本文共 3923 字,大约阅读时间需要 13 分钟。
YModem协议最初是XModem协议的升级,其核心优势体现在传输效率和可靠性上。相比XModem的128字节传输块,YModem支持到1024字节,这使得文件传输速度大幅提升。此外,ZModem协议进一步优化了YModem,使其在通信中断时能够实现检查点重启,进一步增强传输的可靠性。
YModem协议的数据包帧结构分为起始帧、数据帧和结束帧。起始帧包含文件名和大小信息,数据帧承载实际数据,结束帧则标志着文件传输结束。
在YModem协议中,数据帧的传输有数种关键特性:
128字节数据帧:文件剩余空间小于等于128字节时,使用SOH格式数据帧传输,数据区间填充0x1A。
1024字节数据帧:文件剩余空间大于128字节且小于等于1024字节时,使用STX格式数据帧传输,数据区间同样以0x1A填充。
需要注意的是,发送序号和序号补码对数据包正确传输至关重要,一旦发现序号不匹配应返回NAK负确认。
在STM32 IAP编程中,YModem协议主要通过以下几个关键函数实现文件接收:
uint32_t Ymodem_Receive(uint32_t *p_size){ uint32_t i; uint8_t tmp; uint32_t file_size; uint8_t *file_ptr; // 初始化Flash目的地址 uint32_t flashdestination = APPLICATION_ADDRESS; while (session_done == 0) { if (ReceivePacket(aPacketData, &packet_length, DOWNLOAD_TIMEOUT) == HAL_OK) { switch (packet_length) { case 2: // 发送者主动终止 Serial_PutByte(ACK); return COM_ABORT; case 0: // 接收完成 Serial_PutByte(ACK); file_done = 1; break; default: // 数据包处理 if (aPacketData[PACKET_NUMBER_INDEX] != packets_received) { Serial_PutByte(NAK); } else { if (packets_received == 0) { // 提取文件名和大小 i = 0; file_ptr = aPacketData + PACKET_DATA_INDEX; while (*file_ptr != 0 && i < FILE_NAME_LENGTH) { aFileName[i++] = *file_ptr++; } aFileName[i++] = '\0'; i = 0; while (*file_ptr != ' ' && i < FILE_SIZE_LENGTH) { file_size[i++] = *file_ptr++; } file_size[i++] = '\0'; Str2Int(file_size, &file_size); // 检查文件大小是否超出flash容量 *p_size = file_size; if (*p_size > USER_FLASH_SIZE) { // session终止 Serial_PutByte(CA); Serial_PutByte(NAK); return COM_LIMIT; } // 擦除用户应用区 FLASH_If_Erase(APPLICATION_ADDRESS); Serial_PutByte(ACK); Serial_PutByte(CRC16); } else { // 数据包处理 ramsource = aPacketData[PACKET_DATA_INDEX]; if (FLASH_If_Write(flashdestination, (uint32_t *)ramsource, packet_length/4) == FLASHIF_OK) { flashdestination += packet_length; Serial_PutByte(ACK); } else { // 写入失败 Serial_PutByte(CA); Serial_PutByte(CA); return COM_DATA; } } packets_received++; session_begin = 1; } break; } } // 处理其他情况 if (result != COM_OK) { // 处理错误 if (session_begin > 0) { errors++; if (errors > MAX_ERRORS) { Serial_PutByte(CA); Serial_PutByte(CA); return COM_ABORT; } } Serial_PutByte(CRC16); } } return COM_OK;}
如代码所示,YModem协议的接收流程分为几个关键环节:文件名提取、大小校验、数据写入(Flash或RAM)、错误检测等。代码注释详细描述了每个数据包类型的处理方式[...].
转载地址:http://dxwmz.baihongyu.com/