STM32使用Y-Modem协议进行程序升级
2017-12-27 14:21
309 查看
STM32 Ymodem协议串口升级
为了解决模块不拆机,通过串口对STM32进行程序升级,采用Y-modem 协议进行升级。STM32内存划分为IAP段和APP段。IAP段存储使用Y-Modem协议的下位机程序,APP则为正常使用的软件。文件传输过程
1、文件传输过程的开启:
(1)开启是由下位机开启传输,它发一个大写字母"C(0x43)"开启传输。然后进入等待(SOH)状态,如果没有回应,就会超时退出
(2)上位机开始时处于等待过程中,等待"C(0x43)"。收到"C(0x43)"以后,发送(SOH)数据包开始信号,发送序号(00),补码(FF),“文件名”,“0x00”“文件大小”“除去序号外,补满128字节(用0x00 补充)”,CRC校验两个字节。进入等待(ACK(0x06))状态。
(3)下位机收到以后,CRC校验满足,则发送ACK(0x06)。上位机接收到ACK(0x06),又进入等待“文件传输开启”信号,即重新进入等待"C(0x43)"的状态。
(4)前面下位机只是收到了一个文件名,现在正式开启文件传输,Ymodem支持128字节和1024字节一个数据包。128字节以(SOH)开始,1024字节以(STX)开始。
(5)下位机又发出一个"C(0x43)"信号,开始准备接收文件。进入等待"SOH"或者"STK"状态。
(6)上位机接收到"C(0x43)"以后,发送数据包,(STX)(01序号)(FE补码)(1024位数据)(CRC校验),等待下位机"ACK(0x06)",序号依次递增,不足1024位数据用0x00补充。
(7)文件发送完以后,上位机发EOT(0x04),第一次下位机以NAK(0x15)应答,进行二次确认。上位机收到NAK(0x15)后,重发EOT(0x04),下位机第二次收到结束符,就以ACK(0x06)应答。最后下位机再发送一个"C(0x43)",接着上位机会发出一个“全0数据包”(以SOH 开始的数据包头),下位机"ACK(0x06)"以后,本次通信正式结束。
注:只有数据部分参与CRC校验,数据包头不参与CRC校验。
2、数据包格式
2.1文件名数据包
数据包头 | 数据(SOH 128 Byte) | CRC校验 | |||||
| 序号 | 补码 | 文件名 | | 文件大小 | 用0x00 补齐 | 2Byte |
SOH | | | | 00 | | 高位在前 |
例:DM105_IAP.bin 文件大小 12456
除去用0x00补齐的数据,数据包头、校验码,数据包为
44 4D 31 30 35 5F 49 41 50 2E 62 69 6E 00 31 32 34 35 36
2.2 传输数据包
数据包头 | 数据(STX1024 Byte) | CRC校验 | ||
| 序号 | 补码 | 从 bin 文件中读取的数据(读取的数据不满足1024 Byte 用0x00补齐) | 2Byte |
STX | | | 高位在前 |
2.3 文件传输结束全0数据包
数据包头 | 数据(SOH 128 Byte) | CRC校验 4000 | ||
| 序号 | 补码 | 128Byte都是00 | 2Byte |
SOH | 00 | FF | 高位在前 |
2.4 Ymodem协议中宏定义
SOH (0x01) //128字节数据包开始
STX (0x02) //1024字节的数据包开始
EOT (0x04) //结束传输
ACK (0x06) //回应
NAK (0x15) //没回应
C (0x43) //'C' == 0x4
注:下位机回复NACK的时候,上位机需要重新发送一次数据包
以下提供CRC校验的C语言算法
/******************************************************************************* * @函数名称 UpdateCRC16 * @函数说明 更新输入数据的CRC校验 * @输入参数 crcIn byte * @输出参数 无 * @返回参数 CRC校验值 *******************************************************************************/ uint16_t UpdateCRC16(uint16_t crcIn, uint8_t byte) { uint32_t crc = crcIn; uint32_t in = byte|0x100; do { crc <<= 1; in <<= 1; if (in&0x100) ++crc; if (crc&0x10000) crc ^= 0x1021; } while (!(in&0x10000)); return crc&0xffffu; } /******************************************************************************* * @函数名称 UpdateCRC16 * @函数说明 更新输入数据的CRC校验 * @输入参数 data :数据 size :长度 * @输出参数 无 * @返回参数 CRC校验值 *******************************************************************************/ uint16_t Cal_CRC16(const uint8_t* data, uint32_t size) { uint32_t crc = 0; const uint8_t* dataEnd = data+size; while (data<dataEnd) crc = UpdateCRC16(crc,*data++); crc = UpdateCRC16(crc,0); crc = UpdateCRC16(crc,0); return crc&0xffffu; }以下是我VS2015中C#的CRC校验,根据上面修改的
public UInt16 UpdateCRC16(UInt16 crcIn, byte data) { UInt32 crc = crcIn; UInt32 indata = (UInt32)(data | 0x100); do { crc <<= 1; indata <<= 1; if ((indata & 0x100) == 0x100) ++crc; if ((crc & 0x10000) == 0x10000) crc ^= 0x1021; } while ((indata & 0x10000) == 0); UInt16 redata = (UInt16)(crc & 0xffff); return redata; } public UInt16 Cal_CRC16(byte[] data, UInt32 size) { UInt16 crc = 0; for(UInt32 i =0; i< size; i++) { crc = UpdateCRC16(crc, data[i]); } crc = UpdateCRC16(crc,0); crc = UpdateCRC16(crc,0); UInt16 redata = (UInt16)(crc & 0xffff); return redata; }以上所有为本人自己进行数据跟踪得到,如果有错误,欢迎指出。
相关文章推荐
- 程序使用 HTTP 协议和服务器交互主要是进行数据的提交,通常数据的提交是通过 GET 和 POST 两种方式来完成
- 在stm32 单片机程序中使用printf()进行串口调试
- 对开发的程序(制作CAB)进行签名,并允许网站中使用
- 使用loadrunner录制winsock协议的程序(原创)
- 使用C#和Excel进行报表开发-用程序绑定数据源
- 如何使用*.pdb与源代码进行Web程序的调试?
- 使用NUnit进行DotNet程序测试
- 使用Windows Mobile Test Framework进行Windows Mobile程序的自动化测试 - (2) 小试牛刀
- 使用NetBeans进行J2ME开发(二):把程序转移到手机上
- 开发安全应用程序(五)-- 使用 JAAS 进行开发以使用程序来进行登录
- SqlPager最终版[附源码和示例程序](使用存储过程进行分页)
- 在HttpModule中使用gzip,deflate协议对aspx页面进行压缩
- 未能使用提供程序 "RsaProtectedConfigurationProvider" 进行解密 的解决办法
- 使用C#和Excel进行报表开发(八)-用程序绑定数据源
- 使用Windows Mobile Test Framework进行Windows Mobile程序的自动化测试 - (1)微软Windows Mobile Test Framework简介
- MODEM使用什么协议?
- 使用NUnit进行DotNet程序测试
- 对开发的程序(制作CAB)进行签名,并允许网站中使用
- 使用Windows Mobile Test Framework进行Windows Mobile程序的自动化测试 - (2) 小试牛刀
- 对开发的程序(制作CAB)进行签名,并允许网站中使用