#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ymodem.h" #include "serial_port.h" #include "download.h" #include "checkversion.h" #include #include #define DEV_PATH_DEF "/dev/ttyUSB0" #define BAUDRATE_DEF 115200 #define TIMEOUT_DEF 20 //10*100ms double processvalue = 0; #define short_wait_time 30 #define long_wait_time 3600 static int g_fd; static struct ymodem ymodem; static FILE* g_fp; sem_t *my_semaphore; int is_insem = 0; void signal_handler(int signo) { if (signo == SIGINT || signo == SIGTERM) { // 在这里执行你的操作 sleep(1); printf("Received termination signal. Performing cleanup...\n"); unsigned char stop_data[] = {0x18, 0x18, 0x18, 0x18, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08}; write(g_fd, stop_data, sizeof(stop_data)); sleep(1); // system("/demo/bin/testprogram &"); if(is_insem == 1){ sem_post(my_semaphore); is_insem = 0; printf("%d\n",is_insem); printf("出锁\n"); } exit(0); } } //输入进入ota的命令 void put_start_char(){ unsigned char start_data[] = {0xac,0x53,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x33,0x44,0x85,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x01,0x00,0x84,0x09}; write(g_fd, start_data, sizeof(start_data)); } //清空串口缓存 int flush_serial_input() { int result = tcflush(g_fd, TCIFLUSH); if (result == -1) { perror("tcflush"); } return result; } int _putchar(unsigned char ch) { return write(g_fd, &ch, 1); } int _getchar(void) { ssize_t size; unsigned char ch; size = read(g_fd, &ch, 1); if (size == 1) return ch; else return -1; } int get_result(void) { ssize_t size; unsigned char ch; char buffer[255]; size = read(g_fd, buffer, sizeof(buffer)); if (size > 0){ char hexData[1024]; std::vector byteArray; int i; for (i = 0; i < size; i++) { snprintf(&hexData[i * 2], sizeof(hexData) - i * 2, "%02X", buffer[i]); byteArray.push_back(static_cast(buffer[i])); } printf("Received result: %s\n", hexData); for (unsigned char c : byteArray) { std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast(c) << " "; } std::cout << std::endl; //解析部分 if (byteArray.size() >= 16 && byteArray[15] == 0x04) { // 第15个字节是1 // 在这里编写处理逻辑 std::cout << "功能码为0x04 OTA升级时状态码上报" <= 23 && byteArray[22] == 0x01){ std::cout << "升级包过大,取消升级" <= 23 && byteArray[22] == 0x02){ std::cout << "写入闪存错误" <= 23 && byteArray[22] == 0x03){ std::cout << "用户取消升级" <= 23 && byteArray[22] == 0x04){ std::cout << "获取包错误" <= 23 && byteArray[22] == 0x05){ std::cout << " 升级超时" <= 23 && byteArray[22] == 0x06){ std::cout << "升级成功!" <= 23 && byteArray[22] == 0x07){ std::cout << "错误太多" <= 23 && byteArray[22] == 0x08){ std::cout << "包名错误" <= 23 && byteArray[22] == 0x09){ std::cout << "包名相同" < ymodem.file_size) { invalid = recv_file_size - ymodem.file_size; } fwrite(buf, 1, len - invalid, g_fp); return 0; } int end_packet_callback(const unsigned char *buf, unsigned long len) { fclose(g_fp); return 0; } int recevice(void) { int ret; printf("Receice Ymodem!\r\n"); ret = ymodem_receive(&ymodem); //需要再发送两个0x4F,xshell/secureCRT才会提示传送完成 sleep(1); ymodem.putchar(0x4F); ymodem.putchar(0x4F); return ret; } int send_begin_packet_callback(const unsigned char *buf, unsigned long len) { return 0; } int send_data_packet_callback(const unsigned char *buf, unsigned long len) { return 0; } int send_end_packet_callback(const unsigned char *buf, unsigned long len) { return 0; } int send_file(const char* file_name) { int ret, fd, index, size; printf("Send Ymodem! file: %s\r\n", file_name); strcpy(ymodem.file_name, file_name); fd = open(file_name, O_RDONLY); if (fd <= 0) return -1; //get file data index = 0; ymodem.data = (unsigned char *)malloc(300*1024); do { size = read(fd, &ymodem.data[index], 1024); if (size) index += size; } while(size > 0); close(fd); ymodem.file_size = index; ret = ymodem_send(&ymodem); free(ymodem.data); return ret; } void ymodem_help(void) { printf("Usage : ./ymodem [options]\n"); printf("options:\r\n"); printf("eg send Ymodem: ./ymodem -d /dev/ttyUSB0 -s /sdcard/test.txt\r\n"); printf("eg receive Ymodem: ./ymodem -d /dev/ttyUSB0\r\n"); printf("\t -d device path.设置设备名,默认/dev/ttyUSB0.\r\n"); printf("\t -s send Ymodem, receiving mode if not set.发送文件,如果不选,默认为接收文件\r\n"); printf("\t -t Set getchar timeout,def:10(1s), 1=100ms.设置getchar超时,1为100毫秒,默认10=>1s.\r\n"); printf("\t --help display specific types of command line options.\r\n\r\n"); } int main(int argc, char *argv[]) { // 注册信号处理函数 signal(SIGINT, signal_handler); // SIGINT 对应Ctrl+C signal(SIGTERM, signal_handler); // SIGTERM 对应kill或pkill my_semaphore = sem_open("/my_semaphore", O_CREAT, 0644, 1); int this_option_optind = optind ? optind : 1; int option_index = 0; int c = -1; int timeout = TIMEOUT_DEF; char dev_path[128] = DEV_PATH_DEF; int is_send = 0; char g_file_name[256] = {0}; int putchar_flag = 0; int putchar_value = 0; char url_download[256] = ""; char url_check[256] = ""; int res = -1; while (1) { struct option long_options[] = { {"help", no_argument, 0, 'h' }, {"url_download", required_argument, 0, 'u'}, {"url_check", required_argument, 0, 'w'}, {0, 0, 0, 0 } }; c = getopt_long_only(argc, argv, "c:s:d:t:u:w:h", long_options, &option_index); if (c == -1) break; switch (c) { case 0: break; case 'c': putchar_flag = 1; putchar_value = optarg[0]; printf("putchar value: %c\r\n", putchar_value); break; case 'd': strcpy(dev_path, optarg); printf("dev path: %s\r\n", dev_path); break; case 's': strcpy(g_file_name, optarg); printf("send file: %s.\r\n", g_file_name); is_send = 1; break; case 't': timeout = atoi(optarg); printf("timeout: %d*100ms.\r\n", timeout); break; case 'u': strcpy(url_download, optarg); printf("URL_downlaod: %s\r\n", url_download); break; case 'w': strcpy(url_check, optarg); printf("URL_check: %s\r\n", url_check); break; case 'h': case '?': ymodem_help(); return 0; // break; default: break; } } if (optind < argc) { printf("non-option ARGV-elements: "); while (optind < argc) printf("%s ", argv[optind++]); printf("\n"); ymodem_help(); return 0; } while(1){ char local_SE_APP_version[50] = {0}; char download_SE_APP_version[50] = {0}; char download_SE_APP_url[255] = {0}; if(check_version(local_SE_APP_version,download_SE_APP_version,download_SE_APP_url, sizeof(local_SE_APP_version),sizeof(download_SE_APP_version),sizeof(download_SE_APP_url))){ printf("_save_APP_path = %s\n",_save_APP_path); //获取文件 int res = download_file(download_SE_APP_url, _save_APP_path); if (res == -1) { printf("download_file error.\n"); sleep(long_wait_time); continue; } strcpy(g_file_name, _save_APP_path); is_send = 1; // init serial printf("open dev: %s\r\n", dev_path); g_fd = open(dev_path, O_RDWR); if (g_fd <= 0) { printf("open %s failed!\r\n", dev_path); sleep(long_wait_time); continue; } serial_set(g_fd, BAUDRATE_DEF, 8, 'N', 1, timeout, 0); //1vtime = 100ms, 10=1000ms=1s ymodem.putchar = _putchar; ymodem.getchar = _getchar; if (putchar_flag) { ymodem.putchar(putchar_value); printf("putchar: %c/%d\r\n", putchar_value,putchar_value); sleep(30); continue; } if (is_send) { // system("pkill testprogram"); printf("等锁\n"); sem_wait(my_semaphore); is_insem = 1; printf("入锁\n"); sleep(1); ymodem.begin_packet_cb = send_begin_packet_callback; ymodem.data_packet_cb = send_data_packet_callback; ymodem.end_packet_cb = send_end_packet_callback; if (send_file(g_file_name) == 0) { printf("Transfer complete!\r\n"); // int i = 0; // do { // res = get_result(); // i++; // printf("res: %d i=%d\n",res,i); // } while ((res != 0) && (i < 3)); sem_post(my_semaphore); is_insem = 0; printf("出锁\n"); // system("/demo/bin/testprogram &"); } else { printf("Send Ymodem err!\r\n"); printf("stage: %d\r\n", ymodem.stage); // int i = 0; // do { // res = get_result(); // i++; // printf("res: %d i=%d\n",res,i); // } while ((res != 0) && (i < 3)); sem_post(my_semaphore); is_insem = 0; printf("出锁\n"); // system("/demo/bin/testprogram &"); } } else { ymodem.begin_packet_cb = begin_packet_callback; ymodem.data_packet_cb = data_packet_callback; ymodem.end_packet_cb = end_packet_callback; if (recevice() == 0) { printf("Recevice complete!\r\n"); printf("file: %s, size: %d\r\n", ymodem.file_name, ymodem.file_size); } else { printf("Recevice Ymodem err!\r\n"); printf("stage: %d\r\n", ymodem.stage); } } close(g_fd); sleep(long_wait_time); continue; }else{ sleep(long_wait_time); continue; } } }