{"id":2226,"date":"2024-05-23T11:56:59","date_gmt":"2024-05-23T03:56:59","guid":{"rendered":"https:\/\/www.huangrongzhen.ink\/?p=2226"},"modified":"2024-05-23T12:04:42","modified_gmt":"2024-05-23T04:04:42","slug":"ymodem-%e9%a9%b1%e5%8a%a8","status":"publish","type":"post","link":"https:\/\/www.huangrongzhen.ink\/?p=2226","title":{"rendered":"Ymodem \u9a71\u52a8"},"content":{"rendered":"<div class=\"wp-block-post-excerpt\"><p class=\"wp-block-post-excerpt__excerpt\">\u4f7f\u7528 C \u8bed\u8a00\u7f16\u5199\u7684 Ymodem \u9a71\u52a8\u3002 <\/p><\/div>\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"%E5%8F%91%E9%80%81%E9%A9%B1%E5%8A%A8\"><\/span>\u53d1\u9001\u9a71\u52a8<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>\u5934\u6587\u4ef6\u5982\u4e0b\u6240\u793a\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/*********************************************************************************************************\n* \u6a21\u5757\u540d\u79f0\uff1a YmodemSender.h\n* \u6458    \u8981\uff1a Ymodem \u534f\u8bae\u53d1\u9001\u65b9\n* \u5f53\u524d\u7248\u672c\uff1a 1.0.0\n* \u4f5c    \u8005\uff1a SZLY(COPYRIGHT 2018 - 2020 SZLY. All rights reserved.)\n* \u5b8c\u6210\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5 \n* \u5185    \u5bb9\uff1a\n* \u6ce8    \u610f\uff1a\n**********************************************************************************************************\n* \u53d6\u4ee3\u7248\u672c\uff1a\n* \u4f5c    \u8005\uff1a\n* \u5b8c\u6210\u65e5\u671f\uff1a\n* \u4fee\u6539\u5185\u5bb9\uff1a\n* \u4fee\u6539\u6587\u4ef6\uff1a\n*********************************************************************************************************\/\n#ifndef _YMODEM_SENDER_H_\n#define _YMODEM_SENDER_H_\n\n\/*********************************************************************************************************\n*                                              \u5305\u542b\u5934\u6587\u4ef6\n*********************************************************************************************************\/\n\n\/*********************************************************************************************************\n*                                              \u5b8f\u5b9a\u4e49\n*********************************************************************************************************\/\n\/\/\u534f\u8bae\u4e2d\u7528\u5230\u7684\u7b26\u53f7\n#define YMODEM_SENDER_SOH 0x01 \/\/Ymodem \u77ed\u5e27\u6570\u636e\u5934\n#define YMODEM_SENDER_STX 0x02 \/\/Ymodem \u957f\u5e27\u6570\u636e\u5934\n#define YMODEM_SENDER_EOT 0x04 \/\/\u53d1\u9001\u7ed3\u675f\n#define YMODEM_SENDER_ACK 0x06 \/\/\u5e94\u7b54\n#define YMODEM_SENDER_NAK 0x15 \/\/\u975e\u5e94\u7b54\n#define YMODEM_SENDER_CAN 0x18 \/\/\u53d6\u6d88\u53d1\u9001\n#define YMODEM_SENDER_C   0x43 \/\/\u8bf7\u6c42\u6570\u636e\n\n\/\/\u72b6\u6001\u5b9a\u4e49\n#define YMODEM_SENDER_STATE_IDLE   0x00 \/\/\u7a7a\u95f2\u72b6\u6001\n#define YMODEM_SENDER_STATE_BUSY   0x01 \/\/\u6b63\u5728\u53d1\u9001\n#define YMODEM_SENDER_STATE_FINISH 0x02 \/\/\u5df2\u53d1\u9001\u5b8c\u6210\n#define YMODEM_SENDER_STATE_CANCEL 0x03 \/\/\u53d6\u6d88\u53d1\u9001\n#define YMODEM_SENDER_STATE_ERROR  0x04 \/\/\u51fa\u9519\n\n\/\/\u8d85\u65f6\u65f6\u957f\u914d\u7f6e\uff0c\u5355\u4f4d\u662f ms\n#define YMODEM_SENDER_TIMEOUT      3500\n\n\/\/\u6700\u5927\u91cd\u53d1\u6b21\u6570\u914d\u7f6e\n#define YMODEM_SENDER_MAX_RETRY    10\n\n\/\/\u9519\u8bef\u5b9a\u4e49\n#define YMODEM_SENDER_INFO_NULL      0x00 \/\/\u65e0\u9519\u8bef\n#define YMODEM_SENDER_INFO_TIMEOUT   0x01 \/\/\u63a5\u6536\u65b9\u56de\u5e94\u8d85\u65f6\n#define YMODEM_SENDER_INFO_RETRY_OUT 0x02 \/\/\u91cd\u65b0\u53d1\u9001\u6b21\u6570\u8d85\u8fc7\u4e86\u6700\u5927\u503c\n#define YMODEM_SENDER_INFO_FINISH    0x03 \/\/\u4f20\u8f93\u5b8c\u6210\n#define YMODEM_SENDER_INFO_CANCEL    0x04 \/\/\u68c0\u6d4b\u5230\u7528\u6237\u53d1\u8d77\u4e86\u53d6\u6d88\u4f20\u8f93\n\n\/*********************************************************************************************************\n*                                              \u679a\u4e3e\u7ed3\u6784\u4f53\u5b9a\u4e49\n*********************************************************************************************************\/\n\n\/*********************************************************************************************************\n*                                              API\u51fd\u6570\u58f0\u660e\n*********************************************************************************************************\/\nvoid         InitYmodemSender(void);                                                  \/\/\u521d\u59cb\u5316\nvoid         YmodemSenderPoll(unsigned int period);                                   \/\/\u8f6e\u8be2\nunsigned int YmodemSenderStart(char* fileName, unsigned char* buf, unsigned int len); \/\/\u5f00\u59cb\u4f20\u8f93\nunsigned int YmodemSenderGetStaus(void);                                              \/\/\u83b7\u53d6\u5f53\u524d\u72b6\u6001\nunsigned int YmodemSenderGetAmountOfSended(void);                                     \/\/\u83b7\u53d6\u5df2\u7ecf\u53d1\u9001\u7684\u6570\u636e\u91cf\nvoid         YmodemSenderCancel(void);                                                \/\/\u53d6\u6d88\u53d1\u9001\n\n\/\/\u9700\u8981\u79fb\u690d\u7684\u51fd\u6570\nunsigned int YmodemSenderWrite(unsigned char* buf, unsigned int len);                 \/\/\u53d1\u9001\u6587\u4ef6\u6570\u636e\nunsigned int YmodemSenderRead(unsigned char* buf, unsigned int len);                  \/\/\u63a5\u6536\u56de\u5e94\nvoid         YmodemSenderInfo(unsigned int info);                                     \/\/\u4e0a\u62a5\u4fe1\u606f\n\n#endif\n<\/code><\/pre>\n\n\n\n<p>\u6e90\u6587\u4ef6\u5982\u4e0b\u6240\u793a\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/*********************************************************************************************************\n* \u6a21\u5757\u540d\u79f0\uff1a YmodemSender.c\n* \u6458    \u8981\uff1a Ymodem \u534f\u8bae\u53d1\u9001\u65b9\n* \u5f53\u524d\u7248\u672c\uff1a 1.0.0\n* \u4f5c    \u8005\uff1a SZLY(COPYRIGHT 2018 - 2020 SZLY. All rights reserved.)\n* \u5b8c\u6210\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5 \n* \u5185    \u5bb9\uff1a \n* \u6ce8    \u610f\uff1a \n**********************************************************************************************************\n* \u53d6\u4ee3\u7248\u672c\uff1a\n* \u4f5c    \u8005\uff1a\n* \u5b8c\u6210\u65e5\u671f\uff1a\n* \u4fee\u6539\u5185\u5bb9\uff1a\n* \u4fee\u6539\u6587\u4ef6\uff1a\n*********************************************************************************************************\/\n\n\/*********************************************************************************************************\n*                                              \u5305\u542b\u5934\u6587\u4ef6\n*********************************************************************************************************\/\n#include \"YmodemSender.h\"\n\n\/*********************************************************************************************************\n*                                              \u5b8f\u5b9a\u4e49\n*********************************************************************************************************\/\n#define MAX_STRING_CONVER_LEN 64 \/\/\u5b57\u7b26\u4e32\u8f6c\u6362\u6700\u5927\u957f\u5ea6\n\n\/*********************************************************************************************************\n*                                              \u679a\u4e3e\u7ed3\u6784\u4f53\u5b9a\u4e49\n*********************************************************************************************************\/\n\/\/\u53d1\u9001\u72b6\u6001\u673a\u5b9a\u4e49\ntypedef enum\n{\n  STAET_INIT_START,                  \/\/\u521d\u59cb\u5316\uff0c\u51c6\u5907\u4f20\u8f93\n  STATE_WAIT_RECEIVER_REQUEST_START, \/\/\u7b49\u5f85\u63a5\u6536\u65b9\u53d1\u8d77\u8bf7\u6c42\u8d77\u59cb\u5e27\n  STATE_SEND_START_PACK,             \/\/\u53d1\u9001\u8d77\u59cb\u5e27\n  STATE_WAIT_START_PACK_ACK,         \/\/\u7b49\u5f85\u8d77\u59cb\u5e27\u7684\u56de\u5e94\n  STATE_WAIT_RECEIVER_REQUEST_DATA,  \/\/\u7b49\u5f85\u63a5\u6536\u65b9\u53d1\u8d77\u8bf7\u6c42\u6570\u636e\u5e27\n  STATE_SEND_DATA_PACK,              \/\/\u53d1\u9001\u6570\u636e\u5e27\n  STATE_WAIT_DATA_PACK_ACK,          \/\/\u7b49\u5f85\u6570\u636e\u5e27\u7684\u56de\u5e94\uff08\u91cd\u53d1\u5904\u7406\u5728\u8fd9\u91cc\u5b8c\u6210\uff09\n  STATE_SEND_EOT0_PACK,              \/\/\u7b2c\u4e00\u6b21\u53d1\u9001\u4f20\u8f93\u7ed3\u675f\n  STATE_WAIT_EOT0_ACK,               \/\/\u7b49\u5f85 NAK\uff08\u54cd\u5e94\u7ed3\u675f\u547d\u4ee4\uff09\u56de\u5e94\n  STATE_SEND_EOT1_PACK,              \/\/\u7b2c\u4e8c\u6b21\u53d1\u9001\u4f20\u8f93\u7ed3\u675f\n  STATE_WAIT_EOT1_ACK,               \/\/\u7b49\u5f85 ACK \u56de\u5e94\n  STATE_WAIT_EOT1_C,                 \/\/\u7b49\u5f85 C\uff08\u8bf7\u6c42\u7ed3\u675f\u5e27\uff09\u56de\u5e94\n  STATE_SEND_END_PACK,               \/\/\u53d1\u9001\u4f20\u8f93\u7ed3\u675f\u5e27\n  STATE_WAIT_END_ACK,                \/\/\u7b49\u5f85\u4f20\u8f93\u7ed3\u675f\u5e27\u56de\u5e94\n}EnumYmodemState;\n\n\/*********************************************************************************************************\n*                                              \u5185\u90e8\u53d8\u91cf\n*********************************************************************************************************\/\n\/\/\u72b6\u6001\nstatic unsigned int s_iSenderState = YMODEM_SENDER_STATE_IDLE;\n\n\/\/\u6587\u4ef6\u4fe1\u606f\u8bb0\u5f55\nstatic char* s_pFileName;\nstatic unsigned char* s_pFileSource;\nstatic unsigned int s_iFileSize;\n\n\/\/\u5df2\u7ecf\u53d1\u9001\u7684\u6570\u636e\u91cf\u8ba1\u6570\nstatic unsigned int s_iDataCnt = 0;\n\n\/\/\u5f53\u524d\u6570\u636e\u5305\u8bb0\u5f55\nstatic unsigned int s_iPackNumCnt = 0;\n\n\/\/\u6570\u636e\u5305\nstatic unsigned char s_arrCurrentPack[1029];\nstatic unsigned char s_arrCurrentPack2[128];\nstatic unsigned int s_iCurrentPackSize;\n\n\/\/\u5b57\u7b26\u4e32\u8f6c\u6362\u7f13\u51b2\u533a\nstatic const char s_arrNumTable[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };\nstatic char s_arrStringBuf[MAX_STRING_CONVER_LEN];\n\n\/\/\u53d1\u9001\u72b6\u6001\u673a\nstatic EnumYmodemState s_enumYmodemState = STAET_INIT_START;\n\n\/\/\u53d1\u9001\u65f6\u9700\u8981\u4f7f\u7528\u5230\u7684\u9759\u6001\u53d8\u91cf\nstatic unsigned int s_iTimeOutCnt = 0;\nstatic unsigned int s_iRetryCnt = 0;\n\n\/*********************************************************************************************************\n*                                              \u5185\u90e8\u51fd\u6570\u58f0\u660e\n*********************************************************************************************************\/\nstatic void           PutDecUint(unsigned int num, unsigned int width);                              \/\/\u6574\u578b\u8f6c\u5b57\u7b26\u4e32\nstatic unsigned short CalCRC(unsigned char* data, unsigned int size);                                \/\/\u8ba1\u7b97 CRC \u6821\u9a8c\nstatic void           SendPack128(unsigned char header, unsigned char oder, unsigned char* buf);     \/\/\u53d1\u9001\u77ed\u5305\nstatic void           SendPack1024(unsigned char header, unsigned char oder, unsigned char* buf);    \/\/\u53d1\u9001\u957f\u5305\nstatic void           SendBeginPack(void);                                                           \/\/\u53d1\u9001\u8d77\u59cb\u5e27\nstatic void           SendEndPack(void);                                                             \/\/\u53d1\u9001\u7ed3\u675f\u5e27\nstatic void           SendFileLastPack(unsigned char oder, unsigned char* buf, unsigned int remain); \/\/\u53d1\u9001\u6587\u4ef6\u4e0d\u8db3 128 \u5b57\u8282\u90e8\u5206\u6570\u636e\nstatic unsigned int   WaitForAck(unsigned int period);                                               \/\/\u7b49\u5f85 ACK \u56de\u5e94\nstatic unsigned int   WaitForC(unsigned int period);                                                 \/\/\u7b49\u5f85 C \u56de\u5e94\n\n\/*********************************************************************************************************\n*                                              \u5185\u90e8\u51fd\u6570\u5b9e\u73b0\n*********************************************************************************************************\/\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1aPutUint\n* \u51fd\u6570\u529f\u80fd\uff1a\u6574\u578b\u8f6c\u5b57\u7b26\u4e32\n* \u8f93\u5165\u53c2\u6570\uff1anum\uff1a\u663e\u793a\u6570\u503c\uff0cwidth\uff1a\u663e\u793a\u5bbd\u5ea6\uff0c\u4e0d\u8db3\u8865\u96f6\n* \u8f93\u51fa\u53c2\u6570\uff1avoid\n* \u8fd4 \u56de \u503c\uff1avoid\n* \u521b\u5efa\u65e5\u671f\uff1a2021\u5e7407\u670801\u65e5\n* \u6ce8    \u610f\uff1a\n*********************************************************************************************************\/\nvoid PutDecUint(unsigned int num, unsigned int width)\n{\n  unsigned int divisor;      \/\/\u9664\u65701\u300110\u3001100\u30011000...\n  unsigned int widthDivisor; \/\/\u663e\u793a\u5b8c\u6574\u5bbd\u5ea6\u9700\u8981\u7684\u9664\u6570\u5927\u5c0f\n  unsigned int needDivisor;  \/\/\u663e\u793a\u5b8c\u6574\u6570\u5b57\u9700\u8981\u7684\u9664\u6570\u5927\u5c0f\n  unsigned int stringCnt;    \/\/\u5b57\u7b26\u4e32\u8ba1\u6570\n  unsigned int digital;      \/\/\u5355\u4e2a\u4f4d\u6570\u636e\n\n  \/\/\u8ba1\u7b97\u663e\u793a\u4f4d\u5bbd\u4e0b\u9700\u8981\u7684\u9664\u6570\u5927\u5c0f\n  widthDivisor = 1;\n  while (width)\n  {\n    width--;\n    widthDivisor = widthDivisor * 10;\n  }\n  widthDivisor = widthDivisor \/ 10;\n\n  \/\/\u8ba1\u7b97\u663e\u793a\u5b8c\u6574\u6570\u5b57\u9700\u8981\u7684\u9664\u6570\u5927\u5c0f\n  needDivisor = 1;\n  while (num &gt;= needDivisor)\n  {\n    needDivisor = needDivisor * 10;\n  }\n  needDivisor = needDivisor \/ 10;\n\n  \/\/\u786e\u5b9a\u9664\u6570\u521d\u503c\n  if (widthDivisor &gt; needDivisor)\n  {\n    divisor = widthDivisor;\n  }\n  else\n  {\n    divisor = needDivisor;\n  }\n\n  \/\/\u5b57\u7b26\u4e32\u8f6c\u6362\n  stringCnt = 0;\n  while (1)\n  {\n    \/\/\u5df2\u7ecf\u5230\u4e2a\u4f4d\u4e86\n    if (1 == divisor)\n    {\n      digital = num;\n      s_arrStringBuf[stringCnt++] = s_arrNumTable[digital];\n      break;\n    }\n    else\n    {\n      digital = num \/ divisor; \/\/\u53d6\u51fa\u9ad8\u4f4d\n      num = num % divisor; \/\/\u5c06\u9ad8\u4f4d\u5254\u9664\n      divisor = divisor \/ 10;  \/\/\u66f4\u65b0\u9664\u6570\n      s_arrStringBuf[stringCnt++] = s_arrNumTable[digital]; \/\/\u6570\u503c\u8f6cASCII\u7801\n    }\n  }\n  s_arrStringBuf[stringCnt] = 0;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a CalCRC\n* \u51fd\u6570\u529f\u80fd\uff1a \u8ba1\u7b97 CRC \u6821\u9a8c\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a 16 \u4f4d CRC \u6821\u9a8c\u7684\u9664\u6570\u591a\u9879\u5f0f\u4e3a X^16 + X^12 + X^5 + 1\n*********************************************************************************************************\/\nstatic unsigned short UpdateCRC16(unsigned short crcIn, unsigned char byte)\n{\n  unsigned int crc = crcIn;\n  unsigned int in = byte | 0x100;\n  do\n  {\n    crc &lt;&lt;= 1;\n    in &lt;&lt;= 1;\n    if (in &amp; 0x100)\n    {\n      ++crc;\n    }\n    if (crc &amp; 0x10000)\n    {\n      crc ^= 0x1021;\n    }\n  } while (!(in &amp; 0x10000));\n  return crc &amp; 0xffffu;\n}\nstatic unsigned short CalCRC(unsigned char* data, unsigned int size)\n{\n  unsigned int crc = 0;\n  unsigned char* dataEnd = data + size;\n  while (data &lt; dataEnd)\n  {\n    crc = UpdateCRC16(crc, *data++);\n  }\n  crc = UpdateCRC16(crc, 0);\n  crc = UpdateCRC16(crc, 0);\n  return crc &amp; 0xffffu;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a SendPack128\n* \u51fd\u6570\u529f\u80fd\uff1a \u53d1\u9001\u77ed\u5305\n* \u8f93\u5165\u53c2\u6570\uff1a header\uff1a\u5e27\u5934\n*            oder  \uff1a\u5e27\u5e8f\u53f7\n*            buf   \uff1a\u6570\u636e\u7f13\u51b2\u533a\uff0c\u957f\u5ea6\u4e3a 128 \u5b57\u8282\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \u7981\u6b62\u7528 s_arrCurrentPack \u505a\u4e3a\u7f13\u51b2\u533a\n*********************************************************************************************************\/\nstatic void SendPack128(unsigned char header, unsigned char oder, unsigned char* buf)\n{\n  unsigned int i, j;\n  unsigned short crc16;\n\n  \/\/\u8bbe\u7f6e\u5e27\u5934\n  s_arrCurrentPack[0] = header;\n\n  \/\/\u8bbe\u7f6e\u5e27\u5e8f\u53f7\n  s_arrCurrentPack[1] = oder;\n\n  \/\/\u8bbe\u7f6e\u5e27\u5e8f\u53f7\u7684\u53d6\u53cd\n  s_arrCurrentPack[2] = ~oder;\n\n  \/\/\u62f7\u8d1d\u539f\u59cb\u6570\u636e\n  i = 0; j = 3;\n  while (i &lt; 128)\n  {\n    s_arrCurrentPack[j] = buf[i];\n    j++; i++;\n  }\n\n  \/\/\u8ba1\u7b97\u6821\u9a8c\u548c\n  crc16 = CalCRC(buf, 128);\n\n  \/\/\u586b\u5145 CRC \u9ad8\u4f4d\n  s_arrCurrentPack[131] = (crc16 &gt;&gt; 8) &amp; 0xFF;\n  s_arrCurrentPack[132] = (crc16 &gt;&gt; 0) &amp; 0xFF;\n\n  \/\/\u53d1\u9001\n  s_iCurrentPackSize = 133;\n  YmodemSenderWrite(s_arrCurrentPack, s_iCurrentPackSize);\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a SendPack1024\n* \u51fd\u6570\u529f\u80fd\uff1a \u53d1\u9001\u957f\u5305\n* \u8f93\u5165\u53c2\u6570\uff1a header\uff1a\u5e27\u5934\n*            oder  \uff1a\u5e27\u5e8f\u53f7\n*            buf   \uff1a\u6570\u636e\u7f13\u51b2\u533a\uff0c\u957f\u5ea6\u4e3a 1024 \u5b57\u8282\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \u7981\u6b62\u7528 s_arrCurrentPack \u505a\u4e3a\u7f13\u51b2\u533a\n*********************************************************************************************************\/\nstatic void SendPack1024(unsigned char header, unsigned char oder, unsigned char* buf)\n{\n  unsigned int i, j;\n  unsigned short crc16;\n\n  \/\/\u8bbe\u7f6e\u5e27\u5934\n  s_arrCurrentPack[0] = header;\n\n  \/\/\u8bbe\u7f6e\u5e27\u5e8f\u53f7\n  s_arrCurrentPack[1] = oder;\n\n  \/\/\u8bbe\u7f6e\u5e27\u5e8f\u53f7\u7684\u53d6\u53cd\n  s_arrCurrentPack[2] = ~oder;\n\n  \/\/\u62f7\u8d1d\u539f\u59cb\u6570\u636e\n  i = 0; j = 3;\n  while (i &lt; 1024)\n  {\n    s_arrCurrentPack[j] = buf[i];\n    j++; i++;\n  }\n\n  \/\/\u8ba1\u7b97\u6821\u9a8c\u548c\n  crc16 = CalCRC(buf, 1024);\n\n  \/\/\u586b\u5145 CRC \u9ad8\u4f4d\n  s_arrCurrentPack[1027] = (crc16 &gt;&gt; 8) &amp; 0xFF;\n  s_arrCurrentPack[1028] = (crc16 &gt;&gt; 0) &amp; 0xFF;\n\n  \/\/\u53d1\u9001\n  s_iCurrentPackSize = 1029;\n  YmodemSenderWrite(s_arrCurrentPack, s_iCurrentPackSize);\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a SendBeginPack\n* \u51fd\u6570\u529f\u80fd\uff1a \u53d1\u9001\u8d77\u59cb\u5e27\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a\n*********************************************************************************************************\/\nstatic void SendBeginPack(void)\n{\n  unsigned int i, j;\n\n  \/\/\u4fdd\u5b58\u6587\u4ef6\u540d\n  i = 0; j = 0;\n  while (0 != s_pFileName[i]) { s_arrCurrentPack2[j] = s_pFileName[i]; i++; j++; }\n  s_arrCurrentPack2[j] = 0;\n\n  \/\/\u4fdd\u5b58\u6587\u4ef6\u5927\u5c0f\n  PutDecUint(s_iFileSize, 1);\n  i = 0; j++;\n  while (0 != s_arrStringBuf[i]) { s_arrCurrentPack2[j] = s_arrStringBuf[i]; i++; j++; }\n  s_arrCurrentPack2[j] = 0;\n\n  \/\/\u5269\u4f59\u76f4\u63a5\u586b\u96f6\n  j++; while (j &lt; 128) { s_arrCurrentPack2[j] = 0; j++; }\n\n  \/\/\u53d1\u9001\n  SendPack128(YMODEM_SENDER_SOH, 0, s_arrCurrentPack2);\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a SendEndPack\n* \u51fd\u6570\u529f\u80fd\uff1a \u53d1\u9001\u7ed3\u675f\u5e27\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a\n*********************************************************************************************************\/\nstatic void SendEndPack(void)\n{\n  unsigned int j;\n\n  \/\/\u7f13\u51b2\u533a\u586b\u96f6\n  j = 0; while (j &lt; 128) { s_arrCurrentPack2[j] = 0; j++; }\n\n  \/\/\u53d1\u9001\n  SendPack128(YMODEM_SENDER_SOH, 0, s_arrCurrentPack2);\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a SendFileLastPack\n* \u51fd\u6570\u529f\u80fd\uff1a \u53d1\u9001\u6587\u4ef6\u4e0d\u8db3 128 \u5b57\u8282\u90e8\u5206\u6570\u636e\n* \u8f93\u5165\u53c2\u6570\uff1a order \uff1a\u5305\u5e8f\u53f7\n*            buf   \uff1a\u7f13\u51b2\u533a\u9996\u5730\u5740\n*            remain\uff1a\u8fd8\u5269\u4f59\u7684\u6570\u636e\u91cf\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a\n*********************************************************************************************************\/\nstatic void SendFileLastPack(unsigned char oder, unsigned char* buf, unsigned int remain)\n{\n  unsigned int i;\n\n  \/\/\u6570\u636e\u91cf\u4e3a\u96f6\uff0c\u76f4\u63a5\u8fd4\u56de\n  if(0 == remain) { return; }\n\n  \/\/\u586b\u5145\u7f13\u51b2\u533a\n  i = 0;\n  while (i &lt; remain)\n  {\n    s_arrCurrentPack2[i] = buf[i];\n    i++;\n  }\n  \n  \/\/\u5269\u4f59\u90e8\u5206\u586b\u5145 0x1A\n  while (i &lt; 128)\n  {\n    s_arrCurrentPack2[i] = 0x1A;\n    i++;\n  }\n\n  \/\/\u53d1\u9001\n  SendPack128(YMODEM_SENDER_SOH, oder, s_arrCurrentPack2);\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a WaitForC\n* \u51fd\u6570\u529f\u80fd\uff1a \u7b49\u5f85 C \u56de\u5e94\n* \u8f93\u5165\u53c2\u6570\uff1a period\uff1a\u8f6e\u8be2\u51fd\u6570\u5468\u671f\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a 0-\u83b7\u53d6 C \u5931\u8d25\uff0c1-\u83b7\u53d6 C \u6210\u529f\uff0c\u53ef\u4ee5\u8fdb\u5165\u4e0b\u4e00\u4e2a\u6b65\u9aa4\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a\n*********************************************************************************************************\/\nstatic unsigned int WaitForC(unsigned int period)\n{\n  unsigned char uData;\n  if (YmodemSenderRead(&amp;uData, 1))\n  {\n    if (YMODEM_SENDER_C == uData)\n    {\n      s_iTimeOutCnt = 0;\n      return 1;\n    }\n    else if (YMODEM_SENDER_CAN == uData)\n    {\n      s_iSenderState = YMODEM_SENDER_STATE_CANCEL;\n      YmodemSenderInfo(YMODEM_SENDER_INFO_CANCEL);\n    }\n  }\n  s_iTimeOutCnt = s_iTimeOutCnt + period;\n  if (s_iTimeOutCnt &gt;= YMODEM_SENDER_TIMEOUT)\n  {\n    s_iSenderState = YMODEM_SENDER_STATE_ERROR;\n    YmodemSenderInfo(YMODEM_SENDER_INFO_TIMEOUT);\n  }\n  return 0;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a WaitForAck\n* \u51fd\u6570\u529f\u80fd\uff1a \u7b49\u5f85 ACK \u56de\u5e94\n* \u8f93\u5165\u53c2\u6570\uff1a period\uff1a\u8f6e\u8be2\u51fd\u6570\u5468\u671f\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a 0-\u83b7\u53d6 ACK \u5931\u8d25\uff0c1-\u83b7\u53d6 ACK \u6210\u529f\uff0c\u53ef\u4ee5\u8fdb\u5165\u4e0b\u4e00\u4e2a\u6b65\u9aa4\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \n*********************************************************************************************************\/\nstatic unsigned int WaitForAck(unsigned int period)\n{\n  unsigned char uData;\n  if (YmodemSenderRead(&amp;uData, 1))\n  {\n    if (YMODEM_SENDER_ACK == uData) \/\/\u6536\u5230\u4e86 ACK\n    {\n      s_iTimeOutCnt = 0;\n      return 1;\n    }\n    else if (YMODEM_SENDER_NAK == uData) \/\/\u6536\u5230\u4e86 NACK\n    {\n      YmodemSenderWrite(s_arrCurrentPack, s_iCurrentPackSize);\n      s_iRetryCnt++;\n      if (s_iRetryCnt &gt;= YMODEM_SENDER_MAX_RETRY)\n      {\n        s_iSenderState = YMODEM_SENDER_STATE_ERROR;\n        YmodemSenderInfo(YMODEM_SENDER_INFO_RETRY_OUT);\n      }\n    }\n    else if ((YMODEM_SENDER_CAN == uData) &amp;&amp; (STATE_WAIT_END_ACK != s_enumYmodemState)) \/\/\u6536\u5230\u4e86 CANCEL\n    {\n      s_iSenderState = YMODEM_SENDER_STATE_CANCEL;\n      YmodemSenderInfo(YMODEM_SENDER_INFO_CANCEL);\n    }\n  }\n  s_iTimeOutCnt = s_iTimeOutCnt + period;\n  if (s_iTimeOutCnt &gt;= YMODEM_SENDER_TIMEOUT)\n  {\n    s_iSenderState = YMODEM_SENDER_STATE_ERROR;\n    YmodemSenderInfo(YMODEM_SENDER_INFO_TIMEOUT);\n  }\n  return 0;\n}\n\n\/*********************************************************************************************************\n*                                              API\u51fd\u6570\u5b9e\u73b0\n*********************************************************************************************************\/\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a InitYmodemSender\n* \u51fd\u6570\u529f\u80fd\uff1a \u521d\u59cb\u5316 Ymodem \u53d1\u9001\u65b9\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \n*********************************************************************************************************\/\nvoid InitYmodemSender(void)\n{\n  s_iSenderState = YMODEM_SENDER_STATE_IDLE;\n  s_enumYmodemState = STAET_INIT_START;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemSenderPoll\n* \u51fd\u6570\u529f\u80fd\uff1a \u8f6e\u8be2\n* \u8f93\u5165\u53c2\u6570\uff1a period\uff1a\u6267\u884c\u5468\u671f\uff0c\u4f8b\u5982\u6bcf\u9694 10ms \u6267\u884c\u4e00\u6b21\uff0cperiod \u8f93\u5165 10\uff0c\u4ee5\u6b64\u7c7b\u63a8\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \n*********************************************************************************************************\/\nvoid YmodemSenderPoll(unsigned int period)\n{\n  unsigned char uData;\n  unsigned int remain;\n\n  \/\/\u975e\u5fd9\u788c\uff0c\u76f4\u63a5\u8fd4\u56de\n  if(YMODEM_SENDER_STATE_BUSY != s_iSenderState) { return; }\n\n  \/\/\u51c6\u5907\u4f20\u8f93\n  if (STAET_INIT_START == s_enumYmodemState)\n  {\n    while (YmodemSenderRead(&amp;uData, 1)) {}\n    s_iTimeOutCnt = 0;\n    s_iRetryCnt = 0;\n    s_iPackNumCnt = 0;\n    s_iDataCnt = 0; \n    s_enumYmodemState = STATE_WAIT_RECEIVER_REQUEST_START;\n  }\n\n  \/\/\u7b49\u5f85\u63a5\u6536\u65b9\u53d1\u8d77\u8bf7\u6c42\u8d77\u59cb\u5e27\n  if (STATE_WAIT_RECEIVER_REQUEST_START == s_enumYmodemState)\n  {\n    if(1 == WaitForC(period)) { s_enumYmodemState = STATE_SEND_START_PACK; }\n  }\n\n  \/\/\u53d1\u9001\u8d77\u59cb\u5e27\n  if (STATE_SEND_START_PACK == s_enumYmodemState)\n  {\n    SendBeginPack();\n    s_iTimeOutCnt = 0;\n    s_iRetryCnt = 0;\n    s_enumYmodemState = STATE_WAIT_START_PACK_ACK;\n  }\n\n  \/\/\u7b49\u5f85\u8d77\u59cb\u5e27\u7684\u56de\u5e94\n  if (STATE_WAIT_START_PACK_ACK == s_enumYmodemState)\n  {\n    if (1 == WaitForAck(period)) { s_enumYmodemState = STATE_WAIT_RECEIVER_REQUEST_DATA; }\n  }\n\n  \/\/\u7b49\u5f85\u63a5\u6536\u65b9\u53d1\u8d77\u8bf7\u6c42\u6570\u636e\u5e27\n  if (STATE_WAIT_RECEIVER_REQUEST_DATA == s_enumYmodemState)\n  {\n    if (1 == WaitForC(period)) { s_enumYmodemState = STATE_SEND_DATA_PACK; }\n  }\n\n  \/\/\u53d1\u9001\u6570\u636e\u5e27\n  if (STATE_SEND_DATA_PACK == s_enumYmodemState)\n  {\n    \/\/\u66f4\u65b0\u6570\u636e\u5305\u5e8f\u53f7\n    s_iPackNumCnt++;\n\n    \/\/\u7edf\u8ba1\u5269\u4f59\u6570\u636e\u91cf\n    remain = s_iFileSize - s_iDataCnt;\n\n    \/\/\u5269\u4f59\u6570\u636e\u91cf\u4e3a\u96f6\uff0c\u76f4\u63a5\u8df3\u8f6c\u5230\u7b2c\u4e00\u6b21\u53d1\u9001\u4f20\u8f93\u7ed3\u675f\n    if (0 == remain)\n    {\n      s_enumYmodemState = STATE_SEND_EOT0_PACK;\n      goto STATE_SEND_EOT0_PACK_MARK;\n    }\n\n    \/\/\u6570\u636e\u5305\u957f\u5ea6\u5927\u4e8e\u7b49\u4e8e 1024\n    if (remain &gt;= 1024)\n    {\n      SendPack1024(YMODEM_SENDER_STX, s_iPackNumCnt, s_pFileSource + s_iDataCnt);\n      s_iDataCnt = s_iDataCnt + 1024;\n      s_iTimeOutCnt = 0;\n      s_iRetryCnt = 0;\n      s_enumYmodemState = STATE_WAIT_DATA_PACK_ACK;\n    }\n\n    \/\/\u5305\u957f\u5ea6\u5927\u4e8e\u7b49\u4e8e 128 \u5c0f\u4e8e 1024\n    else if (remain &gt;= 128)\n    {\n      SendPack128(YMODEM_SENDER_SOH, s_iPackNumCnt, s_pFileSource + s_iDataCnt);\n      s_iDataCnt = s_iDataCnt + 128;\n      s_iTimeOutCnt = 0;\n      s_iRetryCnt = 0;\n      s_enumYmodemState = STATE_WAIT_DATA_PACK_ACK;\n    }\n\n    \/\/\u5305\u957f\u5ea6\u5c0f\u4e8e 128\n    else\n    {\n      SendFileLastPack(s_iPackNumCnt, s_pFileSource + s_iDataCnt, remain);\n      s_iDataCnt = s_iDataCnt + remain;\n      s_iTimeOutCnt = 0;\n      s_iRetryCnt = 0;\n      s_enumYmodemState = STATE_WAIT_DATA_PACK_ACK;\n    }\n  }\n\n  \/\/\u7b49\u5f85\u6570\u636e\u5e27\u7684\u56de\u5e94\uff08\u91cd\u53d1\u5904\u7406\u5728\u8fd9\u91cc\u5b8c\u6210\uff09\n  if (STATE_WAIT_DATA_PACK_ACK == s_enumYmodemState)\n  {\n    if (1 == WaitForAck(period)) { s_enumYmodemState = STATE_SEND_DATA_PACK; }\n  }\n\n  \/\/\u7b2c\u4e00\u6b21\u53d1\u9001\u4f20\u8f93\u7ed3\u675f\nSTATE_SEND_EOT0_PACK_MARK:\n  if (STATE_SEND_EOT0_PACK == s_enumYmodemState)\n  {\n    uData = YMODEM_SENDER_EOT;\n    YmodemSenderWrite(&amp;uData, 1);\n    s_iTimeOutCnt = 0;\n    s_enumYmodemState = STATE_WAIT_EOT0_ACK;\n  }\n\n  \/\/\u7b49\u5f85 NAK\uff08\u54cd\u5e94\u7ed3\u675f\u547d\u4ee4\uff09\u56de\u5e94\n  if (STATE_WAIT_EOT0_ACK == s_enumYmodemState)\n  {\n    if (YmodemSenderRead(&amp;uData, 1))\n    {\n      if (YMODEM_SENDER_NAK == uData)\n      {\n        s_iTimeOutCnt = 0;\n        s_enumYmodemState = STATE_SEND_EOT1_PACK;\n      }\n      else if (YMODEM_SENDER_CAN == uData)\n      {\n        s_iSenderState = YMODEM_SENDER_STATE_CANCEL;\n        YmodemSenderInfo(YMODEM_SENDER_INFO_CANCEL);\n        return;\n      }\n    }\n    s_iTimeOutCnt = s_iTimeOutCnt + period;\n    if (s_iTimeOutCnt &gt;= YMODEM_SENDER_TIMEOUT)\n    {\n      s_iSenderState = YMODEM_SENDER_STATE_ERROR;\n      YmodemSenderInfo(YMODEM_SENDER_INFO_TIMEOUT);\n    }\n  }\n\n  \/\/\u7b2c\u4e8c\u6b21\u53d1\u9001\u4f20\u8f93\u7ed3\u675f\n  if (STATE_SEND_EOT1_PACK == s_enumYmodemState)\n  {\n    uData = YMODEM_SENDER_EOT;\n    YmodemSenderWrite(&amp;uData, 1);\n    s_iTimeOutCnt = 0;\n    s_enumYmodemState = STATE_WAIT_EOT1_ACK;\n  }\n\n  \/\/\u7b49\u5f85 ACK \u56de\u5e94\n  if (STATE_WAIT_EOT1_ACK == s_enumYmodemState)\n  {\n    if (1 == WaitForAck(period)) { s_enumYmodemState = STATE_WAIT_EOT1_C; }\n  }\n\n  \/\/\u7b49\u5f85 C\uff08\u8bf7\u6c42\u7ed3\u675f\u5e27\uff09\u56de\u5e94\n  if (STATE_WAIT_EOT1_C == s_enumYmodemState)\n  {\n    if (YmodemSenderRead(&amp;uData, 1))\n    {\n      if (YMODEM_SENDER_C == uData)\n      {\n        s_iTimeOutCnt = 0;\n        s_enumYmodemState = STATE_SEND_END_PACK;\n      }\n      else if (YMODEM_SENDER_CAN == uData)\n      {\n        s_iSenderState = YMODEM_SENDER_STATE_CANCEL;\n        YmodemSenderInfo(YMODEM_SENDER_INFO_CANCEL);\n        return;\n      }\n    }\n    s_iTimeOutCnt = s_iTimeOutCnt + period;\n    if (s_iTimeOutCnt &gt;= YMODEM_SENDER_TIMEOUT)\n    {\n      s_iSenderState = YMODEM_SENDER_STATE_ERROR;\n      YmodemSenderInfo(YMODEM_SENDER_INFO_TIMEOUT);\n    }\n  }\n\n  \/\/\u53d1\u9001\u4f20\u8f93\u7ed3\u675f\u5e27\n  if (STATE_SEND_END_PACK == s_enumYmodemState)\n  {\n    SendEndPack();\n    s_iTimeOutCnt = 0;\n    s_iRetryCnt = 0;\n    s_enumYmodemState = STATE_WAIT_END_ACK;\n  }\n\n  \/\/\u7b49\u5f85\u4f20\u8f93\u7ed3\u675f\u5e27\u56de\u5e94\n  if (STATE_WAIT_END_ACK == s_enumYmodemState)\n  {\n    if (1 == WaitForAck(period)) \n    { \n      s_enumYmodemState = STAET_INIT_START;\n      s_iSenderState = YMODEM_SENDER_STATE_FINISH;\n      YmodemSenderInfo(YMODEM_SENDER_INFO_FINISH);\n    }\n  }\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemSenderStart\n* \u51fd\u6570\u529f\u80fd\uff1a \u5f00\u59cb\u53d1\u9001\n* \u8f93\u5165\u53c2\u6570\uff1a fileName\uff1a\u6587\u4ef6\u540d\n*            buf     \uff1a\u6587\u4ef6\u6570\u636e\u9996\u5730\u5740\n*            len     \uff1a\u6587\u4ef6\u5927\u5c0f\uff0c\u5355\u4f4d\u662f\u5b57\u8282\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a 0-\u6210\u529f\u3002\u5176\u5b83-\u5931\u8d25\uff0c\u56e0\u4e3a\u6b63\u5728\u53d1\u9001\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \n*            1\u3001\u542f\u52a8\u53d1\u9001\u540e\uff0c\u6bcf\u9694\u4e00\u6bb5\u65f6\u95f4\u8c03\u7528 YmodemSenderPoll \u51fd\u6570\n*            2\u3001fileName \u548c buf \u6240\u6307\u5411\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u5728\u6574\u4e2a\u53d1\u9001\u8fc7\u7a0b\u4e2d\uff0c\u90fd\u4e0d\u5141\u8bb8\u53d1\u751f\u53d8\u52a8\n*********************************************************************************************************\/\nunsigned int YmodemSenderStart(char* fileName, unsigned char* buf, unsigned int len)\n{\n  \/\/\u6b63\u5728\u53d1\u9001\uff0c\u76f4\u63a5\u8fd4\u56de\n  if (YMODEM_SENDER_STATE_BUSY == s_iSenderState)\n  {\n    return 1;\n  }\n\n  \/\/\u8bb0\u5f55\u6587\u4ef6\u540d\n  s_pFileName = fileName;\n\n  \/\/\u8bb0\u5f55\u6587\u4ef6\u8d44\u6e90\u9996\u5730\u5740\n  s_pFileSource = buf;\n\n  \/\/\u8bb0\u5f55\u6587\u4ef6\u5927\u5c0f\n  s_iFileSize = len;\n\n  \/\/\u6807\u8bb0\u72b6\u6001\u4e3a\u5f00\u59cb\u53d1\u9001\n  s_iSenderState = YMODEM_SENDER_STATE_BUSY;\n  s_enumYmodemState = STAET_INIT_START;\n\n  \/\/\u6210\u529f\n  return 0;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemSenderGetStaus\n* \u51fd\u6570\u529f\u80fd\uff1a \u83b7\u53d6\u5f53\u524d\u72b6\u6001\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \n*********************************************************************************************************\/\nunsigned int YmodemSenderGetStaus(void)\n{\n  return s_iSenderState;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemSenderGetAmountOfSended\n* \u51fd\u6570\u529f\u80fd\uff1a \u83b7\u53d6\u5df2\u7ecf\u53d1\u9001\u7684\u6570\u636e\u91cf\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a \u5df2\u7ecf\u53d1\u9001\u7684\u6570\u636e\u91cf\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a\n*********************************************************************************************************\/\nunsigned int YmodemSenderGetAmountOfSended(void)\n{\n  return s_iDataCnt;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemSenderCancel\n* \u51fd\u6570\u529f\u80fd\uff1a \u53d6\u6d88\u53d1\u9001\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \n*********************************************************************************************************\/\nvoid YmodemSenderCancel(void)\n{\n  s_iSenderState = YMODEM_SENDER_STATE_IDLE;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemSenderWrite\n* \u51fd\u6570\u529f\u80fd\uff1a \u53d1\u9001\u6587\u4ef6\u6570\u636e\n* \u8f93\u5165\u53c2\u6570\uff1a buf\uff1a\u7f13\u51b2\u533a\u9996\u5730\u5740\u3002len\uff1a\u8bfb\u5199\u957f\u5ea6\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a \u6210\u529f\u8bfb\u5199\u7684\u6570\u636e\u91cf\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \n*            1\u3001\u9700\u8981\u79fb\u690d\n*            2\u3001\u79bb\u5f00\u6b64\u51fd\u6570\u65f6\uff0c\u9ed8\u8ba4\u6570\u636e\u5df2\u7ecf\u53d1\u9001\u5b8c\u6bd5\n*********************************************************************************************************\/\nunsigned int YmodemSenderWrite(unsigned char* buf, unsigned int len)\n{\n  unsigned int WriteUART(unsigned char* buf, unsigned int len);\n  return WriteUART(buf, len);\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemSenderRead\n* \u51fd\u6570\u529f\u80fd\uff1a \u63a5\u6536\u56de\u5e94\n* \u8f93\u5165\u53c2\u6570\uff1a buf\uff1a\u7f13\u51b2\u533a\u9996\u5730\u5740\u3002len\uff1a\u8bfb\u5199\u957f\u5ea6\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a \u6210\u529f\u8bfb\u5199\u7684\u6570\u636e\u91cf\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \n*            1\u3001\u9700\u8981\u79fb\u690d\n*            2\u3001\u8fd9\u91cc\u63a5\u6536\u7684\u662f\u4ece\u673a\u7684\u56de\u5e94\uff0c\u800c\u4e0d\u662f\u9700\u8981\u53d1\u9001\u7684\u6587\u4ef6\u7684\u6570\u636e\n*********************************************************************************************************\/\nunsigned int YmodemSenderRead(unsigned char* buf, unsigned int len)\n{\n  unsigned int ReadUART(unsigned char* buf, unsigned int len);\n  return ReadUART(buf, len);\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemSenderInfo\n* \u51fd\u6570\u529f\u80fd\uff1a \u4e0a\u62a5\u4fe1\u606f\n* \u8f93\u5165\u53c2\u6570\uff1a info\uff1a\u4fe1\u606f\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \u9700\u8981\u79fb\u690d\n*********************************************************************************************************\/\nvoid YmodemSenderInfo(unsigned int info)\n{\n  void SenderInfo(unsigned int info);\n  SenderInfo(info);\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"%E6%8E%A5%E6%94%B6%E9%A9%B1%E5%8A%A8\"><\/span>\u63a5\u6536\u9a71\u52a8<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>\u5934\u6587\u4ef6\u5982\u4e0b\u6240\u793a\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/*********************************************************************************************************\n* \u6a21\u5757\u540d\u79f0\uff1a YmodemReceiver.h\n* \u6458    \u8981\uff1a Ymodem \u534f\u8bae\u63a5\u6536\u65b9\n* \u5f53\u524d\u7248\u672c\uff1a 1.0.0\n* \u4f5c    \u8005\uff1a SZLY(COPYRIGHT 2018 - 2020 SZLY. All rights reserved.)\n* \u5b8c\u6210\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5 \n* \u5185    \u5bb9\uff1a\n* \u6ce8    \u610f\uff1a\n**********************************************************************************************************\n* \u53d6\u4ee3\u7248\u672c\uff1a\n* \u4f5c    \u8005\uff1a\n* \u5b8c\u6210\u65e5\u671f\uff1a\n* \u4fee\u6539\u5185\u5bb9\uff1a\n* \u4fee\u6539\u6587\u4ef6\uff1a\n*********************************************************************************************************\/\n#ifndef _YMODEM_RECEIVER_H_\n#define _YMODEM_RECEIVER_H_\n\n\/*********************************************************************************************************\n*                                              \u5305\u542b\u5934\u6587\u4ef6\n*********************************************************************************************************\/\n\/\/\u534f\u8bae\u4e2d\u7528\u5230\u7684\u7b26\u53f7\n#define YMODEM_RECEIVER_SOH    0x01 \/\/Ymodem \u77ed\u5e27\u6570\u636e\u5934\n#define YMODEM_RECEIVER_STX    0x02 \/\/Ymodem \u957f\u5e27\u6570\u636e\u5934\n#define YMODEM_RECEIVER_EOT    0x04 \/\/\u53d1\u9001\u7ed3\u675f\n#define YMODEM_RECEIVER_ACK    0x06 \/\/\u5e94\u7b54\n#define YMODEM_RECEIVER_NAK    0x15 \/\/\u975e\u5e94\u7b54\n#define YMODEM_RECEIVER_CAN    0x18 \/\/\u53d6\u6d88\u53d1\u9001\n#define YMODEM_RECEIVER_C      0x43 \/\/\u8bf7\u6c42\u6570\u636e\n\n\/\/\u5176\u5b83\u5305\u957f\u7684\u5e27\u5934\n#define YMODEM_RECEIVER_STX_8B   0xA1\n#define YMODEM_RECEIVER_STX_16B  0xA2\n#define YMODEM_RECEIVER_STX_32B  0xA3\n#define YMODEM_RECEIVER_STX_64B  0xA4\n#define YMODEM_RECEIVER_STX_128B 0xA5\n#define YMODEM_RECEIVER_STX_256B 0xA6\n#define YMODEM_RECEIVER_STX_512B 0xA7\n#define YMODEM_RECEIVER_STX_1KB  0xA8\n#define YMODEM_RECEIVER_STX_2KB  0XA9\n\n\/\/\u8d85\u65f6\u65f6\u95f4\u914d\u7f6e\uff0c\u63a5\u6536\u5230\u5305\u5934\u540e\uff0c\u8d85\u8fc7\u6b64\u65f6\u95f4\u672a\u6536\u5230\u65b0\u7684\u5b57\u8282\u5219\u8ba4\u4e3a\u6709\u4e22\u5305\u4e8b\u4ef6\n\/\/0 \u8868\u793a\u4e0d\u8bbe\u7f6e\u8d85\u65f6\u65f6\u95f4\n#define YMODEM_RECEIVER_MAX_TIMEOUT 100\n\n\/\/\u53d1\u9001\u8bf7\u6c42\u6570\u636e\u5e27\u7684\u65f6\u95f4\u9891\u7387\uff0c\u907f\u514d\u53d1\u9001\u592a\u591a\u7684\u8bf7\u6c42\u7ed9\u4e0a\u4f4d\u673a\n\/\/0 \u8868\u793a\u4e0d\u8bbe\u7f6e\uff0c\u4ee5\u6700\u9ad8\u901f\u5ea6\uff08\u8f6e\u8be2\u51fd\u6570\u6267\u884c\u7684\u987a\u5e8f\uff09\u53d1\u9001\n#define YMODEM_RECEIVER_REQUEST_TIME 3000\n\n\/\/\u72b6\u6001\n#define YMODEM_RECEIVER_IDLE   0x00 \/\/\u7a7a\u95f2\u72b6\u6001\n#define YMODEM_RECEIVER_BUSY   0x01 \/\/\u5fd9\u788c\n#define YMODEM_RECEIVER_FINISH 0x02 \/\/\u4f20\u8f93\u5b8c\u6210\n\n\/\/\u4fe1\u606f\n#define YMODEM_RECEIVER_INFO_START  0x01 \/\/\u6536\u5230\u4e86\u8d77\u59cb\u5e27\n#define YMODEM_RECEIVER_INFO_FINISH 0x02 \/\/\u4f20\u8f93\u5b8c\u6210\n\n\/*********************************************************************************************************\n*                                              \u5b8f\u5b9a\u4e49\n*********************************************************************************************************\/\n\n\/*********************************************************************************************************\n*                                              \u679a\u4e3e\u7ed3\u6784\u4f53\u5b9a\u4e49\n*********************************************************************************************************\/\n\n\/*********************************************************************************************************\n*                                              API\u51fd\u6570\u58f0\u660e\n*********************************************************************************************************\/\nvoid         InitYmodemReceiver(void);                \/\/\u521d\u59cb\u5316\nvoid         YmodemReceiverPoll(unsigned int period); \/\/\u8f6e\u8be2\nvoid         YmodemReceiverStart(void);               \/\/\u5f00\u59cb\u63a5\u6536\u6587\u4ef6\nunsigned int YmodemReceiverGetState(void);            \/\/\u83b7\u53d6\u72b6\u6001\nchar*        YmodemReceiverGetFileName(void);         \/\/\u83b7\u53d6\u6587\u4ef6\u540d\nunsigned int YmodemReceiverGetFileSize(void);         \/\/\u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\nunsigned int YmodemReceiverGetReadSize(void);         \/\/\u83b7\u53d6\u5df2\u7ecf\u63a5\u6536\u7684\u5b57\u8282\u6570\n\n\/\/\u9700\u8981\u79fb\u690d\u7684\u51fd\u6570\nunsigned int YmodemReceiverWrite(unsigned char* buf, unsigned int len);                       \/\/\u53d1\u9001\u56de\u5e94\nunsigned int YmodemReceiverRead(unsigned char* buf, unsigned int len);                        \/\/\u63a5\u6536\u6570\u636e\nvoid         YmodemReceiverInfo(unsigned int info);                                           \/\/\u4e0a\u62a5\u4fe1\u606f\nvoid         YmodemReceiverOutput(unsigned int offset, unsigned char* buf, unsigned int len); \/\/\u6570\u636e\u8f93\u51fa\n\n#endif\n<\/code><\/pre>\n\n\n\n<p>\u6e90\u6587\u4ef6\u5982\u4e0b\u6240\u793a\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/*********************************************************************************************************\n* \u6a21\u5757\u540d\u79f0\uff1a YmodemReceiver.c\n* \u6458    \u8981\uff1a Ymodem \u534f\u8bae\u63a5\u6536\u65b9\n* \u5f53\u524d\u7248\u672c\uff1a 1.0.0\n* \u4f5c    \u8005\uff1a SZLY(COPYRIGHT 2018 - 2020 SZLY. All rights reserved.)\n* \u5b8c\u6210\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5 \n* \u5185    \u5bb9\uff1a\n* \u6ce8    \u610f\uff1a\n**********************************************************************************************************\n* \u53d6\u4ee3\u7248\u672c\uff1a\n* \u4f5c    \u8005\uff1a\n* \u5b8c\u6210\u65e5\u671f\uff1a\n* \u4fee\u6539\u5185\u5bb9\uff1a\n* \u4fee\u6539\u6587\u4ef6\uff1a\n*********************************************************************************************************\/\n\n\/*********************************************************************************************************\n*                                              \u5305\u542b\u5934\u6587\u4ef6\n*********************************************************************************************************\/\n#include \"YmodemReceiver.h\"\n\n\/*********************************************************************************************************\n*                                              \u5b8f\u5b9a\u4e49\n*********************************************************************************************************\/\n#ifndef NULL\n  #define NULL 0\n#endif\n\n\/*********************************************************************************************************\n*                                              \u679a\u4e3e\u7ed3\u6784\u4f53\u5b9a\u4e49\n*********************************************************************************************************\/\n\n\/*********************************************************************************************************\n*                                              \u5185\u90e8\u53d8\u91cf\n*********************************************************************************************************\/\n\/\/\u7cfb\u7edf\u72b6\u6001\nstatic unsigned int s_iReceiverState = YMODEM_RECEIVER_IDLE;\n\n\/\/\u4f20\u8f93\u6807\u5fd7\u4f4d\nstatic unsigned char s_iBeginFlag = 0;\nstatic unsigned char s_iGetStartPackFlag = 0;\nstatic unsigned char s_iInitFlag = 1;\nstatic unsigned char s_iEndCnt;\n\n\/\/\u6570\u636e\u5e27\u7f13\u51b2\u533a\nstatic unsigned char s_arrFrameBuf[2048 + 5];\nstatic unsigned int s_iFrameCnt;\n\n\/\/\u6587\u4ef6\u4fe1\u606f\nstatic char s_arrFileName[64];\nstatic unsigned int s_iFileSize;\nstatic unsigned int s_iReadByteCnt;\n\n\/*********************************************************************************************************\n*                                              \u5185\u90e8\u51fd\u6570\u58f0\u660e\n*********************************************************************************************************\/\nstatic int            StringToInt(char* string);                      \/\/10 \u8fdb\u5236\u5b57\u7b26\u4e32\u8f6c\u6574\u578b\nstatic unsigned short CalCRC(unsigned char* data, unsigned int size); \/\/\u8ba1\u7b97 CRC \u6821\u9a8c\n\n\/*********************************************************************************************************\n*                                              \u5185\u90e8\u51fd\u6570\u5b9e\u73b0\n*********************************************************************************************************\/\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a StringToInt\n* \u51fd\u6570\u529f\u80fd\uff1a 10 \u8fdb\u5236\u5b57\u7b26\u4e32\u8f6c\u6574\u578b\n* \u8f93\u5165\u53c2\u6570\uff1a string\uff1a\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u6570\u5b57\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a \u8f6c\u6362\u7ed3\u679c\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7402\u670810\u65e5\n* \u6ce8    \u610f\uff1a \u4e0d\u80fd\u542b\u6709\u6570\u5b57\u3001\u6b63\u8d1f\u53f7\u7b49\u5176\u5b83\u7b26\u53f7\n*********************************************************************************************************\/\nstatic int StringToInt(char* string)\n{\n  int sum;\n  int negative;\n  unsigned int i;\n  sum = 0;\n  i = 0;\n  negative = 0;\n  while (('+' == string[i]) || ('-' == string[i]) || ((string[i] &gt;= '0') &amp;&amp; (string[i] &lt;= '9')))\n  {\n    \/\/\u6b63\u53f7\n    if ('+' == string[i])\n    {\n      negative = 0;\n    }\n\n    \/\/\u8d1f\u53f7\n    else if ('-' == string[i])\n    {\n      negative = 1;\n    }\n\n    \/\/\u7a7a\u683c\n    else if (' ' == string[i])\n    {\n      \/\/\u4e0d\u505a\u5904\u7406\n    }\n\n    \/\/\u6570\u5b57\n    else if ((string[i] &gt;= '0') &amp;&amp; (string[i] &lt;= '9'))\n    {\n      sum = (sum * 10) + (string[i] - '0');\n    }\n\n    \/\/\u5faa\u73af\u53d8\u91cf\u52a0\u4e00\n    i++;\n  }\n\n  \/\/\u8d1f\u53f7\u5904\u7406\n  if (0 != negative)\n  {\n    sum = -sum;\n  }\n\n  \/\/\u8fd4\u56de\u8f6c\u6362\u7ed3\u679c\n  return sum;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a CalCRC\n* \u51fd\u6570\u529f\u80fd\uff1a \u8ba1\u7b97 CRC \u6821\u9a8c\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a 16 \u4f4d CRC \u6821\u9a8c\u7684\u9664\u6570\u591a\u9879\u5f0f\u4e3a X^16 + X^12 + X^5 + 1\n*********************************************************************************************************\/\nstatic unsigned short UpdateCRC16(unsigned short crcIn, unsigned char byte)\n{\n  unsigned int crc = crcIn;\n  unsigned int in = byte | 0x100;\n  do\n  {\n    crc &lt;&lt;= 1;\n    in &lt;&lt;= 1;\n    if(in &amp; 0x100)\n    {\n      ++crc;\n    }\n    if(crc &amp; 0x10000)\n    {\n      crc ^= 0x1021;\n    }\n  } while(!(in &amp; 0x10000));\n  return crc &amp; 0xffffu;\n}\nstatic unsigned short CalCRC(unsigned char* data, unsigned int size)\n{\n  unsigned int crc = 0;\n  unsigned char* dataEnd = data+size;\n  while(data &lt; dataEnd)\n  {\n    crc = UpdateCRC16(crc, *data++);\n  }\n  crc = UpdateCRC16(crc, 0);\n  crc = UpdateCRC16(crc, 0);\n  return crc &amp; 0xffffu;\n}\n\n\/*********************************************************************************************************\n*                                              API\u51fd\u6570\u5b9e\u73b0\n*********************************************************************************************************\/\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a InitYmodemReceiver\n* \u51fd\u6570\u529f\u80fd\uff1a \u521d\u59cb\u5316\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \n*********************************************************************************************************\/\nvoid InitYmodemReceiver(void)\n{\n  s_iBeginFlag = 0;\n  s_iReceiverState = YMODEM_RECEIVER_IDLE;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemReceiverPoll\n* \u51fd\u6570\u529f\u80fd\uff1a \u8f6e\u8be2\n* \u8f93\u5165\u53c2\u6570\uff1a period\uff1a\u6267\u884c\u5468\u671f\uff0c\u4f8b\u5982\u6bcf\u9694 10ms \u6267\u884c\u4e00\u6b21\uff0cperiod \u8f93\u5165 10\uff0c\u4ee5\u6b64\u7c7b\u63a8\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \u63a8\u8350 10ms \u8c03\u7528\u4e00\u6b21\n*********************************************************************************************************\/\nvoid YmodemReceiverPoll(unsigned int period)\n{\n#if (YMODEM_RECEIVER_MAX_TIMEOUT | YMODEM_RECEIVER_REQUEST_TIME)\n  static unsigned int s_iTimeCnt;\n#endif\n  static unsigned int s_iPackOrderCnt;\n  unsigned char uData;\n  unsigned int packLen, i, j, outputNum;\n  unsigned short crcInpack, crcCalc;\n\n  \/\/\u975e\u5fd9\u788c\u72b6\u6001\u76f4\u63a5\u8fd4\u56de\n  if(YMODEM_RECEIVER_BUSY != s_iReceiverState) { return; }\n\n  \/\/\u521d\u59cb\u5316\n  if (0 != s_iInitFlag)\n  {\n    s_iInitFlag = 0;\n    s_iBeginFlag = 0;\n    s_iGetStartPackFlag = 1;\n    s_iFrameCnt = 0;\n    s_iEndCnt = 0;\n    s_iReadByteCnt = 0;\n#if (YMODEM_RECEIVER_MAX_TIMEOUT | YMODEM_RECEIVER_REQUEST_TIME)\n    s_iTimeCnt = 0;\n#endif\n    s_iPackOrderCnt = 0;\n    while (YmodemReceiverRead(&amp;uData, 1)){}\n    uData = YMODEM_RECEIVER_C;\n    YmodemReceiverWrite(&amp;uData, 1);\n  }\n\n  \/\/\u5c1a\u672a\u6536\u5230\u8d77\u59cb\u5e27\uff0c\u8fde\u7eed\u53d1\u9001 \u201cC\u201d\n  if (0 == s_iBeginFlag)\n  {\n    if (YmodemReceiverRead(&amp;uData, 1))\n    {\n      if (YMODEM_RECEIVER_SOH == uData) \/\/\u5f00\u59cb\u4f20\u8f93\n      {\n        s_iBeginFlag = 1;\n        goto RECEIVER_READ_LOOP;\n      }\n    }\n#if (YMODEM_RECEIVER_REQUEST_TIME)\n    s_iTimeCnt = s_iTimeCnt + period;\n    if (s_iTimeCnt &gt;= YMODEM_RECEIVER_REQUEST_TIME)\n    {\n      s_iTimeCnt = 0;\n      uData = YMODEM_RECEIVER_C;\n      YmodemReceiverWrite(&amp;uData, 1);\n    }\n#else\n    uData = YMODEM_RECEIVER_C;\n    YmodemReceiverWrite(&amp;uData, 1);\n#endif\n    return;\n  }\n  \n  \/\/\u83b7\u53d6\u6570\u636e\n  while (YmodemReceiverRead(&amp;uData, 1))\n  {\nRECEIVER_READ_LOOP:\n\n#if (YMODEM_RECEIVER_MAX_TIMEOUT)\n    \/\/\u8d85\u65f6\u65f6\u95f4\u6e05\u96f6\n    s_iTimeCnt = 0;\n#endif\n\n    \/\/\u63a5\u6536\u5230\u7ed3\u675f\u547d\u4ee4\n    if ((0 == s_iFrameCnt) &amp;&amp; (YMODEM_RECEIVER_EOT == uData))\n    {\n      \/\/\u7b2c\u4e00\u6b21\u63a5\u6536\u5230\u7ed3\u675f\u547d\u4ee4\uff0c\u56de\u5e94 NAK\n      if (0 == s_iEndCnt)\n      {\n        uData = YMODEM_RECEIVER_NAK;\n        YmodemReceiverWrite(&amp;uData, 1);\n        s_iEndCnt++;\n      }\n\n      \/\/\u7b2c\u4e8c\u6b21\u63a5\u6536\u5230\u7ed3\u675f\u547d\u4ee4\uff0c\u56de\u5e94 ACK + C\n      else\n      {\n        uData = YMODEM_RECEIVER_ACK;\n        YmodemReceiverWrite(&amp;uData, 1);\n        uData = YMODEM_RECEIVER_C;\n        YmodemReceiverWrite(&amp;uData, 1);\n        s_iEndCnt++;\n      }\n    }\n\n    \/\/\u8d77\u59cb\u5e27\u6216\u6b63\u5e38\u7684\u6570\u636e\u5e27\n    else\n    {\n      \/\/\u5f02\u5e38\u7684\u5e27\u5934\n      if ((0 == s_iFrameCnt) &amp;&amp; (YMODEM_RECEIVER_SOH != uData) &amp;&amp; (YMODEM_RECEIVER_STX != uData) &amp;&amp;\n          (YMODEM_RECEIVER_STX_8B != uData) &amp;&amp; (YMODEM_RECEIVER_STX_16B != uData) &amp;&amp; (YMODEM_RECEIVER_STX_32B != uData) &amp;&amp;\n          (YMODEM_RECEIVER_STX_64B != uData) &amp;&amp; (YMODEM_RECEIVER_STX_128B != uData) &amp;&amp; (YMODEM_RECEIVER_STX_256B != uData) &amp;&amp;\n          (YMODEM_RECEIVER_STX_512B != uData) &amp;&amp; (YMODEM_RECEIVER_STX_1KB != uData) &amp;&amp; (YMODEM_RECEIVER_STX_2KB != uData))\n      {\n        s_iFrameCnt = 0;\n        \/\/uData = YMODEM_RECEIVER_NAK;\n        \/\/YmodemReceiverWrite(&amp;uData, 1);\n        return;\n      }\n\n      \/\/\u5305\u5e8f\u53f7\u4e0d\u5bf9\uff08\u8981\u6392\u9664\u7ed3\u675f\u5e27\u7684\u5e72\u6270\uff09\n      if ((0 == s_iEndCnt) &amp;&amp; (1 == s_iFrameCnt))\n      {\n        if (uData != s_iPackOrderCnt)\n        {\n          s_iFrameCnt = 0;\n          uData = YMODEM_RECEIVER_NAK;\n          YmodemReceiverWrite(&amp;uData, 1);\n          return;\n        }\n      }\n\n      \/\/\u5c06\u6570\u636e\u586b\u5145\u5230\u6570\u636e\u5305\n      if(s_iFrameCnt &lt; 1029) { s_arrFrameBuf[s_iFrameCnt++] = uData; }\n      \n      \/\/\u83b7\u53d6\u6570\u636e\u5305\u957f\u5ea6\n      if (YMODEM_RECEIVER_SOH == s_arrFrameBuf[0]) { packLen = 128 + 5; }\n      else if (YMODEM_RECEIVER_STX == s_arrFrameBuf[0]) { packLen = 1024 + 5; }\n      else if (YMODEM_RECEIVER_STX_8B == s_arrFrameBuf[0]) { packLen = 8 + 5; }\n      else if (YMODEM_RECEIVER_STX_16B == s_arrFrameBuf[0]) { packLen = 16 + 5; }\n      else if (YMODEM_RECEIVER_STX_32B == s_arrFrameBuf[0]) { packLen = 32 + 5; }\n      else if (YMODEM_RECEIVER_STX_64B == s_arrFrameBuf[0]) { packLen = 64 + 5; }\n      else if (YMODEM_RECEIVER_STX_128B == s_arrFrameBuf[0]) { packLen = 128 + 5; }\n      else if (YMODEM_RECEIVER_STX_256B == s_arrFrameBuf[0]) { packLen = 256 + 5; }\n      else if (YMODEM_RECEIVER_STX_512B == s_arrFrameBuf[0]) { packLen = 512 + 5; }\n      else if (YMODEM_RECEIVER_STX_1KB == s_arrFrameBuf[0]) { packLen = 1024 + 5; }\n      else { packLen = 2048 + 5; }\n\n      \/\/\u6570\u636e\u5305\u63a5\u6536\u5b8c\u6210\n      if (s_iFrameCnt &gt;= packLen)\n      {\n        \/\/\u5e27\u8ba1\u6570\u6e05\u96f6\n        s_iFrameCnt = 0;\n\n        \/\/\u8ba1\u7b97 CRC \u6821\u9a8c\n        crcCalc = CalCRC(s_arrFrameBuf + 3, packLen - 5);\n\n        \/\/\u83b7\u53d6\u6570\u636e\u5305\u4e2d\u7684 CRC \u6821\u9a8c\n        crcInpack = s_arrFrameBuf[packLen - 2] &amp; 0xFF; crcInpack = ((crcInpack &lt;&lt; 8) &amp; 0xFF00) | (s_arrFrameBuf[packLen - 1] &amp; 0xFF);\n\n        \/\/\u6821\u9a8c\u548c\u4e0d\u540c\n        if (crcInpack != crcCalc)\n        {\n          s_iFrameCnt = 0;\n          uData = YMODEM_RECEIVER_NAK;\n          YmodemReceiverWrite(&amp;uData, 1);\n          return;\n        }\n\n        \/\/\u5305\u8ba1\u6570\u52a0\u4e00\n        s_iPackOrderCnt = (s_iPackOrderCnt + 1) % 256;\n\n        \/\/\u8d77\u59cb\u5e27\n        if (0 != s_iGetStartPackFlag)\n        {\n          \/\/\u6807\u8bb0\u8d77\u59cb\u5e27\u5df2\u7ecf\u88ab\u83b7\u53d6\u5230\n          s_iGetStartPackFlag = 0;\n\n          \/\/\u89e3\u6790\u6587\u4ef6\u540d\n          i = 0; j = 3;\n          while (0 != s_arrFrameBuf[j]) { s_arrFileName[i] = s_arrFrameBuf[j]; i++; j++; }\n          s_arrFileName[i] = 0;\n\n          \/\/\u89e3\u6790\u6587\u4ef6\u5927\u5c0f\n          while(0 == s_arrFrameBuf[j]) { j++; }\n          s_iFileSize = StringToInt((char*)s_arrFrameBuf + j);\n\n          \/\/\u53d1\u9001\u8d77\u59cb\u5e27\u7684\u56de\u5e94\n          uData = YMODEM_RECEIVER_ACK;\n          YmodemReceiverWrite(&amp;uData, 1);\n\n          \/\/\u8bf7\u6c42\u6570\u636e\u5e27\n          uData = YMODEM_RECEIVER_C;\n          YmodemReceiverWrite(&amp;uData, 1);\n\n          \/\/\u4e0a\u62a5\u63a5\u6536\u5230\u4e86\u8d77\u59cb\u5e27\n          YmodemReceiverInfo(YMODEM_RECEIVER_INFO_START);\n        }\n\n        \/\/\u7ed3\u675f\u5e27\n        else if (0 != s_iEndCnt)\n        {\n          uData = YMODEM_RECEIVER_ACK;\n          YmodemReceiverWrite(&amp;uData, 1);\n          uData = YMODEM_RECEIVER_CAN;\n          YmodemReceiverWrite(&amp;uData, 1);\n          uData = YMODEM_RECEIVER_CAN;\n          YmodemReceiverWrite(&amp;uData, 1);\n          YmodemReceiverInfo(YMODEM_RECEIVER_INFO_FINISH);\n        }\n\n        \/\/\u6570\u636e\u5e27\n        else\n        {\n          \/\/\u8ba1\u7b97\u9700\u8981\u8f93\u51fa\u7684\u6570\u636e\u91cf\n          outputNum = s_iFileSize - s_iReadByteCnt;\n          if (outputNum &gt;= (packLen - 5))\n          {\n            outputNum = (packLen - 5);\n          }\n\n          \/\/\u8f93\u51fa\n          YmodemReceiverOutput(s_iReadByteCnt, s_arrFrameBuf + 3, outputNum);\n\n          \/\/\u66f4\u65b0\u8bb0\u5f55\n          s_iReadByteCnt = s_iReadByteCnt + outputNum;\n\n          \/\/\u53d1\u9001\u56de\u5e94\u4fe1\u53f7\n          uData = YMODEM_RECEIVER_ACK;\n          YmodemReceiverWrite(&amp;uData, 1);\n        }\n      }\n    }\n  }\n\n  \/\/\u8d85\u65f6\uff0c\u8bf7\u6c42\u91cd\u65b0\u53d1\u9001\u3002\u6536\u5230\u5e27\u5934\u4e4b\u540e\u624d\u5f00\u59cb\u7edf\u8ba1\u8d85\u65f6\n#if (YMODEM_RECEIVER_MAX_TIMEOUT)\n  if (0 != s_iFrameCnt)\n  {\n    s_iTimeCnt = s_iTimeCnt + period;\n    if (s_iTimeCnt &gt;= YMODEM_RECEIVER_MAX_TIMEOUT)\n    {\n      s_iTimeCnt = 0;\n      s_iFrameCnt = 0;\n      uData = YMODEM_RECEIVER_NAK;\n      YmodemReceiverWrite(&amp;uData, 1);\n    }\n  }\n#endif\n\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemReceiverStart\n* \u51fd\u6570\u529f\u80fd\uff1a \u5f00\u59cb\u63a5\u6536\u6587\u4ef6\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a\n*********************************************************************************************************\/\nvoid YmodemReceiverStart(void)\n{\n  s_iReceiverState = YMODEM_RECEIVER_BUSY;\n  s_iBeginFlag = 0;\n  s_iInitFlag = 1;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemReceiverGetState\n* \u51fd\u6570\u529f\u80fd\uff1a \u83b7\u53d6\u72b6\u6001\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a \u5f53\u524d\u72b6\u6001\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a\n*********************************************************************************************************\/\nunsigned int YmodemReceiverGetState(void)\n{\n  return s_iReceiverState;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemReceiverGetFileName\n* \u51fd\u6570\u529f\u80fd\uff1a \u83b7\u53d6\u6587\u4ef6\u540d\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a \u6587\u4ef6\u540d\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a\n*********************************************************************************************************\/\nchar* YmodemReceiverGetFileName(void)\n{\n  return s_arrFileName;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemReceiverGetFileSize\n* \u51fd\u6570\u529f\u80fd\uff1a \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a \u6587\u4ef6\u5927\u5c0f\uff0c\u5355\u4f4d\u662f\u5b57\u8282\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a\n*********************************************************************************************************\/\nunsigned int YmodemReceiverGetFileSize(void)\n{\n  return s_iFileSize;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemReceiverGetReadSize\n* \u51fd\u6570\u529f\u80fd\uff1a \u83b7\u53d6\u5df2\u7ecf\u63a5\u6536\u7684\u5b57\u8282\u6570\n* \u8f93\u5165\u53c2\u6570\uff1a void\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a \u5df2\u7ecf\u63a5\u6536\u7684\u5b57\u8282\u6570\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a\n*********************************************************************************************************\/\nunsigned int YmodemReceiverGetReadSize(void)\n{\n  return s_iReadByteCnt;\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemReceiverWrite\n* \u51fd\u6570\u529f\u80fd\uff1a \u53d1\u9001\u56de\u5e94\n* \u8f93\u5165\u53c2\u6570\uff1a buf\uff1a\u7f13\u51b2\u533a\u9996\u5730\u5740\u3002len\uff1a\u8bfb\u5199\u957f\u5ea6\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a \u6210\u529f\u8bfb\u5199\u7684\u6570\u636e\u91cf\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a\n*            1\u3001\u9700\u8981\u79fb\u690d\n*            2\u3001\u79bb\u5f00\u6b64\u51fd\u6570\u65f6\uff0c\u9ed8\u8ba4\u6570\u636e\u5df2\u7ecf\u53d1\u9001\u5b8c\u6bd5\n*********************************************************************************************************\/\nunsigned int YmodemReceiverWrite(unsigned char* buf, unsigned int len)\n{\n  unsigned int ReceiverWrite(unsigned char* buf, unsigned int len);\n  return ReceiverWrite(buf, len);\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemReceiverRead\n* \u51fd\u6570\u529f\u80fd\uff1a \u63a5\u6536\u6570\u636e\n* \u8f93\u5165\u53c2\u6570\uff1a buf\uff1a\u7f13\u51b2\u533a\u9996\u5730\u5740\u3002len\uff1a\u8bfb\u5199\u957f\u5ea6\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a \u6210\u529f\u8bfb\u5199\u7684\u6570\u636e\u91cf\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a\n*            1\u3001\u9700\u8981\u79fb\u690d\n*            2\u3001\u8fd9\u91cc\u63a5\u6536\u7684\u662f\u4e3b\u673a\u7684\u6570\u636e\u5305\u6570\u636e\n*********************************************************************************************************\/\nunsigned int YmodemReceiverRead(unsigned char* buf, unsigned int len)\n{\n  unsigned int ReceiverRead(unsigned char* buf, unsigned int len);\n  return ReceiverRead(buf, len);\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemReceiverInfo\n* \u51fd\u6570\u529f\u80fd\uff1a \u4e0a\u62a5\u4fe1\u606f\n* \u8f93\u5165\u53c2\u6570\uff1a info\uff1a\u4fe1\u606f\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \u9700\u8981\u79fb\u690d\n*********************************************************************************************************\/\nvoid YmodemReceiverInfo(unsigned int info)\n{\n  void ReceiverInfo(unsigned int info);\n  ReceiverInfo(info);\n}\n\n\/*********************************************************************************************************\n* \u51fd\u6570\u540d\u79f0\uff1a YmodemReceiverOutput\n* \u51fd\u6570\u529f\u80fd\uff1a \u6570\u636e\u8f93\u51fa\n* \u8f93\u5165\u53c2\u6570\uff1a info\uff1a\u4fe1\u606f\n* \u8f93\u51fa\u53c2\u6570\uff1a void\n* \u8fd4 \u56de \u503c\uff1a void\n* \u521b\u5efa\u65e5\u671f\uff1a 2023\u5e7411\u670816\u65e5\n* \u6ce8    \u610f\uff1a \u9700\u8981\u79fb\u690d\n*********************************************************************************************************\/\nvoid YmodemReceiverOutput(unsigned int offset, unsigned char* buf, unsigned int len)\n{\n  void ReceiverOutput(unsigned int offset, unsigned char* buf, unsigned int len);\n  ReceiverOutput(offset, buf, len);\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"%E5%9F%BA%E4%BA%8E%E4%B8%B2%E5%8F%A3%E4%BC%A0%E8%BE%93%E7%9A%84_Ymodem_%E5%8F%91%E9%80%81%E5%B0%8F%E5%B7%A5%E5%85%B7\"><\/span>\u57fa\u4e8e\u4e32\u53e3\u4f20\u8f93\u7684 Ymodem \u53d1\u9001\u5c0f\u5de5\u5177<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>\u57fa\u4e8e\u4e0a\u8ff0\u4ee3\u7801\uff0c\u5236\u4f5c\u7684 Ymodem \u53d1\u9001\u5c0f\u5de5\u5177\u5982\u4e0b\u6240\u793a\u3002\u8fd9\u4e2a\u5c0f\u5de5\u5177\u53ef\u4ee5\u7528\u4e8e\u901a\u8fc7\u4e32\u53e3\u5411\u5355\u7247\u673a\u53d1\u9001\u6587\u4ef6\uff0c\u4f8b\u5982 IAP \u5347\u7ea7\uff0c\u5b9e\u6d4b\u53ef\u4ee5\u7a33\u5b9a\u66f4\u65b0 350kB \u7684\u7a0b\u5e8f\u6587\u4ef6\u3002<\/p>\n\n\n\n<p>\u7b2c\u4e00\u6b21\u8fd0\u884c\u65f6\uff0c\u9700\u8981\u8f93\u5165\u4e32\u53e3\u53f7\u3001\u6ce2\u7279\u7387\u4ee5\u53ca\u6587\u4ef6\u540d\uff0c\u6ce8\u610f\u6587\u4ef6\u540d\u9700\u8981\u4e0e\u5c0f\u5de5\u5177\u5904\u4e8e\u540c\u4e00\u6587\u4ef6\u5939\u4e0b\uff0c\u5373\u540c\u4e00\u8def\u5f84\u3002\u914d\u7f6e\u4fe1\u606f\u5c06\u4f1a\u88ab\u4fdd\u5b58\u5230\u201cConfig.ini\u201d\u6587\u4ef6\u4e2d\u3002\u540e\u7eed\u9700\u8981\u4fee\u6539\u4e32\u53e3\u53f7\u3001\u6ce2\u7279\u7387\u6216\u6587\u4ef6\u540d\u65f6\uff0c\u9700\u8981\u4ee5\u6587\u672c\u6587\u4ef6\u5f62\u5f0f\u6253\u5f00\u201cConfig.ini\u201d\u6587\u4ef6\uff0c\u76f4\u63a5\u4fee\u6539\u914d\u7f6e\u3002<\/p>\n\n\n\n<p>\u5c0f\u5de5\u5177\u5982\u4e0b\u6240\u793a\u3002<\/p>\n\n\n\n<div class=\"wp-block-file\"><a id=\"wp-block-file--media-e93288ec-e0c2-4c6d-b385-56ea09a1e0fc\" href=\"http:\/\/www.huangrongzhen.ink\/wp-content\/uploads\/2024\/05\/YmodemSender-release-20240318.rar\">YmodemSender-release-20240318<\/a><a href=\"http:\/\/www.huangrongzhen.ink\/wp-content\/uploads\/2024\/05\/YmodemSender-release-20240318.rar\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-e93288ec-e0c2-4c6d-b385-56ea09a1e0fc\">\u4e0b\u8f7d<\/a><\/div>\n\n\n\n<p>\u6e90\u7801\u5982\u4e0b\u6240\u793a\u3002<\/p>\n\n\n\n<div class=\"wp-block-file\"><a id=\"wp-block-file--media-66f3c9c2-a435-45ea-b31a-aca3459de80a\" href=\"http:\/\/www.huangrongzhen.ink\/wp-content\/uploads\/2024\/05\/YmodemSender-source-20240523.rar\">YmodemSender-source-20240523<\/a><a href=\"http:\/\/www.huangrongzhen.ink\/wp-content\/uploads\/2024\/05\/YmodemSender-source-20240523.rar\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-66f3c9c2-a435-45ea-b31a-aca3459de80a\">\u4e0b\u8f7d<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u4f7f\u7528 C \u8bed\u8a00\u7f16\u5199\u7684 Ymodem \u9a71\u52a8\u3002<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,6],"tags":[],"_links":{"self":[{"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=\/wp\/v2\/posts\/2226"}],"collection":[{"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2226"}],"version-history":[{"count":2,"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=\/wp\/v2\/posts\/2226\/revisions"}],"predecessor-version":[{"id":2230,"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=\/wp\/v2\/posts\/2226\/revisions\/2230"}],"wp:attachment":[{"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2226"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2226"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2226"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}