最后更新:2022-05-10 03:10:30 手机定位技术交流文章
简介
系列通信中使用的文件转让协议包括Xmodem、Ymodem、Zmodem、Kermit等。Ward Chritensen的Xmodem协议于1978年制定,用于解决问题。这是一个流行的不对称文件传输协议。
Xmodem 以包形式发送数据 。数据包由字节起始字符、字节包号、字节包号补充、数据包内容和数据验证要素组成。在此示例中,数据包下的数字从 0x01 提高到顶部。插入 0xFF 时循环会重复。
根据初等和二等人物的区别可将Xmodem协议分为两种版本:普通Xmodem和Xmodem-1k。协议包的标准 Xmodem 版本的固定大小为128 字节。数据包的 Xmodem-1k 版本的固定大小为 1024 字节。设置交付方将随软件包发送的字节数。当发送者提供起始字符 SOH (0x01) 时,包件的其余内容限于128字节。如果发件人从字符STX(0x02)开始,,表示包件其余内容固定在1024字节;在实际数据部署中,每个传输包都有固定的长度。如果数据包的内容小于128/1024字节,数据包将短于长。要完成数据包的内容,请按 CTRLZ (0x1A) 键。
标准 Xmodem 议定书(每个数据点都含有 " 是 " 字) 128 字节数据)帧格式:
SOH+数据集序列号+数据集序列号+数据集序列号+数据集序列号+数据集序列号+数据集数据集数据集内容(128 字节)+数据验证的补充
Xmodem-1k 议定书(每个数据点都含有 " 是 " 字) 1024 字节数据)帧格式:
STX+数据包序号+补充数据包序号+数据包序号+数据包内容(1024字节)+数据校验
测试 Xmodem 协议的数据有两种方法。一种方法是添加和检查。(a) 添加和计算发送的数据;然后我们拿剩下的256核查技术为一字节长,而《儿童权利公约》的核查方法为两字节长。(a) 传送的CRC计算数据(CRC多式X16+X12+X5+1);然后我们再提取16位较低数据此校验的测试长度为 2 字节 。这不是确定使用哪种试验来决定使用哪种试验的问题。接收人作出决定;接收人准备接收信息。如果收件人发送大写字母C,它将每隔三秒钟向发件人发送信号字符。如果接收者以CRC检查的形式传输数据,发送者必须打包数据;如果接收者以NAK(0x15)的形式发送数据,发送者必须用CRC检查接收者以CRC检查的形式发送数据,发送者必须打包数据;如果接收者以NAK(0x15)的形式发送数据,发送者必须用CRC检查的形式发送数据。接收者要求发送者以累积和可核查的方式打包数据;接收者收到发送者的数据后即接收。使用同一技术进行计算核查的情况也是如此。
Xmodem 如何启动传输?
1. 接收方通过向接收方指示发送者发送字符C或NAK信号来启动发送。
2. 当接收器通过发送NAK信号启动传输时,显示接收器采用累积和核查技术;当接收器传输字符C以开始传输时,表明接收方使用《儿童权利公约》技术进行核查;添加和测试要求一个字节;CRC检查了两字节。
Xmodem 传输过程描述:
1. 当发件人收到收件人的初始字符C或NAK时,发件人相信第一个数据包可能会寄出传输已经启动。然后,数据应添加到发送者每128/1024字节的第一个字符中。数据包序列号,数据包序列号补码,末尾加上校验和,为了传送,它被包裹成框架格式。
2. 在提供第一组数据后,发送者等待接收者对ACK确认字节作出答复,在收到接收者的ACK确认后,发送者确定包件是接收者适当接收的,并要求发送者继续发送下一套数据以传送第一组数据,发送者等待接收者对ACK确认字节作出答复,收到接收者的ACK确认后,发送者确定包件是接收者适当接收的,并要求发送者继续发送下一套数据。
3. 如果发件人从接收方得到一份NAK字节,它意味着接收方要求立即重新发送数据框架;如果发送方从接收方收到一份可调出源字节,它意味着接收方要求立即终止传输。
Xmodem 处理注意事项 :
1. 接收方应首先测试数据包信号的完整性,在数据包中添加序列号,然后添加不同的或操作的数据包序列号,结果为0准确,结果为0,NAK发送重新传输。
2. 如果收到的数据包与前一个数据包的编号相同,接收方将不理会重复的软件包,向发送者发送ACK,并准备接收下一个数据包。
3. 如果收件人确认资料包序号正确无误,而且是否预期资料包序号正确,则只添加和检查128/1024字节数据字段,或核查CRC,并将结果与框架中的最后一次数据检查进行比较,并将结果交付ACK,或者交给NAK。
实现功能
MobaXterm 工具用于合并SHELL命令,以选择用于发送或接收测试的Xmodem;SecureCRT工具用于发送和接收Xmodem数据;通信 USB 中继器用于打印传输过程并查看传输结果。
实现代码
由于篇幅有限,以下守则只是基本实现要素,整个守则载于附件,附件以中文提供详尽的评论,易于阅读和理解。
Xmodem 检查的计算 :
uint16_t Xmodem_CalcCheckCRC(uint8_t *Buffer, uint16_t Length)
{
uint32_t Result = 0;
Length += 2;
while(Length--)
{
uint8_t Value = (Length < 2) ? 0 : *Buffer++;
for(uint8_t j = 0; j < 8; j++)
{
Result <<= 1;
if(Value & 0x00080) Result += 0x0001;
Value <<= 1;
if(Result & 0x10000) Result ^= 0x1021;
}
}
Result &= 0xFFFF;
printf("rnrnCheck CRC:0x%04xrnrn", Result);
return Result;
}
uint8_t Xmodem_CalcCheckSum(uint8_t *Buffer, uint16_t Length)
{
uint16_t Result = 0;
while(Length--)
{
Result += *Buffer++;
}
Result &= 0xFF;
printf("rnrnCheck Sum:0x%02xrnrn", Result);
return Result;
}
Xmodem 接收程序 :
void Xmodem_RxHandler(void)
{
uint32_t StartTryTimtout = 0x0;
QUEUE_INIT(QUEUE_RS232_RX_IDX);
Xmodem_State = XMODEM_RX_STATE_SOH;
while(1)
{
if(QUEUE_EMPTY(QUEUE_RS232_RX_IDX) == 0)
{
uint8_t data = QUEUE_READ(QUEUE_RS232_RX_IDX);
printf("0x%02x ", data);
switch(Xmodem_State)
{
case XMODEM_RX_STATE_SOH:
if((data == XMODEM_SOH) || (data == XMODEM_STX))
{
Xmodem_Length = (data == XMODEM_STX) ? 1024 : 128;
Xmodem_Index = 0;
Xmodem_State = XMODEM_RX_STATE_NUM;
}
else if(data == XMODEM_EOT)
{
RS232_SendData(XMODEM_ACK);
printf("rnXmodem Finish"); return;
}
else if(data == XMODEM_CAN)
{
printf("rnXmodem Cancle"); return;
}
else
{
}
break;
case XMODEM_RX_STATE_NUM:
Xmodem_Number[Xmodem_Index++] = data;
if(Xmodem_Index == 2)
{
Xmodem_Index = 0;
Xmodem_State = XMODEM_RX_STATE_DAT;
}
break;
case XMODEM_RX_STATE_DAT:
Xmodem_Buffer[Xmodem_Index++] = data;
if(Xmodem_Index == Xmodem_Length)
{
Xmodem_Index = 0;
Xmodem_State = XMODEM_RX_STATE_CHK;
}
break;
case XMODEM_RX_STATE_CHK:
Xmodem_CheckData[Xmodem_Index++] = data;
if((Xmodem_CheckType == 1) && (Xmodem_Index == 1))
{
Xmodem_Index = 0;
if(Xmodem_Number[0] == ((Xmodem_Number[1] ^ 0xFF) & 0xFF))
{
if(Xmodem_CheckData[0] == Xmodem_CalcCheckSum(Xmodem_Buffer, Xmodem_Length))
{
RS232_SendData(XMODEM_ACK);
}
else
{
RS232_SendData(XMODEM_NAK);
}
}
else
{
RS232_SendData(XMODEM_NAK);
}
Xmodem_State = XMODEM_RX_STATE_SOH;
}
else if((Xmodem_CheckType == 0) && (Xmodem_Index == 2))
{
Xmodem_Index = 0;
if(Xmodem_Number[0] == ((Xmodem_Number[1] ^ 0xFF) & 0xFF))
{
uint16_t Result = 0;
Result = Xmodem_CheckData[0];
Result <<= 8;
Result |= Xmodem_CheckData[1];
if(Result == Xmodem_CalcCheckCRC(Xmodem_Buffer, Xmodem_Length))
{
RS232_SendData(XMODEM_ACK);
}
else
{
RS232_SendData(XMODEM_NAK);
}
}
else
{
RS232_SendData(XMODEM_NAK);
}
Xmodem_State = XMODEM_RX_STATE_SOH;
}
else
{
}
break;
default:
break;
}
}
else
{
if(StartTryTimtout == 0)
{
if(Xmodem_CheckType)
{
RS232_SendData(XMODEM_NAK);
}
else
{
RS232_SendData('C');
}
}
StartTryTimtout = (StartTryTimtout + 1) % XMODEM_TRY_TIMEOUT;
}
}
}
Xmodem 传输程序:
void Xmodem_TxHandler(void)
{
for(uint16_t i = 0; i < sizeof(Xmodem_FileBuffer); i++)
{
Xmodem_FileBuffer[i] = 0x30 + (i % 10);
}
QUEUE_INIT(QUEUE_RS232_RX_IDX);
Xmodem_State = XMODEM_TX_STATE_WAIT_SOH;
Xmodem_SentLength = 0;
Xmodem_Length = 128;
while(1)
{
switch(Xmodem_State)
{
case XMODEM_TX_STATE_WAIT_SOH:
if(QUEUE_EMPTY(QUEUE_RS232_RX_IDX) == 0)
{
uint8_t data = QUEUE_READ(QUEUE_RS232_RX_IDX);
printf("rnSOH: 0x%02x", data);
if((data == 'C') || (data == XMODEM_NAK))
{
Xmodem_CheckType = (data == 'C') ? 0 : 1;
Xmodem_Number[0] = 0x00;
Xmodem_Number[1] = (Xmodem_Number[0] ^ 0xFF) & 0xFF;
Xmodem_State = XMODEM_TX_STATE_SEND_DAT;
}
else if(data == XMODEM_CAN)
{
return;
}
else
{
}
}
break;
case XMODEM_TX_STATE_SEND_DAT:
memset(Xmodem_Buffer, 0, sizeof(Xmodem_Buffer));
QUEUE_INIT(QUEUE_RS232_RX_IDX);
Xmodem_Index = 0;
Xmodem_Number[0]++;
Xmodem_Number[1] = (Xmodem_Number[0] ^ 0xFF) & 0xFF;
while(Xmodem_SentLength < Xmodem_FileLength)
{
if(Xmodem_Index < Xmodem_Length)
{
Xmodem_Buffer[Xmodem_Index++] = Xmodem_FileBuffer[Xmodem_SentLength++];
}
else
{
break;
}
}
while(Xmodem_Index < Xmodem_Length)
{
Xmodem_Buffer[Xmodem_Index++] = XMODEM_CTRLZ;
}
if(Xmodem_Length == 128)
{
RS232_SendData(XMODEM_SOH);
}
else
{
RS232_SendData(XMODEM_STX);
}
RS232_SendData(Xmodem_Number[0]);
RS232_SendData(Xmodem_Number[1]);
for(uint16_t i = 0; i < Xmodem_Length; i++)
{
RS232_SendData(Xmodem_Buffer[i]);
}
if(Xmodem_CheckType)
{
RS232_SendData(Xmodem_CalcCheckSum(Xmodem_Buffer, Xmodem_Length));
}
else
{
uint16_t Result = Xmodem_CalcCheckCRC(Xmodem_Buffer, Xmodem_Length);
RS232_SendData((Result >> 0x08) & 0xFF);
RS232_SendData((Result >> 0x00) & 0xFF);
}
Xmodem_State = XMODEM_TX_STATE_WAIT_ACK;
break;
case XMODEM_TX_STATE_WAIT_ACK:
if(QUEUE_EMPTY(QUEUE_RS232_RX_IDX) == 0)
{
uint8_t data = QUEUE_READ(QUEUE_RS232_RX_IDX);
printf("rnACK: 0x%02x", data);
if(data == XMODEM_ACK)
{
if(Xmodem_SentLength == Xmodem_FileLength)
{
QUEUE_INIT(QUEUE_RS232_RX_IDX);
RS232_SendData(XMODEM_EOT);
Xmodem_State = XMODEM_TX_STATE_WAIT_EOT;
}
else
{
Xmodem_State = XMODEM_TX_STATE_SEND_DAT;
}
}
else if(data == XMODEM_NAK)
{
Xmodem_Number[0] -= 1;
Xmodem_SentLength -= Xmodem_Length;
Xmodem_State = XMODEM_TX_STATE_SEND_DAT;
}
}
break;
case XMODEM_TX_STATE_WAIT_EOT:
if(QUEUE_EMPTY(QUEUE_RS232_RX_IDX) == 0)
{
uint8_t data = QUEUE_READ(QUEUE_RS232_RX_IDX);
printf("rnEOT: 0x%02x", data);
if(data == XMODEM_ACK)
{
printf("rnXmodem Finish"); return;
}
else if(data == XMODEM_NAK)
{
RS232_SendData(XMODEM_EOT);
}
}
break;
default:
break;
}
}
}
运行测试

程序启动后,MobaXterm终端显示书面信息。键入第一个命令时,MSCU作为接收方,通过SecureCRT从计算机获取数据内容,这是唯一的数据来源。当输入二号时MCU作为发射机运作,在PC上向安全CTT发送数据。SecureCRT 保存在指定位置指定的文件中接收的数据 。

使用常规Xmodem和Xmodem-1k,我们将使用各种核查技术测试数据接收和传输。在SecureCRT软件中Options->Session Options->X/Y/Zmodem中来选择发送数据包的长度,是正常的 128 字节或标准 1024 字节。

1 、使用 CRC 的校验方式进行测试 :在MobaXterm终端中,将 XMODEM 1 命令输入接收 Xmodem 数据状态。此时 SecureCRT 程序窗口定期显示大写字母。 C;通过点击Transfer->Send Xmodem...在弹出的窗口中,选择需要发送的文件1.TXT,点击Send后即刻发送数据。



一.1. Xmodem 标准协议


一.2. 商定Xmodem-1k


2 累积和核查测试技术 :在MobaXterm终端中,将 XMODEM 1 命令输入接收 Xmodem 数据状态。此时 SecureCRT 因为接收者此时传输, 程序窗口无法提供任何线索信息 。 NAK 这是一个不可见的性格。;通过点击Transfer->Send Xmodem...在弹出的窗口中,选择需要发送的文件1.TXT,点击Send后即刻发送数据。
2.1.1. Xmodem 标准协议


2.2. 商定Xmodem-1k


我们可以看到在当 SecureCRT 将程序中的软件包配置为 1024 ,在实际分发过程中,最终的软件包基于文件的剩余数据大小,即小于 128 使用的字节为标准字节。 Xmodem 数据包大小。
3 、使用标准 Xmodem 协议接收来自 MCU 的文件数据 :在 MobaXterm 终端中,将 XMODEM 2 命令输入 Xmodem 数据状态。等待 SecureCRT 软件提供启动字符,以便开始传输; 从程序打印中学习,当Xmodem获得安全CRT软件时《儿童权利公约》是使用的核查机制。在SecureCRT软件中通过点击Transfer->Receive Xmodem...在弹出的窗口中,选择要保存的文件的目录和文件名。 例如, TXT 。点击“接收”时,将接收数据。




附件
软件工程源代码:
Xmodem.zip(2.74 MB)
参考资料:
XMODEM-YMODEM-Protocol-Refrence.pdf(323.26 KB)
使用 UART (Xmodem 协议) 传输文件 。(448.42 KB)
测试文件:
1.zip(207 Bytes)
2.zip(180 Bytes)
---------------------
xld0932 是作者。
对不起,21点,Co/icview -3217632-1-1-1.html
本页是2011年马拉维大选特别报导的一部分。
该物品已被指定为原始/发起物品,拥有21个所有权,任何人不得复制该物品。
本文由 在线网速测试 整理编辑,转载请注明出处。