/* * COPYRIGHT (C) 2011-2023, Real-Thread Information Technology Ltd * All rights reserved * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2013-04-14 Grissiom initial implementation * 2019-12-09 Steven Liu add YMODEM send protocol * 2022-08-04 Meco Man move error codes to rym_code to silence warnings * * Radkil adapted in 2026: 移除 RT-Thread 依赖, 使用 rd_time 抽象 */ #ifndef __YMODEM_H__ #define __YMODEM_H__ #include #include #include "common.h" #include "rd_time.h" #include "com.h" /* The word "RYM" is stand for "Real-YModem". */ enum rym_code { RYM_CODE_NONE = 0x00, RYM_CODE_SOH = 0x01, RYM_CODE_STX = 0x02, RYM_CODE_EOT = 0x04, RYM_CODE_ACK = 0x06, RYM_CODE_NAK = 0x15, RYM_CODE_CAN = 0x18, RYM_CODE_C = 0x43, /* RYM error code */ RYM_ERR_TMO = 0x70, RYM_ERR_CODE = 0x71, RYM_ERR_SEQ = 0x72, RYM_ERR_CRC = 0x73, RYM_ERR_DSZ = 0x74, RYM_ERR_CAN = 0x75, RYM_ERR_ACK = 0x76, RYM_ERR_FILE = 0x77, }; /* 超时改为毫秒 */ #ifndef RYM_WAIT_CHR_MS #define RYM_WAIT_CHR_MS 3000 #endif #ifndef RYM_WAIT_PKG_MS #define RYM_WAIT_PKG_MS 3000 #endif #ifndef RYM_CHD_INTV_MS #define RYM_CHD_INTV_MS 3000 #endif #ifndef RYM_END_SESSION_SEND_CAN_NUM #define RYM_END_SESSION_SEND_CAN_NUM 0x07 #endif #ifndef RYM_MAX_ERRORS #define RYM_MAX_ERRORS ((size_t)5) #endif enum rym_stage { RYM_STAGE_NONE = 0, RYM_STAGE_ESTABLISHING, RYM_STAGE_ESTABLISHED, RYM_STAGE_TRANSMITTING, RYM_STAGE_FINISHING, RYM_STAGE_FINISHED, }; struct rym_ctx; typedef enum rym_code(*rym_callback)(struct rym_ctx *ctx, uint8_t *buf, size_t len); /* * rym_device: 串口设备抽象层 * * 使用者提供 read/write/set_rx_indicate 回调, ymodem 协议层不再依赖 * 任何具体 OS 或驱动框架. * * set_rx_indicate(opaque, callback, arg): * 注册接收通知回调. 当串口收到数据时, 驱动应调用 callback(arg). * callback 可以为 NULL (取消注册). */ typedef struct { /* 读串口: 返回实际读到的字节数, 无数据返回 0 */ size_t (*read)(void *opaque, uint8_t *buf, size_t len); /* 写串口: 返回实际写入的字节数 */ size_t (*write)(void *opaque, const uint8_t *buf, size_t len); /* 透传指针 (如 TComCtrl*) */ void *opaque; } rym_device_t; struct rym_ctx { rym_callback on_data; rym_callback on_begin; rym_callback on_end; enum rym_stage stage; uint8_t *buf; rym_device_t dev; }; int rym_recv_on_device(struct rym_ctx *ctx, rym_device_t *dev, rym_callback on_begin, rym_callback on_data, rym_callback on_end, int handshake_timeout_sec); int rym_send_on_device(struct rym_ctx *ctx, rym_device_t *dev, rym_callback on_begin, rym_callback on_data, rym_callback on_end, int handshake_timeout_sec); /** * @brief YMODEM 接收文件 * @param ptCom 串口 TComCtrl (需已创建且 recv 线程已启动) * @param file_path 本地保存路径, 如 "C:/fw.bin" * @return 0 成功, <0 失败 (参见 enum rym_code) */ int rym_download_file(TComCtrl *ptCom, const char *file_path); /** * @brief YMODEM 发送文件 * @param ptCom 串口 TComCtrl * @param file_path 待发送的本地文件路径 * @return 0 成功, <0 失败 */ int rym_upload_file(TComCtrl *ptCom, const char *file_path); #endif