MM32F103 串口 BootLoader 升级(二)
通过Ymodem 协议升级代码Ymodem 协议详解
参考链接;
Ymodem协议解析-CSDN博客
Ymodem协议发送数据前需要接收端发起通信,发送端收到接收端发送的数据后才会开始传输数据,也就是握手信号。主要通信的时序参考文件传输过程,但需要注意的是,在接受过程中,通过同一个串口有打印数据的情况下,会导致发送端发送中断或者异常。在测试中,发送端发送的帧头一直是soh,没有出现过stx,只需要按照协议解析数据就可以了。
Ymodem握手信号
握手信号由接收方发起,在发送方开始传输文件前,接收方需发送YMODEM_C (字符C,ASII码为0x43)命令,发送方收到后,开始传输起始帧。
文件传输过程
文件的传输过程,以具体的例子说明。把foo.c,大小为4196Byte(16进制为0x1064)的文件作为传输的对象,则它的传输过程如下:
发送端----------------------------------------------------------------接收端
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< C
SOH 00 FF “foo.c” "1064’’ NUL CRC CRC >>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< C
STX 01 FE data CRC CRC>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
STX 02 FD data CRC CRC>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
STX 03 FC data CRC CRC>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
STX 04 FB data CRC CRC>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
SOH 05 FA data 1A CRC CRC>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
EOT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< NAK
EOT>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< C
SOH 00 FF NUL CRC CRC >>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
原文链接:https://blog.csdn.net/huangdenan/article/details/103611081
数据解析:
void YModem_Parse(uint8_t data) {
static uint8_t packetBuffer;// 存放接收到的数据块
static uint16_t packetIndex = 0; // 当前数据块接收的位置
switch (ymodemState) {
case YMODEM_IDLE:
if (data == SOH || data == STX) {
// 检测到 SOH 或 STX,开始接收数据块
packetIndex = 0;
packetBuffer = data;
ymodemState = YMODEM_RECEIVING;
}
if (data == EOT) {
// 检测到 EOT,传输结束
ymodemState = YMODEM_IDLE;
// 发送 ACK 响应确认传输结束
Set_state(TO_RECEIVE_EOT2);
send_command(ACK);
send_command(CCC);
}
if (data == CAN) {
// 检测到 EOT,传输结束
ymodemState = YMODEM_IDLE;
// 发送 ACK 响应确认传输结束
Set_state(TO_stday);
}
break;
case YMODEM_RECEIVING:
packetBuffer = data;
if ((packetBuffer == SOH && packetIndex == 133) || (packetBuffer == STX && packetIndex == 1029)) {
YModem_ProcessDataBlock(packetBuffer, packetIndex);
LOGD("blockNumber %d",packetBuffer);
ymodemState = YMODEM_IDLE;
}
break;
default:
break;
}
}
代码升级
/**
* @bieaf YModem升级
*
* @param none
* @return none
*/
void ymodem_fun(uint8_t* data,int len)
{
static unsigned char data_state = 0;
static unsigned int app2_size = 0;
if(Check_CRC(data, len)==1)///< 通过CRC16校验
{
if(data == 0x00 &&data_state == 0)
Set_state(TO_START);
if(Get_state()==TO_RECEIVE_EOT2)
Set_state(TO_RECEIVE_END);
if((Get_state()==TO_START)&&(data == 0x00)&&(data == (unsigned char)(~data)))///< 开始
{
LOGD("> Receive start...\r\n");
data_state = 0x01;
Set_state(TO_RECEIVE_DATA);
/* 擦除App2 */
// Erase_page(Application_2_Addr, 30);
}
else if((Get_state()==TO_RECEIVE_END)&&(data == 0x00)&&(data == (unsigned char)(~data)))///< 结束
{
LOGD("> Receive end...\r\n");
Set_Update_Down();
Set_state(TO_stday);
send_command(ACK);
if(data == 0x00)
send_command(CCC);
delay_ms(1000);
SoftReset();
}
else if((Get_state()==TO_RECEIVE_DATA)&&(data == data_state)&&(data == (unsigned char)(~data)))///< 接收数据
{
LOGD("> Receive data bag:%d byte\r\n",data_state * 128);
/* 烧录程序 */
ONCHIP_FLASH_Write_32Bit((Application_2_Addr + (data_state-1) * 128), (uint32_t *)(&data), 32);
data_state++;
}
send_command(ACK);
if(data == 0x00)
send_command(CCC);
}
else
{
LOGD("> Notpass crc\r\n");
}
}
源文件下载链接:https://download.csdn.net/download/qq_45234526/90294512
结语
上面代码内容均以测试实现,可放心下载。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_45234526/article/details/145283100
YModem和XModem的区别在哪儿呢?
页:
[1]