网站的命名规则潍坊高新区建设局门户网站
网站的命名规则,潍坊高新区建设局门户网站,网站空间登陆,商贸网站源码1 概述 XMODEM协议是一种使用拨号调制解调器的个人计算机通信中广泛使用的异步文件运输协议。这种协议以128字节块的形式传输数据#xff0c;并且每个块都使用一个校验和过程来进行错误检测。使用循环冗余校验的与XMODEM相应的一种协议称为XMODEM-CRC。还有一种是XMODEM-1K并且每个块都使用一个校验和过程来进行错误检测。使用循环冗余校验的与XMODEM相应的一种协议称为XMODEM-CRC。还有一种是XMODEM-1K它以1024字节一块来传输数据。YMODEM也是一种XMODEM的实现。它包括XMODEM-1K的所有特征另外在一次单一会话期间为发送一组文件增加了批处理文件传输模式。
本文利用C实现XYModem-1K协议并利用Qt串口类QSerialPort实现数据读写。
3 实现
3.2 XModem
该模块定义和实现了XModem协议。
3.2.1 XModem定义
class XModem : public Modem
{
public:XModem(): id_(0x0){}enum Code {NUL 0x00,SOH 0x01,STX 0x02,EOT 0x04,ACK 0x06,NAK 0x15,CAN 0x18,C 0x43,MAX 0xff};enum Size {CODE 1,ID 2,SIZE1 128,SIZE2 1024,CRC16 2,FRAME_HEAD CODE ID, //1 2FRAME_SIZE1 FRAME_HEAD SIZE1 CRC16,// 3 128 2 133FRAME_SIZE2 FRAME_HEAD SIZE2 CRC16, // 3 1024 2 1029DATA_SIZE1 FRAME_SIZE1 -1,DATA_SIZE2 FRAME_SIZE2 -1};
protected:virtual uint8_t get_code() 0;bool tx_send(uint8_t *data, uint32_t size, int max_count 5);bool tx_eot();bool tx_end();void tx_code(Code code);uint8_t wait_start(int max_count 5);void tx_cancel();uint8_t not_id(uint8_t id) { return 0xFF - id; }void next_id() { id_ next_id(id_); }
private:uint8_t next_id(uint8_t id) { return (id 1) % 0x100; }void do_send(uint8_t const* data, uint16_t size);void do_eot() { tx_code(EOT); }void do_c() { tx_code(C); }
private:uint8_t id_;uint8_t frame_[FRAME_SIZE2];
};纯虚接口:
get_code 获取操作码Code
函数列表
tx_send 发送数据tx_eot 判断发送是否结束。tx_code 发送操作码wait_start 发送C码等待接收码SOH或STX 码tx_cancel 发送取消帧not_id 返回id的反码next_id 返回下一id
3.2.2 XModem实现
3.2.2.1 tx_send
bool XModem::tx_send(uint8_t *data, uint32_t size, int max_count)
{if(size SIZE2)return false;do_send(data, size);for(int i 0; i max_count; i){uint8_t code get_code();if(code MAX)break;else if(code NAK)do_send(data, size);else if(code ACK){next_id();return true;}}return false;
}函数流程
发送数据获取操作码获得无效操作码函数返回获得重传操作码NAK重传数据获得确认操作码ACK说明发送成功设置下一id如果一直返回NAK重复max_count次后函数返回
3.2.2.2 tx_eot
bool XModem::tx_eot()
{do_eot();uint8_t code get_code();if(code NAK){std::cout need next file std::endl;do_eot();if(get_code() ACK)return true;}else if(code ACK){return true;}return false;
}函数流程
发送EOT码获取操作码如果是NAK码重新发送EOT码如何是ACK码成功返回否则失败返回
3.2.2.3 tx_cancel
void XModem::tx_cancel()
{uint8_t frame[] { CAN, CAN, CAN, CAN, CAN };write(frame, sizeof(frame));
}函数流程
构造包含5个CAN取消码帧发送取消码帧
3.2.2.4 tx_code
void XModem::tx_code(Code code)
{uint8_t frame[CODE] { code };write(frame, CODE);
}函数流程
构造包含1个操作码帧发送操作码帧
3.2.2.5 wait_start
uint8_t XModem::wait_start(int max_count)
{for(int i 0; i max_count; i){do_c();uint8_t code get_code();if(code ! MAX)return code;}return MAX;
}函数流程
发送C开始码获取操作码如果获取到有效操作码则返回获取无效操作码重复max_count次上述操作后返回
3.2.2.6 do_send
void XModem::do_send(uint8_t const* data, uint16_t size)
{uint16_t data_size SIZE2;memset(frame_, 0, sizeof(frame_));frame_[1] id_;frame_[2] not_id(id_);if(size SIZE1)frame_[0] STX;else{frame_[0] SOH;data_size SIZE1;}memcpy(frame_[FRAME_HEAD], data, size);memset(frame_[FRAME_HEAD size], 0x1A, data_size - size);uint16_t crc crc16(frame_[FRAME_HEAD], data_size);frame_[FRAME_HEAD data_size] (uint8_t)(crc 8);frame_[FRAME_HEAD data_size 1] (uint8_t)(crc 0);write(frame_, (data_size SIZE1 ? FRAME_SIZE1 : FRAME_SIZE2));
}函数流程
设置frame头id和not_id根据大小判断是XModem帧还是1K-XModem帧如果数据不满则填充字节0x1A计算数据CRC值(包括填充字节)在帧末尾设置CRC值发送数据帧 Qt实现XYModem协议(二)
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/90869.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!