IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    ymodem源码(基于C语言实现)

    reille发表于 2019-06-10 02:42:16
    love 0

    基于类串口通信的文件传输协议,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。

    » 本文地址: http://velep.com/archives/1445.html
    » 文章出处: 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段大小问题


沪ICP备19023445号-2号
友情链接