You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

142 lines
3.6 KiB

/*
* 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 <string.h>
#include <stdint.h>
#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