blob: 2c0657ee4e958fd5e7b42ba8ab4624b2036c08a5 [file] [log] [blame]
liubin281ac462023-07-19 14:22:54 +08001#include <sys/stat.h>
2#include <sys/time.h>
3#include <errno.h>
4#include <time.h>
5#include <stdio.h>
6#include <fcntl.h>
7#include <string.h>
8#include <stdlib.h>
9#include <unistd.h>
10#include <sys/times.h>
11#include <sys/types.h>
12#include <termios.h>
13#include <unistd.h>
14#include <sys/ioctl.h>
15#include <sys/wait.h>
16#include <ctype.h>
17#include <sched.h>
18#include <limits.h>
19#include <linux/serial.h>
20
21#define RTM_FILE_NAME "rtm.bin"
22
23#define PARA_ERR -1
24#define FILE_CHECK_ERR -2
25#define ENTER_UPDATE_MODE_ERR -3
26#define UPDATE_ERR -4
27#define UART_DEV_ERR -5
28
29#define XMODEM_SOH 0x01
30#define XMODEM_STX 0x02
31#define XMODEM_EOT 0x04
32#define XMODEM_ACK 0x06
33#define XMODEM_NAK 0x15
34#define XMODEM_CAN 0x18
35#define XMODEM_CRC_CHR 'C'
36#define XMODEM_CRC_SIZE 2 /* Crc_High Byte + Crc_Low Byte */
37#define XMODEM_FRAME_ID_SIZE 2 /* Frame_Id + 255-Frame_Id */
38#define XMODEM_DATA_SIZE_SOH 128 /* for Xmodem protocol */
39#define XMODEM_DATA_SIZE_STX 1024 /* for 1K xmodem protocol */
40#define USE_1K_XMODEM 1 /* 1 for use 1k_xmodem 0 for xmodem */
41#define TIMEOUT_USEC 0
42#define TIMEOUT_SEC 10
43
44#if (USE_1K_XMODEM)
45#define XMODEM_DATA_SIZE XMODEM_DATA_SIZE_STX
46#define XMODEM_HEAD XMODEM_STX
47#else
48#define XMODEM_DATA_SIZE XMODEM_DATA_SIZE_SOH
49#define XMODEM_HEAD XMODEM_SOH
50#endif
51
52
53/******************************************************************************
54 * 时间处理相关的宏
55 *****************************************************************************/
56// 时间超时标志
57int timeout_sign = 1;
58// 获取当前时间
59#define GET_TIME() { gettimeofday(&time_m, NULL); \
60 time_m.tv_sec += TIMEOUT_SEC;\
61}
62// 设置从循环中退出的时间
63#define SET_TIME_OUT(x) { gettimeofday(&time_m, NULL); \
64 time_m.tv_sec += x;\
65}
66// 检测时间是否超时,超时则退出当前函数
67#define CHK_TIME() { gettimeofday(&time_n, NULL); \
68 if(time_n.tv_sec > time_m.tv_sec) { \
69 printf("\ntimeout!!!\n\n");\
70 close(fd); \
71 return ret; \
72 } \
73}
74// 检测时间是否超时,超时则退出当前循环
75#define CHK_TIME_BREAK() { gettimeofday(&time_n, NULL); \
76 if(time_n.tv_sec > time_m.tv_sec) { \
77 timeout_sign = 1; \
78 printf("\ntimeout!!!\n\n");\
79 break; \
80 } \
81}
82// 检测延时是否到达,到达则退出当前循环
83#define DELAY_TIME_BREAK() { gettimeofday(&time_n, NULL); \
84 if(time_n.tv_sec > time_m.tv_sec) { \
85 timeout_sign = 1; \
86 break; \
87 } \
88}
89
90// 检测时间是否超时,超时则退出当前函数
91#define CHK_TIME1() { gettimeofday(&time_n, NULL); \
92 if(time_n.tv_sec > time_m.tv_sec) { \
93 printf("\ntimeout!!!\n\n");\
94 if(datafile != NULL) \
95 fclose(datafile); \
96 return ret; \
97 } \
98}
99
100
101/******************************************************************************
102 * APData 相关定义、声明
103 *****************************************************************************/
104// APData 数据头部定义
105typedef struct {
106 unsigned int ih_magic; // Image Header Magic Number
107 unsigned int ih_dcrc; // Image Data CRC checksum
108 unsigned int ih_time; // Image Creation Timestamp
109 unsigned int ih_size; // Image Data Size
110 unsigned int ih_compress; // Image Header compress or not:0, not compress
111 unsigned int pkg_flash_addr; // flash memory offset for package
112 unsigned int pkg_run_addr; // Run time address for this package
113 unsigned int ih_hcrc; // Image Header CRC checksum
114} uc_image_header_t;
115
116// APData 数据头部长度
117#define HEADERLEN 32
118// APData 接收状态类型
119typedef enum ReceStat{
120 WAIT_FD = 1,
121 WAIT_FC,
122 WAIT_FB,
123 WAIT_FA,
124 RECE_HEADER,
125 RECE_DATA,
126} RecvStat_t;
127// APData 接收状态变量
128static RecvStat_t recvStat = WAIT_FD;
129// APData 接收状态变量
130static int isStartReceive = 0;
131// APData 开始接收
132void af_start_receive();
133// APData 停止接收,在数据接收完成或出错时调用
134void af_stop_receive();
135// 获取isStartReceive 变量值
136int af_is_start_receive();
137// APData 数据接收入口
138int af_add_char(char *file, unsigned char c);
139// 校验 APData 数据头
140int af_check_header(unsigned char *pbuf, unsigned int len);
141// 校验 APData 数据区
142int af_check_data(unsigned int * pbuf, unsigned int len);
143// 获取 APData 数据长度
144int af_get_data_len();
145// APData 数据接收缓存
146unsigned int recv_buf[1024 * 2];
147unsigned char *pbuf;
148int data_len;
149// 校验文件
150int check_file(char *fname);
151
152/******************************************************************************
153 * 与接收机串口通讯相关定义、声明
154 *****************************************************************************/
155// select功能使用变量
156static int use_select = 1;
157// 初始化串口资源
158int initial_serialPort(char * serial_device);
159// 设置串口波特率
160static int set_baudrate(int fd, int baudrate);
161// 检测串口数据
162static int select_read(int fd, int timeout);
163// 读取串口数据
164static ssize_t deal_read(int fd, void *buf, size_t count);
165// 向接收机发送串口数据
166static void gps_dev_send(int fd, char *msg);
167// 通过xmodem协议向接收机发送串口数据
168int xmodem_send(int fd, char *fname);
169
170/******************************************************************************
171 * apflash 功能函数
172 *****************************************************************************/
173// 检测接收机发送的'YC'信号,如果收到,则标志着接收机进入boot模式,并可以通过xmodem发送数据
174int check_YC(char newchar);
175// 获取 APData 数据, 应该在接收机定位且星历数据接收完整时获取
176int getAPData(int fd, char *file);
177// 向接收机发送 APData 数据,有效的APData数据可以让CI模块迅速定位
178int sendAPData(int fd, char *ap);
179// 校验 APData 数据文件
180int checkAPData(char *apFile);
181// 为接收机加载BootLoader,该流程执行时,需要根据终端提示,给接收机下电和上电,确保接收机进入boot模式
182int downloadBL(int fd, char *bl);
183// 为接收机加载Firmware,该流程必须在加载BootLoader之后进行
184int downloadFW(int fd, char *fw);
185
186void printGetapUsage(char *app)
187{
188 printf("\n%s getap -d receiverPort [-b baudrate] [-h] -a apfile \n", app);
189 printf("\tfunction: read APData from receiver\n");
190 printf("\tparas:\n");
191 printf("\t\treceiverPort: Port that connected to receiver\n");
192 printf("\t\tbaudrate: baudrate of receiverPort\n");
193}
194
195void printSendapUsage(char *app)
196{
197 printf("\n%s sendap -d receiverPort [-b baudrate] [-h] -a apfile\n", app);
198 printf("\tfunction: send APData to receiver\n");
199 printf("\tparas:\n");
200 printf("\t\treceiverPort: Port that connected to receiver\n");
201 printf("\t\tbaudrate: baudrate of receiverPort\n");
202}
203
204void printCheckapUsage(char *app)
205{
206 printf("\n%s checkap -a apfile [-h]\n", app);
207 printf("\tfunction: check APData\n");
208 printf("\tparas:\n");
209 printf("\t\tapfile: APData file\n");
210}
211
212void printDownloadblUsage(char *app)
213{
214 printf("\n%s downbl -d receiverPort [-b baudrate] -l bootloader [-h]\n", app);
215 printf("\tfunction: download bootloader to receiver\n");
216 printf("\tparas:\n");
217 printf("\t\treceiverPort: Port that connected to receiver\n");
218 printf("\t\tbaudrate: baudrate of receiverPort\n");
219 printf("\t\tbootloader: bootloader file\n");
220}
221
222void printDownloadfwUsage(char *app)
223{
224 printf("\n%s downfw -d receiverPort [-b baudrate] -f firmware [-h]\n", app);
225 printf("\tfunction: download firmware to receiver\n");
226 printf("\tparas:\n");
227 printf("\t\treceiverPort: Port that connected to receiver\n");
228 printf("\t\tbaudrate: baudrate of receiverPort\n");
229 printf("\t\tfirmware: firmware file\n");
230}
231
232void printUsage(char *app)
233{
234 printGetapUsage(app);
235 printSendapUsage(app);
236 printCheckapUsage(app);
237 printDownloadblUsage(app);
238 printDownloadfwUsage(app);
239}
240
241#define GPS_DEV "/sys/devices/soc.0/d4000000.apb/mbtk-dev-op/gps_power"
242
243static int mopen_open_gps(int state)
244{
245 int fd, ret;
246 char s[4] = "on";
247 fd = open(GPS_DEV, O_RDWR | O_TRUNC, 0644);
248 if(fd < 0) {
249 printf("[%s] file [%s] open error\n", __FUNCTION__, GPS_DEV);
250 return -1;
251 }
252 if(0 == state)
253 {
254 memcpy(s, "off", 3);
255 }
256 ret = write(fd, s, 4);
257 if (ret < 0) {
258 printf("%s: error writing to file!\n", __FUNCTION__);
259 close(fd);
260 return -2;
261 }
262
263 close(fd);
264 return 0;
265}
266
267int main(int argc, char *argv[])
268{
269 int c;
270 int ret = 0;
271 int fd = -1;
272 int paraMask = 0;
273 int baud = 115200;
274 char devPort[200] = {0};
275 char fw[200] = {0};
276 char bl[200] = {0};
277 char ap[200] = {0};
278 int func = 0; // 1:getap, 2:sendap, 3:downbl, 4:downfw, 5:checkap
279
280 // Verify arguments
281 if (argc < 2) {
282 printf("Usage:\n");
283 printUsage(argv[0]);
284 exit(1);
285 }
286
287 if(strcmp(argv[1], "getap") == 0) {
288 func = 1;
289 paraMask = 1;
290 } else if (strcmp(argv[1], "sendap") == 0) {
291 func = 2;
292 paraMask = 1;
293 } else if (strcmp(argv[1], "downbl") == 0) {
294 func = 3;
295 paraMask = 9;
296 } else if (strcmp(argv[1], "downfw") == 0) {
297 func = 4;
298 paraMask = 5;
299 } else if (strcmp(argv[1], "checkap") == 0) {
300 func = 5;
301 paraMask = 16;
302 } else {
303 printf("Usage:\n");
304 printUsage(argv[0]);
305 exit(1);
306 }
307
308 for(;;) {
309 opterr = 0;
310 c = getopt(argc, argv, "d:b:f:l:a:h");
311 if(c < 0)
312 break;
313 switch(c) {
314 case 'd':
315 snprintf(devPort, 200, "%s", optarg);
316 printf("receiver port: %s\n", devPort);
317 paraMask &= ~1;
318 break;
319 case 'b':
320 baud = atoi(optarg);
321 printf("baud rate: %d\n", baud);
322 break;
323 case 'f':
324 snprintf(fw, 200, "%s", optarg);
325 printf("firmware: %s\n", fw);
326 paraMask &= ~4;
327 break;
328 case 'l':
329 snprintf(bl, 200, "%s", optarg);
330 printf("bootloader: %s\n", bl);
331 paraMask &= ~8;
332 break;
333 case 'a':
334 snprintf(ap, 200, "%s", optarg);
335 printf("apdata file: %s\n", ap);
336 paraMask &= ~16;
337 break;
338 case 'h':
339 default:
340 printf("Usage:\n");
341 if (func == 1)
342 printGetapUsage(argv[0]);
343 else if (func == 2)
344 printSendapUsage(argv[0]);
345 else if (func == 3)
346 printDownloadblUsage(argv[0]);
347 else if (func == 4)
348 printDownloadfwUsage(argv[0]);
349 else if (func == 5)
350 printCheckapUsage(argv[0]);
351 else
352 printUsage(argv[0]);
353 exit(1);
354 }
355 }
356 if (paraMask) {
357 if (func == 1)
358 printGetapUsage(argv[0]);
359 else if (func == 2)
360 printSendapUsage(argv[0]);
361 else if (func == 3)
362 printDownloadblUsage(argv[0]);
363 else if (func == 4)
364 printDownloadfwUsage(argv[0]);
365 else if (func == 5)
366 printCheckapUsage(argv[0]);
367 else
368 printUsage(argv[0]);
369 exit(1);
370 }
371
372 // Open serial port
373 if (func != 5) {
374 if ((fd = initial_serialPort(devPort)) == -1)
375 {
376 printf("Can't open COM\n");
377 return UART_DEV_ERR;
378 }
379 if (baud == 115200) {
380 set_baudrate(fd, B115200);
381 } else if (baud == 921600) {
382 set_baudrate(fd, B921600);
383 } else if (baud == 1843200) {
384 set_baudrate(fd, B1500000);
385 } else {
386 printf("baudrate %d not supported\n", baud);
387 close(fd);
388 exit(1);
389 }
390 }
391
392 // execute function
393 switch(func) {
394 case 1:
395 ret = getAPData(fd, ap);
396 break;
397 case 2:
398 ret = sendAPData(fd, ap);
399 break;
400 case 3:
401 ret = downloadBL(fd, bl);
402 break;
403 case 4:
404 ret = downloadFW(fd, fw);
405 break;
406 case 5:
407 ret = checkAPData(ap);
408 break;
409 default:break;
410 }
411 close(fd);
412 return ret;
413
414}
415
416int getAPData(int fd, char *file)
417{
418 int rByte = 0;
419 char rbuf[4096];
420 int ret = 0, i;
421 struct timeval time_m, time_n;
422
423 if (NULL == file) {
424 printf("Please input file!! \n");
425 return 1;
426 }
427 if (!fd)
428 return 1;
429 printf("Get apdata\n");
430 gps_dev_send(fd, "$ReqRecvFlash\r\n");
431 af_start_receive();
432 GET_TIME();
433 while(1) {
434 CHK_TIME();
435 if(select_read(fd,1) > 0)
436 usleep(50000);
437 else
438 continue;
439
440 rByte = deal_read(fd,&rbuf,sizeof(rbuf));
441 if(rByte >= 1){
442 if(af_is_start_receive()) {
443 for(i = 0; i < rByte; i++)
444 af_add_char(file, rbuf[i]);
445 } else {
446 break;
447 }
448 }
449 }
450
451 checkAPData(file);
452 return 0;
453}
454
455int sendAPData(int fd, char *apFile)
456{
457 int rByte = 0;
458 char rbuf[4096];
459 int ret = 0;
460 struct timeval time_m, time_n;
461
462 if(access(apFile, F_OK) != -1)
463 {
464 // Download APData only if the file exits
465 printf("Download APData...\n");
466 if(xmodem_send(fd, apFile))
467 {
468 printf("xmodem error!\n");
469 close(fd);
470 return ENTER_UPDATE_MODE_ERR;
471 }
472 // Waiting for 'C'
473 GET_TIME();
474 while(1)
475 {
476 CHK_TIME();
477 if(select_read(fd,1) > 0)
478 usleep(500000);
479 else
480 continue;
481 rByte = deal_read(fd,&rbuf,sizeof(rbuf)-1);
482 rbuf[rByte] = 0;
483 if(rByte > 0)
484 {
485 if(rbuf[rByte - 1] == 'C')
486 break;
487 }
488 }
489 printf("download APData success\n");
490 }
491 else
492 {
493 printf("file err!\n");
494 return 1;
495 }
496
497 return 0;
498}
499
500int checkAPData(char *apFile)
501{
502 printf("Checking %s\n", apFile);
503 if(check_file(apFile))
504 {
505 printf("file error!\n");
506 return FILE_CHECK_ERR;
507
508 }
509 else
510 {
511 printf("pass\r\n");
512 }
513 return 0;
514}
515
516int downloadFW(int fd, char *fw)
517{
518 int ret;
519 struct timeval time_m, time_n;
520 char rbuf[512];
521
522 if(NULL == fw) {
523 printf("Error: Can't find firmware.\n");
524 return -1;
525 }
526 printf("Download firmware...\n");
527 if(xmodem_send(fd, fw) < 0) {
528 printf("xmodem error! send firmware failed!\n");
529 close(fd);
530 return UPDATE_ERR;
531 }
532
533 printf("Download firmware success\n");
534 return 0;
535}
536
537int downloadBL(int fd, char *bl)
538{
539 int rByte = 0;
540 char rbuf[4096];
541 char name[128];
542 int ret = 0;
543 struct timeval time_m, time_n;
544
545 if(NULL == bl) {
546 printf("Error: Can't find bootloader.\n");
547 return -1;
548 }
549 printf("------Please Powerdown the receiver!\n");
550 mopen_open_gps(0);
551 SET_TIME_OUT(3);
552 while(1) {
553 DELAY_TIME_BREAK(); //
554 if(select_read(fd,1) > 0)
555 usleep(50000);
556 else
557 continue;
558
559 rByte = deal_read(fd,&rbuf,sizeof(rbuf));
560 }
561 int start = 0,finish = 0;
562
563 memset(name, 0, sizeof(name));
564 sprintf(name,"M!T");
565 printf("waiting for YC, timeout is %d s\n", TIMEOUT_SEC);
566 printf("-------Please Powerup the receiver!\n");
567 mopen_open_gps(1);
568 // Waiting for 'YC'
569 GET_TIME();
570 while(1) {
571 int finish = 0, i;
572 CHK_TIME_BREAK(); //
573 rByte = write( fd, name, strlen(name));
574 rByte = select_read(fd,1);
575 if(rByte <= 0)
576 continue;
577 rByte = deal_read(fd, rbuf, sizeof(rbuf) - 1);
578 rbuf[rByte] = 0;
579 for (i = 0 ; i < rByte; i++)
580 {
581 if (check_YC(rbuf[i])) {
582 printf("Receive 'YC'\n");
583 finish = 1;
584 break;
585 }
586 }
587 if (finish)
588 break;
589 }
590 //wait 'YC' timeout deal
591 if (timeout_sign == 1)
592 {
593 //wait NAK
594 GET_TIME();
595 while(1)
596 {
597 CHK_TIME();
598 if(select_read(fd,1) <= 0)
599 continue;
600
601 rByte = deal_read(fd, rbuf,sizeof(rbuf));
602 if (rbuf[rByte-1] == 'C')
603 {
604 printf("###read xmodem start character 'C'.\n");
605 break;
606 }
607 }
608 }
609 use_select = 1;
610 printf("download bootloader...\n");
611
612 // Transfer bootloader via xmodem protocal
613 // if(xmodem_send(fd, "./bootloader.bin")) {
614 if(xmodem_send(fd, bl)) {
615 printf("xmodem error!\n");
616 close(fd);
617 return ENTER_UPDATE_MODE_ERR;
618 }
619 printf("download bootloader success\n");
620 return 0;
621}
622
623int check_YC(char newchar)
624{
625 int static state = 0;
626 int ret = 0;
627 switch (state) {
628 case 0:
629 if (newchar == 'Y')
630 state = 1;
631 break;
632 case 1:
633 if (newchar == 'C') {
634 state = 1;
635 ret = 1;
636 }
637 break;
638 default:
639 state = 0;
640 }
641 return ret;
642}
643
644const unsigned short CRC16_Table[256] = {
645 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
646 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
647 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
648 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
649 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
650 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
651 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
652 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
653 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
654 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
655 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
656 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
657 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
658 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
659 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
660 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
661 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
662 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
663 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
664 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
665 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
666 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
667 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
668 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
669 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
670 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
671 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
672 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
673 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
674 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
675 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
676 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
677};
678
679unsigned short crc16_ccitt(const unsigned char *buf, int len)
680{
681 register int counter;
682 register unsigned short crc = 0;
683 for (counter = 0; counter < len; counter++)
684 crc = (crc << 8) ^ CRC16_Table[((crc >> 8) ^ *(char *)buf++) & 0x00FF];
685 return crc;
686}
687
688
689unsigned int checksum32(unsigned int * pbuf, unsigned int len)
690{
691 unsigned int i, sumValue = 0;
692 len >>=2;
693
694 for(i=0;i<len;i++)
695 {
696 sumValue += *pbuf++;
697 }
698 return sumValue;
699}
700
701void af_start_receive()
702{
703 recvStat = WAIT_FD;
704 isStartReceive = 1;
705 return;
706}
707
708void af_stop_receive()
709{
710 int i;
711 printf("%s:%d\r\n", __FUNCTION__, __LINE__);
712 printf("%s:%d recvStat = %d\r\n", __FUNCTION__, __LINE__, recvStat);
713 pbuf = (unsigned char *)recv_buf;
714 for(i = 0; i < 4636; i++){
715 if(i % 32 == 0)printf("\r\n");
716 printf("%02X ", pbuf[i]);
717 }
718 printf("\r\n");
719 isStartReceive = 0;
720 return;
721}
722
723int af_is_start_receive()
724{
725 return isStartReceive;
726}
727
728int af_check_header(unsigned char *pbuf, unsigned int len)
729{
730 unsigned int crc = crc16_ccitt(pbuf, len-4);
731
732 if(crc == *(unsigned int *)(pbuf + len - 4))
733 return 1;
734 else
735 return 0;
736}
737
738int af_check_data(unsigned int * pbuf, unsigned int len)
739{
740 unsigned int cs = checksum32(pbuf + 8, len);
741 if(cs == pbuf[1])
742 return 1;
743 else
744 return 0;
745}
746
747int af_get_data_len()
748{
749 int len = *(int *)(recv_buf+3);
750 return len;
751}
752
753int af_add_char(char *file, unsigned char c)
754{
755 int ret = 0;
756 switch(recvStat){
757 case WAIT_FD:
758 if(c == 0xfd){
759 pbuf = (unsigned char *)recv_buf;
760 pbuf[0] = c;
761 recvStat = WAIT_FC;
762 printf("------------received 0xfd\r\n");
763 }
764 break;
765 case WAIT_FC:
766 if(c == 0xfc){
767 pbuf[1] = c;
768 recvStat = WAIT_FB;
769 printf("------------received 0xfc\r\n");
770 }else{
771 af_stop_receive();
772 }
773 break;
774 case WAIT_FB:
775 if(c == 0xfb){
776 pbuf[2] = c;
777 recvStat = WAIT_FA;
778 printf("------------received 0xfb\r\n");
779 }else{
780 af_stop_receive();
781 }
782 break;
783 case WAIT_FA:
784 if(c == 0xfa){
785 pbuf[3] = c;
786 recvStat = RECE_HEADER;
787 pbuf += 4;
788 printf("------------received 0xfa\r\n");
789 }else{
790 af_stop_receive();
791 }
792 break;
793 case RECE_HEADER:
794 *pbuf = c;
795 pbuf++;
796 if((pbuf - (unsigned char *)recv_buf) == HEADERLEN){
797 if(af_check_header((unsigned char *)recv_buf, HEADERLEN)){
798 recvStat = RECE_DATA;
799 data_len = af_get_data_len();
800 }else{
801 af_stop_receive();
802 }
803 }
804 break;
805 case RECE_DATA:
806 *pbuf = c;
807 pbuf++;
808 if((pbuf - (unsigned char *)recv_buf) == data_len + HEADERLEN){
809 if(af_check_data(recv_buf, recv_buf[3])){
810 int fd = open(file, O_WRONLY|O_CREAT, S_IRWXU);
811 write(fd, recv_buf, pbuf - (unsigned char *)recv_buf);
812 printf("%s:%d rtm len = %ld\r\n", __FUNCTION__, __LINE__, pbuf-(unsigned char *)recv_buf);
813 close(fd);
814 printf("receive rtm\n");
815 }else{
816 printf("af_check_data false!");
817 }
818 af_stop_receive();
819 }
820 ret = 1;
821 break;
822 default:
823 printf("%s:recvStat = %d\r\n", __FUNCTION__, recvStat);
824 break;
825 }
826 return ret;
827}
828
829
830
831ssize_t deal_read(int fd, void *buf, size_t count)
832{
833 int ret = 0;
834
835 while (1)
836 {
837 ret = read(fd, buf, count);
838 if (ret == 0)
839 {
840 printf("read serial return 0, please check serial device.\n");
841 exit(UART_DEV_ERR);
842 }
843 if(ret < 0)
844 {
845 if ((errno == EAGAIN) || (errno == EINTR))
846 {
847 printf("read serial return -1, errno = %d, retry.\n", errno);
848 continue;
849 }
850 else
851 {
852 printf("read serial return -1, errno = %d, please check serial device.\n", errno);
853 exit(UART_DEV_ERR);
854 }
855 }
856 return ret;
857 }
858}
859
860unsigned short get_crc16 ( char *ptr, unsigned short count )
861{
862 unsigned short crc, i;
863
864 crc = 0;
865 while(count--)
866 {
867 crc = crc ^ (int) *ptr++ << 8;
868
869 for(i = 0; i < 8; i++)
870 {
871 if(crc & 0x8000)
872 crc = crc << 1 ^ 0x1021;
873 else
874 crc = crc << 1;
875 }
876 }
877
878 return (crc & 0xFFFF);
879}
880
881void dump_u(void *buf, int len)
882{
883 unsigned char *p = (unsigned char *)buf;
884 int i;
885
886 for(i = 0; i < len; i++) {
887 if(i % 16 == 0) printf("%04x:", i);
888 if(i % 16 == 8) printf(" -");
889 printf(" %02x", p[i]);
890 if(i % 16 == 15) printf("\n");
891 }
892 if(i % 16) printf("\n");
893}
894
895unsigned int get_file_size(const char * name)
896{
897 struct stat statbuff;
898 //unsigned int size, checksum;
899 if(stat(name, &statbuff) < 0)
900 return -1;
901 else
902 return statbuff.st_size;
903}
904
905
906int check_file(char * fname)
907{
908 FILE *fd;
909 uc_image_header_t header;
910 unsigned int buf[1024];
911 unsigned int fsize, checksum, i;
912 unsigned int len;
913 unsigned short crc;
914 size_t rByte;
915
916 if((fd=fopen(fname,"rb"))==NULL)
917 {
918 printf("\n can't open (%s) or not exist!(errno=%d:%s) \n", fname, errno, strerror(errno));
919 return -1;
920 }
921
922 fsize = get_file_size(fname);
923
924 printf("file size [%d]\n",fsize);
925
926 if(fsize == 0)
927 return -1;
928
929 while(fsize > sizeof(header)) {
930 rByte = fread((char *)&header, sizeof(char), sizeof(header), fd);
931
932 dump_u((char *)&header, sizeof(header));
933
934 crc = get_crc16 ( (char *) &header, sizeof(header)-4);
935 printf("crc16 [%08x]\n", crc);
936
937 if((header.ih_hcrc & 0xFFFF) != crc) {
938 fclose(fd);
939 return -1;
940 }
941
942 fsize -= sizeof(header);
943 fsize -= header.ih_size;
944 checksum = 0;
945 len = header.ih_size;
946 while(len > 0)
947 {
948 if(len >= 1024 )
949 rByte = 1024;
950 else
951 rByte = len;
952
953 memset(buf, 0, sizeof(buf));
954 rByte = fread((char *)buf, 1, rByte, fd);
955 for(i = 0; i < (rByte+3)/4; i++)
956 checksum += buf[i];
957
958 len -= rByte;
959 }
960 printf("checksum [%08x]\n\n",checksum);
961
962 if( checksum != header.ih_dcrc) {
963 fclose(fd);
964 return -1;
965 }
966 }
967
968 fclose(fd);
969 return 0;
970}
971
972static int select_read(int fd, int timeout) //1ms
973{
974 fd_set set;
975 struct timeval t;
976 int ret;
977 int i = timeout;
978
979 if(use_select) {
980 do {
981 FD_ZERO(&set);
982 FD_SET(fd, &set);
983 t.tv_sec = 0;
984 t.tv_usec = 100;
985
986 ret = select(FD_SETSIZE, &set, NULL, NULL, &t );
987 if(ret == 0) continue;
988 if(ret < 0 && errno == EINTR)continue;
989 else return ret;
990 } while(i--);
991 } else {
992 struct timeval t0, t1;
993 long dt = 0;
994 int c;
995
996 gettimeofday(&t0, NULL);
997 do {
998 c = 0;
999 ret = ioctl(fd, FIONREAD, &c);
1000 if(c > 0) { ret = c; break; }
1001
1002 gettimeofday(&t1, NULL);
1003 dt = t1.tv_usec - t0.tv_usec;
1004 dt += (t1.tv_sec-t0.tv_sec)*1000*1000;
1005 } while(dt/1000 < timeout);
1006 }
1007
1008 return ret;
1009}
1010
1011int set_baudrate(int fd, int baudrate)
1012{
1013 struct termios options, oldtio;
1014
1015 if(fcntl(fd, F_SETFL, 0) < 0) {
1016 printf("fcntl failed!\n");
1017 return -1;
1018 }
1019
1020 if(tcgetattr(fd, &oldtio) != 0) {
1021 printf("setup serial error!\n");
1022 return -1;
1023 }
1024
1025 /* Get the current options for the port... */
1026 tcgetattr(fd, &options);
1027
1028 /* Set the baud rates to baudrate... */
1029 cfsetispeed(&options,baudrate);
1030 cfsetospeed(&options,baudrate);
1031 tcsetattr(fd, TCSANOW, &options);
1032
1033 if (0 != tcgetattr(fd, &options))
1034 {
1035 printf("get options error!\n");
1036 return -1;
1037 }
1038
1039 /*
1040 * 8bit Data,no partity,1 stop bit...
1041 */
1042 options.c_cflag &= ~PARENB;//无奇偶校验
1043 options.c_cflag &= ~CSTOPB;//停止位,1位
1044 options.c_cflag &= ~CSIZE; //数据位的位掩码
1045 options.c_cflag |= CS8; //数据位,8位
1046
1047 cfmakeraw(&options);
1048
1049 /*
1050 * Set the new options for the port...
1051 */
1052 if (tcsetattr(fd, TCSANOW, &options) != 0)
1053 {
1054 printf("setup serial error!\n");
1055 return -1 ;
1056 }
1057
1058 return 0 ;
1059}
1060
1061int initial_serialPort(char * serial_device)
1062{
1063 int fd;
1064 fd = open( serial_device , O_RDWR );
1065 if ( fd == -1 )
1066 {
1067 /* open error! */
1068 printf("Can't open serial port(%s)!(errno=%d:%s) \n", serial_device, errno, strerror(errno));
1069 return -1;
1070 }
1071
1072 set_baudrate(fd, B9600);
1073
1074 return fd ;
1075}
1076
1077static void gps_dev_send(int fd, char *msg)
1078{
1079 int i, n, ret;
1080
1081 i = strlen(msg);
1082
1083 n = 0;
1084
1085 printf("function gps_dev_send: %s", msg);
1086 do {
1087
1088 ret = write(fd, msg + n, i - n);
1089
1090 if (ret < 0 && errno == EINTR) {
1091 continue;
1092 }
1093
1094 n += ret;
1095
1096 } while (n < i);
1097
1098 // drain cmd
1099 tcdrain(fd);
1100
1101 return;
1102}
1103
1104int xmodem_send(int fd, char *fname)
1105{
1106 char packet_data[XMODEM_DATA_SIZE];
1107 char frame_data[XMODEM_DATA_SIZE + XMODEM_CRC_SIZE + XMODEM_FRAME_ID_SIZE + 1];
1108 int ret = -1;
1109
1110 FILE *datafile;
1111 int complete,retry_num,pack_counter,read_number,write_number,i;
1112 unsigned short crc_value;
1113 unsigned char ack_id = 'C';
1114 struct timeval time_m, time_n;
1115
1116 datafile = NULL;
1117 pack_counter = 0; // 包计数器清零
1118 complete = 0;
1119 retry_num = 0;
1120
1121 printf("[%s]\n",fname);
1122 //只读方式打开一个准备发送的文件,如果不存在就报错,退出程序。
1123 if((datafile=fopen(fname,"rb"))==NULL)
1124 {
1125 printf("\n can't open (%s) or not exist!(errno=%d:%s) \n", fname, errno, strerror(errno));
1126 return -1;
1127 }
1128 else
1129 {
1130 printf("Ready to send the file:%s\n",fname);
1131 }
1132
1133 printf("Waiting for signal C/NAK!\n");
1134 GET_TIME();
1135 while(1)
1136 {
1137 CHK_TIME1();
1138 if(select_read(fd,1) > 0)
1139 usleep(10000);
1140 else
1141 continue;
1142
1143 //read(fd,&ack_id,1);
1144 deal_read(fd,&ack_id,1);
1145 if(ack_id == 'C')
1146 break;
1147 }
1148
1149 printf("The signal NAK: %02x ok!!!\n",ack_id);//打印接收到的NAK信息
1150
1151 while(!complete)
1152 {
1153 switch(ack_id)
1154 {
1155 case XMODEM_CRC_CHR: // 接收到字符'C'开始启动传输,并使用CRC校验
1156 printf("begining to Send file %s...\n",fname);
1157
1158 case XMODEM_ACK: //0x06
1159 retry_num = 0;
1160 pack_counter++;
1161
1162 read_number = fread(packet_data, sizeof(char), XMODEM_DATA_SIZE, datafile);
1163 //从打开的datafile指向的文件中读取
1164 //XMODEM_DATA_SIZE 个(char)数据,
1165 //放到packet_data这个数组中
1166 if(read_number > 0)//read_number为返回的读取实际字节数
1167 {
1168 //printf("test:read_number:%d\n", read_number);
1169 if(read_number < XMODEM_DATA_SIZE_STX)
1170 {
1171 printf("Start filling the last frame!\n");
1172 for(; read_number < XMODEM_DATA_SIZE; read_number++)
1173 packet_data[read_number] = 0x1A; // 不足128字节用0x1A填充
1174 //printf("replenish data.\n");
1175 }
1176
1177 frame_data[0] = XMODEM_HEAD; // 帧开始字符
1178 frame_data[1] = (char)pack_counter; // 信息包序号
1179 frame_data[2] = (char)(255 - frame_data[1]); // 信息包序号的补码
1180
1181 for(i=0; i < XMODEM_DATA_SIZE; i++) // 128字节的数据段
1182 frame_data[i+3] = packet_data[i];//把收到的字符和信息头一起打包
1183
1184 crc_value = get_crc16(packet_data, XMODEM_DATA_SIZE); // 16位crc校验
1185 frame_data[XMODEM_DATA_SIZE+3] = (unsigned char)(crc_value >> 8);// 高八位数据
1186 frame_data[XMODEM_DATA_SIZE+4] = (unsigned char)(crc_value); //低八位数据
1187
1188 /* 发送133字节数据 */
1189 write_number = write( fd, frame_data, XMODEM_DATA_SIZE + 5);//向串口写一个包数据,即133字节数据
1190 printf("."); //ADD: process
1191 fflush(stdout);
1192 //printf("waiting for next ACK... \n......\n");
1193
1194 GET_TIME();
1195 while(1)
1196 {
1197 CHK_TIME1();
1198 if(select_read(fd,1) > 0)
1199 usleep(10000);
1200 else
1201 continue;
1202
1203 //read(fd,&ack_id,1);
1204 deal_read(fd,&ack_id,1);
1205 break;
1206 }
1207
1208 if(ack_id == XMODEM_ACK) {
1209 //printf("ACK Ok!!Ready sending next pack!\n");
1210 ;
1211 }
1212 else
1213 {
1214 printf("ACK Error!\n");
1215 printf("0x%02X\n",ack_id);
1216 //printf("pack_counter = %d\n", pack_counter);
1217 }
1218 }
1219
1220 else // 文件发送完成
1221 {
1222 ack_id = XMODEM_EOT;
1223 complete = 1;
1224 printf("Complete ACK\n");
1225
1226 GET_TIME();
1227 while(ack_id != XMODEM_ACK)
1228 {
1229 CHK_TIME1();
1230 ack_id = XMODEM_EOT;
1231 write_number = write(fd,&ack_id,1);
1232 while((deal_read(fd, &ack_id, 1)) <= 0);
1233 }
1234 printf("Send file successful!!!\n");
1235 fclose(datafile);
1236 datafile = NULL;
1237 }
1238 break;
1239
1240 case XMODEM_NAK:
1241 if( retry_num++ > 10)
1242 {
1243 printf("Retry too many times,Quit!\n");
1244 complete = 1;
1245 }
1246 else //重试,发送
1247 {
1248 write_number = write(fd, frame_data, XMODEM_DATA_SIZE + 5);
1249 printf("Retry for ACK,%d,%d...", pack_counter, write_number);
1250
1251 GET_TIME();
1252 while(1)
1253 {
1254 CHK_TIME1();
1255 if(select_read(fd,1) > 0)
1256 usleep(100);
1257 else
1258 continue;
1259
1260 //read(fd,&ack_id,1);
1261 deal_read(fd,&ack_id,1);
1262 break;
1263 }
1264
1265 if( ack_id == XMODEM_ACK )
1266 printf("OK\n");
1267 else
1268 printf("Error!\n");
1269 }
1270 break;
1271 default:
1272 printf("Fatal Error! %d\n", ack_id);
1273 complete = 1;
1274 return -1;
1275 break;
1276 }
1277 }
1278
1279 if( datafile != NULL )
1280 fclose(datafile);
1281
1282 return 0;
1283}