» 上一篇:
jsoncpp按插入顺序排序和支持指定小数位数
» 下一篇:
6月 102019

基于类串口通信的文件传输协议,ymodem应用非常广泛,比如在MCU IAP中,常用的就是这种协议。ymodem是xmodem的改进版协议,具有传输快速稳定的优点。它可以一次传输1024字节的信息块,同时还支持传输多个文件。
本文ymodem源码基于C语言,采用回调机制,设计为独立的C库,包含了发送端和接收端的实现。
YMODEM协议简介
YMODEM文件传输过程,参考文章:https://blog.csdn.net/lcmsir/article/details/80550821
YMODEM源码简介
/*
* ymodem.h
*
* COPYRIGHT (C) 2019. All rights reserved.
*
* Created on: 2019-06-05
* Author: gyr
*
* \brief YMODEM协议库实现
*
* YMODEM文件传输过程:
*
* 发送端 接收端
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< C
* SOH 00 FF [filename 00] [filesize 00] [NUL..] CRCH CRCL >>>
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< C
* SOH 00 FF [filename 00] [filesize 00] [NUL..] CRCH CRCL >>>
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< C
* STX 01 FE data[1024] CRC CRC>>>>>>>>>>>>>>
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
* STX 02 FD data[1024] CRC CRC>>>>>>>>>>>>>>
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
* STX 03 FC data[1024] CRC CRC>>>>>>>>>>>>>>
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
* STX 04 FB data[1024] CRC CRC>>>>>>>>>>>>>>
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
* SOH 05 FA data[100] 1A[28] CRC CRC>>>>>>>
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
* EOT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< NAK
* EOT>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< C
* SOH 00 FF NUL[128] CRC CRC >>>>>>>>>>>>>>>
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
*
* 上述中:
* filename: 字符串
* filesize: 文件大小,字符串格式
* NUL: 填充为0x00
* CRC: 先传CRC高字节,再传低字节
*/
#ifndef YMODEM_H_
#define YMODEM_H_
/**
* Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Provide the ability to override linkage features of the interface.
*/
#ifndef YMODEM_EXTERN
# define YMODEM_EXTERN extern
#endif
#ifndef YMODEM_API
# define YMODEM_API
#endif
/**
* Ensure these symbols were not defined by some previous header file.
*/
#ifdef YMODEM_VERSION
# undef YMODEM_VERSION
#endif
#ifdef YMODEM_VERSION_NUMBER
# undef YMODEM_VERSION_NUMBER
#endif
/**
* YMODEM库版本号
*
* [YMODEM_VERSION]
*
* 字符串格式版本号,格式为:X.Y.Z,其中,X为主版本号;Y为次版本号;Z为发布版本号
*
* [YMODEM_VERSION_NUMBER]
*
* 整数版本号:(X*1000000 + Y*1000 + Z)
* 对于任何一个版本,该宏的值总是比前一个版本的值大。当Y操持不变时,Z递增;当Y递增时,Z归位为0
*/
#define YMODEM_VERSION "1.0.0"
#define YMODEM_VERSION_NUMBER 1000000
/**
* These interfaces provide the same information as the [YMODEM_VERSION],
* [YMODEM_VERSION_NUMBER]
*/
YMODEM_API YMODEM_EXTERN const char ymodem_version[];
YMODEM_API const char *ymodem_libversion();
YMODEM_API int ymodem_libversion_number();
/**
* Result Codes: result code definitions
*
* Many YMODEM functions return an integer result code from the set shown
* here in order to indicate success or failure.
*
* New error codes may be added in future versions of YMODEM.
*/
typedef int ymodem_rt_t;
#define YMODEM_RT_OK 0 /* Successful result */
/* beginning-of-error-codes */
#define YMODEM_RT_ERR 1 /* Generic error */
/* end-of-error-codes */
/* 定义日志级别 */
#define YM_LOG_LVL_DBG 0 // 调试级别
#define YM_LOG_LVL_INFO 1 // 辅助级别
#define YM_LOG_LVL_WARN 2 // 警告级别
#define YM_LOG_LVL_ERROR 3 // 错误级别
// -----------------------------------------------------------------------------
typedef struct ymodem_mgr ymodem_mgr_t;
typedef struct ymodem_callback ymodem_callback_t;
struct ymodem_callback
{
/**
* \brief 接收数据回调接口
*
* @param buff 接收缓存
* @param len 接收缓存字节长度
* @param timeout 接收超时时间,单位:ms
*/
int (*recv_data)(char* buff, int len, int timeout);
/**
* \brief 发送数据回调接口
*
* @param buff 发送缓存
* @param len 发送缓存字节长度
*/
int (*send_data)(const char* buff, int len);
/**
* \brief 日志输出接口,如果未定义,则不打印输出任何日志信息,即使错误信息
*/
void (*write_log)(int logLevel, const char *file, int line,
const char *fmt, ...);// const __attribute__((format(printf,5,6)));
};
typedef struct ymodem_cfg ymodem_cfg_t;
struct ymodem_cfg
{
/**
* \brief 传输数据时,指定接收超时时间,单位:ms
*/
int timeout;
/**
* \brief YMODEM数据块大小
* 标准YMODEM协议采用128/1024字节大小数据块传输文件
*
* @param blk_size
* 0: 采用标准YMODEM数据块大小
* [20-1024]: 自定义字节大小的YMODEM数据库(非标准)
* 自定义的YMODEM数据块大小必须满足 >= 文件名+字符串格式文件字节大小,否则会出错
* > 1024: N/A
*/
char blk_size;
};
/**
* \brief 开始接收回调函数
*
* @param filename 准备接收的文件名
* @param filesize 准备接收的文件大小,单位:byte
*/
typedef ymodem_rt_t cb_on_receive_begin(const char *filename, unsigned int filesize);
/**
* \brief 接收文件数据回调函数
*/
typedef ymodem_rt_t cb_on_receive_packet(const unsigned char *filedata, unsigned int length);
/**
* \brief 获取要传输的文件数据的回调函数
*
* @param filedata 存储文件数据的缓存
* @param length filedata的字节长度
* @param transmited_size 当前已传输字节数,可用作文件偏移
*/
typedef ymodem_rt_t cb_on_transmit_packet(unsigned char *filedata, unsigned int length, const unsigned int transmited_size);
/**
* \brief 文件传输完成回调函数
*/
typedef ymodem_rt_t cb_on_end(unsigned int transmited_size);
// -----------------------------------------------------------------------------
/**
* \brief 打开、关闭 ymodem对象,涉及内存分配,必须成对使用
*/
YMODEM_API ymodem_rt_t ymodem_open(ymodem_mgr_t **ym, ymodem_callback_t *callback, ymodem_cfg_t *cfg);
YMODEM_API ymodem_rt_t ymodem_close(ymodem_mgr_t *ym);
/**
* \brief 使用YMODEM协议接收文件
*
* @param ym ymodem对象指针
* @param on_begin 开始接收回调函数
* @param on_packet 接收文件数据回调函数
* @param on_end 文件接收完成回调函数
* @param handshake_timeout 等待超时时间,单位:秒
*/
YMODEM_API ymodem_rt_t ymodem_receive(ymodem_mgr_t *ym,
cb_on_receive_begin *on_begin,
cb_on_receive_packet *on_packet,
cb_on_end *on_end,
const int handshake_timeout);
/**
* \brief 使用YMODEM协议传输文件
*
* \input
* @ym ymodem对象指针
* @param filename 要传输的文件名称
* @param filesize 要传输的文件字节大小
* @param on_packet 获取要传输的文件数据
* @param on_end 文件传输完成回调函数
* @param handshake_timeout 等待接收端CCC超时时间,单位:秒
*/
YMODEM_API ymodem_rt_t ymodem_transmit(ymodem_mgr_t *ym,
const char *filename, unsigned int filesize,
cb_on_transmit_packet *on_packet,
cb_on_end *on_end,
const int handshake_timeout);
/*
** END OF REGISTRATION API
*******************************************************************************/
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
#endif
#endif /* YMODEM_H_ */
// -----------------------------------------------------------------------------
// End of ymodem.h
YMODE源码
请等待本人上传github。
» 文章出处:
reille博客—http://velep.com
, 如果没有特别声明,文章均为reille博客原创作品
» 郑重声明:
原创作品未经允许不得转载,如需转载请联系reille#qq.com(#换成@)
推荐阅读相关文章:
- jsoncpp按插入顺序排序和支持指定小数位数
- terminate called after throwing an instance of ‘std::length_error’ what(): basic_string::_S_create
- error: ‘__locale_t’ has not been declared
- 关于FLT_EPSILON、DBL_EPSILON、LDBL_EPSILON
- 编译错误:error: stray ‘\357’ in program
- linux backtrace()详细使用说明,分析Segmentation fault
- linux下统计代码执行时间
- 谈谈程序中BSS段大小问题


大佬,请问源码上传了吗