UartUpdate.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. // UartUpdate.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2. //
  3. #define _CRT_SECURE_NO_WARNINGS
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <windows.h>
  8. static int transferOver = 0;
  9. HANDLE hComm;
  10. typedef enum {
  11. UART_FRAME_START,
  12. UART_FRAME_FILEINFO,
  13. UART_FRAME_FILEXFER,
  14. UART_FRAME_FINISH,
  15. } eUartFrameType;
  16. #define UUP_STATE_IDLE 0
  17. #define UUP_STATE_START 1
  18. #define UUP_STATE_END 2
  19. #define UUP_ACK_OK 1
  20. #define UUP_ACK_FAIL 0
  21. #define UUP_MAX_FILE_SIZE 0x1000000
  22. #define UUP_BUF_SIZE (BYTESPERPAGE * PAGESPERSECTORS)
  23. #define UUP_PACKET_SIZE 128
  24. #define UUP_MAX_FRAME_LEN (UUP_PACKET_SIZE + 16)
  25. #define UUP_RX_FRAME_NUM 16
  26. #pragma pack(16)
  27. static unsigned char uup_rx_buf[UUP_RX_FRAME_NUM][UUP_MAX_FRAME_LEN];
  28. static unsigned char *uup_rx_ptr;
  29. static int uup_rx_rev_len = 0;
  30. static int uup_rx_head = 0;
  31. static int uup_rx_tail = 0;
  32. static int uup_rx_state = 0;
  33. static int uup_rx_data_len = 0;
  34. static int uup_status = UUP_STATE_IDLE;
  35. static int uup_file_type = 0;
  36. static unsigned int uup_file_offset;
  37. static int uup_file_size = 0;
  38. static int uup_packet_num = 0;
  39. static int uup_rev_packet = 0;
  40. static int uup_rev_len = 0;
  41. static DWORD WINAPI uartRevThread(LPVOID lpParam)
  42. {
  43. unsigned char buf[UUP_MAX_FRAME_LEN];
  44. DWORD len;
  45. int i;
  46. while (!transferOver) {
  47. ReadFile(hComm, buf, UUP_MAX_FRAME_LEN, &len, NULL);
  48. for (i = 0; i < (int)len; i++) {
  49. switch (uup_rx_state) {
  50. case 0:
  51. if (buf[i] == 0x55) {
  52. uup_rx_state++;
  53. uup_rx_rev_len = 0;
  54. uup_rx_ptr = &uup_rx_buf[uup_rx_head][0];
  55. }
  56. break;
  57. case 1:
  58. if (buf[i] == 0x80)
  59. uup_rx_state++;
  60. else
  61. uup_rx_state = 0;
  62. *uup_rx_ptr++ = buf[i];
  63. break;
  64. case 2:
  65. if (buf[i] == 0xc5)
  66. uup_rx_state++;
  67. else
  68. uup_rx_state = 0;
  69. *uup_rx_ptr++ = buf[i];
  70. break;
  71. case 3:
  72. uup_rx_data_len = buf[i];
  73. uup_rx_state++;
  74. *uup_rx_ptr++ = buf[i];
  75. break;
  76. case 4:
  77. *uup_rx_ptr++ = buf[i];
  78. if (++uup_rx_rev_len == uup_rx_data_len)
  79. uup_rx_state++;
  80. break;
  81. case 5:
  82. *uup_rx_ptr++ = buf[i];
  83. uup_rx_head = (uup_rx_head + 1) % UUP_RX_FRAME_NUM;
  84. uup_rx_state = 0;
  85. break;
  86. }
  87. }
  88. }
  89. return 0;
  90. }
  91. static int uart_wait_ack(int ack_type, unsigned int timeout_ms)
  92. {
  93. unsigned char *buf;
  94. int len;
  95. unsigned char checksum = 0;
  96. int i;
  97. DWORD tm = GetTickCount();
  98. while (GetTickCount() - tm < timeout_ms) {
  99. if (uup_rx_tail == uup_rx_head) {
  100. Sleep(1);
  101. continue;
  102. }
  103. buf = &uup_rx_buf[uup_rx_tail][0];
  104. uup_rx_tail = (uup_rx_tail + 1) % UUP_RX_FRAME_NUM;
  105. len = buf[2];
  106. if (len != 2) {
  107. printf("rev wrong ack len.\n");
  108. continue;
  109. }
  110. for (i = 0; i < len + 3; i++)
  111. checksum ^= buf[i];
  112. if (checksum == buf[len + 3]) {
  113. if (buf[3] != ack_type) {
  114. printf("rev wrong ack type.\n");
  115. continue;
  116. }
  117. return buf[4];
  118. }
  119. else {
  120. printf("rev ack checksum err.\n");
  121. continue;
  122. }
  123. }
  124. return 0;
  125. }
  126. static void uart_send_frame(unsigned char *data, int len)
  127. {
  128. unsigned char buf[UUP_MAX_FRAME_LEN];
  129. DWORD wLen;
  130. buf[0] = 0x55;
  131. buf[1] = 0x81;
  132. buf[2] = 0xc6;
  133. buf[3] = len;
  134. memcpy(buf + 4, data, len);
  135. buf[len + 4] = 0;
  136. for (int i = 1; i < len + 4; i++)
  137. buf[len + 4] ^= buf[i];
  138. WriteFile(hComm, buf, len + 5, &wLen, NULL);
  139. }
  140. static void uart_send_start(void)
  141. {
  142. unsigned char buf = UART_FRAME_START;
  143. uart_send_frame(&buf, 1);
  144. }
  145. static void uart_send_fileinfo(int filetype, int filesize)
  146. {
  147. unsigned char buf[5];
  148. int packetnum = (filesize + UUP_PACKET_SIZE - 1) / UUP_PACKET_SIZE;
  149. buf[0] = UART_FRAME_FILEINFO;
  150. buf[1] = filetype;
  151. buf[2] = packetnum >> 16;
  152. buf[3] = packetnum >> 8;
  153. buf[4] = packetnum & 0xff;
  154. uart_send_frame(buf, 5);
  155. }
  156. static void uart_send_filedata(int packet_index, unsigned char *data, int len)
  157. {
  158. unsigned char buf[UUP_MAX_FRAME_LEN];
  159. buf[0] = UART_FRAME_FILEXFER;
  160. buf[1] = packet_index & 0xff;
  161. memcpy(buf + 2, data, len);
  162. uart_send_frame(buf, len + 2);
  163. }
  164. static void uart_send_end(int ret)
  165. {
  166. unsigned char buf[2];
  167. buf[0] = UART_FRAME_FINISH;
  168. buf[1] = ret;
  169. uart_send_frame(buf, 2);
  170. }
  171. int main(int argc, char *argv[])
  172. {
  173. char *endptr;
  174. wchar_t comName[16];
  175. int comPort;
  176. int i;
  177. if (argc != 5) {
  178. printf("Input Error! Usage: %s uartPort baud fileType fileName.\n", argv[0]);
  179. system("pause");
  180. return -1;
  181. }
  182. comPort = strtoul(argv[1], &endptr, 10);
  183. if (comPort < 10)
  184. swprintf_s(comName, 16, L"COM%d", comPort);
  185. else
  186. swprintf_s(comName, 16, L"\\\\.\\COM%d", comPort);
  187. hComm = CreateFile(comName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  188. if (hComm == INVALID_HANDLE_VALUE) {
  189. wprintf(L"open %s fail.\n", comName);
  190. system("pause");
  191. return -1;
  192. }
  193. else {
  194. wprintf(L"open %s ok.\n", comName);
  195. }
  196. //需要设置超时,否则,WriteFile() 或ReadFile()会一直阻塞任务。
  197. COMMTIMEOUTS comtimeout;
  198. comtimeout.ReadIntervalTimeout = 0xffffffff;
  199. comtimeout.ReadTotalTimeoutMultiplier = 0x0;
  200. comtimeout.ReadTotalTimeoutConstant = 0x0;
  201. comtimeout.WriteTotalTimeoutMultiplier = 4;//0x64; //100 // 表示平均写一个字节的时间上限
  202. comtimeout.WriteTotalTimeoutConstant = 32;//0x3e8; //992 //单位毫秒 //表示写数据总超时常量
  203. if (!SetCommTimeouts(hComm, &comtimeout)) {
  204. printf("SetCommTimeouts fail\n");
  205. }
  206. //设置输入输出缓冲区大小
  207. if (!SetupComm(hComm, 4096, 4096))
  208. {
  209. printf("SetupComm fail\n");
  210. }
  211. DCB dcb;
  212. GetCommState(hComm, &dcb);
  213. dcb.BaudRate = strtoul(argv[2], &endptr, 10);
  214. dcb.ByteSize = 8;
  215. dcb.StopBits = ONESTOPBIT;
  216. dcb.Parity = NOPARITY;
  217. dcb.fOutxCtsFlow = 0;
  218. dcb.fRtsControl = RTS_CONTROL_DISABLE;
  219. dcb.fDtrControl = DTR_CONTROL_DISABLE;
  220. dcb.EofChar = (char)0xa0;
  221. //dcb.fBinary = true; // binary mode, no EOF check 指定是否允许二进制模式WIN95中须为TRUE
  222. SetCommState(hComm, &dcb);
  223. HANDLE hRevThread = CreateThread(NULL, 0, uartRevThread, 0, 0,NULL);
  224. int fileType;
  225. FILE *fp;
  226. int len;
  227. unsigned char buf[UUP_PACKET_SIZE];
  228. int filesize;
  229. int packetnum = 0;
  230. int ret = -1;
  231. fileType = strtoul(argv[3], &endptr, 10);
  232. fp = fopen(argv[4], "rb");
  233. if (!fp) {
  234. printf("open %s fail.\n", argv[4]);
  235. goto end;
  236. }
  237. fseek(fp, 0, SEEK_END);
  238. filesize = ftell(fp);
  239. fseek(fp, 0, SEEK_SET);
  240. int retry = 10000 / 100;
  241. for (i = 0; i < retry; i++) {
  242. uart_send_start();
  243. if (uart_wait_ack(UART_FRAME_START, 100)) {
  244. printf("wait start ack ok.\n");
  245. break;
  246. } else {
  247. printf("wait start ack fail.\n");
  248. }
  249. }
  250. if (i == retry)
  251. goto end;
  252. retry = 3;
  253. for (i = 0; i < retry; i++) {
  254. uart_send_fileinfo(fileType, filesize);
  255. if (uart_wait_ack(UART_FRAME_FILEINFO, 1000)) {
  256. printf("wait fileinfo ack ok.\n");
  257. break;
  258. } else {
  259. printf("wait fileinfo ack fail.\n");
  260. }
  261. }
  262. if (i == retry)
  263. goto end;
  264. while (1) {
  265. len = fread(buf, 1, UUP_PACKET_SIZE, fp);
  266. if (len <= 0)
  267. break;
  268. for (i = 0; i < retry; i++) {
  269. uart_send_filedata(packetnum, buf, len);
  270. if (uart_wait_ack(UART_FRAME_FILEXFER, 1000)) {
  271. printf("wait filedata ack ok.\n");
  272. break;
  273. } else {
  274. printf("wait filedata ack fail.\n");
  275. }
  276. }
  277. if (i == retry)
  278. goto end;
  279. packetnum++;
  280. }
  281. ret = 0;
  282. end:
  283. for (i = 0; i < retry; i++) {
  284. uart_send_end(ret == 0);
  285. if (uart_wait_ack(UART_FRAME_FINISH, 10000)) {
  286. printf("wait finish ack ok.\n");
  287. break;
  288. }
  289. else {
  290. printf("wait finish ack fail.\n");
  291. }
  292. }
  293. transferOver = 1;
  294. WaitForSingleObject(hRevThread, INFINITE);
  295. PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
  296. CloseHandle(hComm);
  297. system("pause");
  298. return 0;
  299. }