فهرست منبع

优化修改ymodem模块代码

niujiuru 2 روز پیش
والد
کامیت
f5d3df796f
1فایلهای تغییر یافته به همراه33 افزوده شده و 34 حذف شده
  1. 33 34
      ymodem/ymodem.c

+ 33 - 34
ymodem/ymodem.c

@@ -33,7 +33,6 @@ static unsigned long str_to_u32(char *str)
 {
   const char *s = str; unsigned long acc; int c;
 
-  /* Strip leading spaces if any */
   do {
     c = *s++;
   } while(c == ' ');
@@ -73,8 +72,8 @@ static void uart_putchar(int c)
   serial_send_data(s_myUart.h, &ch, 1);
 }
 
-/* Returns 0 on success, 1 on corrupt packet, -1 on error (timeout): */
-static int receive_packet(char *data, int *length)
+/* returns 0 on success, 1 on corrupt packet, -1 on error (timeout): */
+static int receive_packet(unsigned char *data, int *length)
 {
   int i, c; unsigned int packet_size;
   unsigned short received_crc;
@@ -112,7 +111,7 @@ static int receive_packet(char *data, int *length)
   if(data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff)) return 1;
 
   received_crc = (data[PACKET_HEADER + packet_size] << 8) | data[PACKET_HEADER + packet_size + 1];
-  if(crc16((unsigned char*)data + PACKET_HEADER, packet_size) != received_crc) return 1;
+  if(crc16(data + PACKET_HEADER, packet_size) != received_crc) return 1;
 
   *length = packet_size;
   return 0;
@@ -122,7 +121,7 @@ static int comio_data_recv_proc(unsigned long wParam/*传递打开的串口句
 {
   SYmodemUart *pComIO = &s_myUart; void *pSerial = pComIO->h;
   const unsigned char *pRecvBuf = serial_get_recv_buffer(pSerial); int nRecvBytes = serial_get_recv_buffer_bytes(pSerial);
-  const char *log_prefix = serial_get_log_prefix(pSerial); RingBufElement val = pRecvBuf[nRecvBytes - 1]; // 1字节数据
+  const char *log_prefix = serial_get_log_prefix(pSerial); RingBufElement val = pRecvBuf[nRecvBytes - 1]; // 取出1字节数据
   if(!RingBuf_put(&pComIO->rx_buf, val)) {
     uart_putchar(CAN); uart_putchar(CAN);
     sw_log_error("%s: sorry,ring buffer full, failed to put!!", log_prefix);
@@ -135,17 +134,17 @@ static int comio_data_recv_proc(unsigned long wParam/*传递打开的串口句
 int ymodem_recv_files(const char *dir)
 {
   unsigned char packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD];
-  int packet_length, i, file_done, session_done;
+  int packet_length, i, file_done, session_done, ret;
   unsigned int packets_received, errors, first_try, files_num;
   char file_name[FILE_NAME_LENGTH], file_size[FILE_SIZE_LENGTH], *file_ptr;
   unsigned char block[PACKET_1K_SIZE]; unsigned int file_size_val = 0; char path[MAX_PATH_CHARS];
 
-  RingBuf_ctor(&s_myUart.rx_buf, s_myUart.rx_buf_storage, sizeof(s_myUart.rx_buf_storage) / sizeof(RingBufElement));
+  RingBuf_ctor(&s_myUart.rx_buf, s_myUart.rx_buf_storage, sizeof(s_myUart.rx_buf_storage)/sizeof(RingBufElement));
   s_myUart.h = serial_open(UART_DEVICE_NAME, UART_BAUD_RATE, UART_PARITY_CHECK, \
                            comio_data_recv_proc, NULL, NULL);
   if(!s_myUart.h) return -1;
 
-  file_name[0] = '\0'; first_try = 1; files_num = 0;
+  file_name[0] = '\0'; first_try = 1; ret = files_num = 0;
   for(session_done = 0, errors = 0; serial_recvThrd_isAlive(s_myUart.h); )
   { // receive files
     if(!first_try) uart_putchar(CRC);
@@ -153,20 +152,20 @@ int ymodem_recv_files(const char *dir)
 
     for(packets_received = 0, file_done = 0; serial_recvThrd_isAlive(s_myUart.h); )
     { // receive packets
-      switch(receive_packet((char *)packet_data, &packet_length))
+      switch(receive_packet(packet_data, &packet_length))
       {
       case  0: // receive success
         if(errors != 0) errors = 0;
         switch(packet_length)
         {
-        case -1: { uart_putchar(ACK); serial_close(s_myUart.h, WAITTHRD_SAFEEXIT_TIMEOUT); return -2; } // abort
+        case -1: { uart_putchar(ACK); ret = -2; goto ret_p; } // abort
         case  0: { uart_putchar(ACK); file_done = 1; ++files_num; break; } // end of file
         default: // normal data packet
           if((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)) { uart_putchar(NAK); break; } // sequence number error
           if(packets_received == 0)
           {
-            if(packet_data[PACKET_HEADER] != 0x00) // filename packet has data
-            {
+            if(packet_data[PACKET_HEADER] != 0x00)
+            { // filename packet has data
               for(file_ptr = (char *)packet_data + PACKET_HEADER, i = 0; *file_ptr && i < FILE_NAME_LENGTH; ) file_name[i++] = *file_ptr++;
               file_name[i++] = '\0'; // 接收的文件名称
               for(++file_ptr, i = 0; *file_ptr != ' ' && i < FILE_SIZE_LENGTH; ) file_size[i++] = *file_ptr++;
@@ -188,47 +187,47 @@ int ymodem_recv_files(const char *dir)
           {
             for(i = 0; i < packet_length; i++) { block[i] = packet_data[PACKET_HEADER+i]; }
             uart_putchar(ACK);
-            sw_log_debug("[%s] <文件: %s, 大小: %u> 收到第%u包数据, 数据包大小: %u字节", UART_MODULE_NAME, \
-                          file_name, file_size_val, packets_received, packet_length);
+            sw_log_debug("[%s] <文件: %s, 大小: %u> 收到第%u包数据, 数据包大小: %u字节", \
+              UART_MODULE_NAME, file_name, file_size_val, packets_received, packet_length);
 
             if(!sw_dir_exists(dir)) sw_dir_create(dir);
-            if(sw_file_update(path, "ab", (char *)block, packet_length) != packet_length) { uart_putchar(CAN); uart_putchar(CAN); serial_close(s_myUart.h, WAITTHRD_SAFEEXIT_TIMEOUT); return -3; }
+            ret = sw_file_update(path, "ab", (char *)block, packet_length);
+            if(ret != packet_length) { uart_putchar(CAN); uart_putchar(CAN); ret = -3; goto ret_p; }
           }
           ++packets_received; // 累加已接收包数
         }
         break;
       default: // receive error
-        if(packets_received != 0) { if(++errors >= MAX_ERRORS/*many errors*/) { uart_putchar(CAN); uart_putchar(CAN); serial_close(s_myUart.h, WAITTHRD_SAFEEXIT_TIMEOUT); return -4; } }
+        if(packets_received != 0) { if(++errors >= MAX_ERRORS/* too many errors */) { uart_putchar(CAN); uart_putchar(CAN); ret = -4; goto ret_p; } }
         uart_putchar(CRC);
       }
 
       if(file_done)  { if(!session_done) sw_log_info("[%s] 文件: %s 接收完成, 实际大小: %u字节", UART_MODULE_NAME, file_name, sw_file_getSize(path)); break; } // 文件接收完成
     }
 
-    if(session_done) break; // 传输会话结束
+    if(session_done) { ret = files_num; break; } // 传输会话结束
   }
 
-  serial_close(s_myUart.h, WAITTHRD_SAFEEXIT_TIMEOUT);
-  return files_num;
+ret_p:
+  if(s_myUart.h) serial_close(s_myUart.h, WAITTHRD_SAFEEXIT_TIMEOUT);
+  return ret;
 }
 
 static void send_packet(unsigned char *data, int block_no)
 {
- int count, packet_size; unsigned short crc;
+  int count, packet_size; unsigned short crc;
 
- /* We use a short packet for block 0 - all others are 1K */
- if(block_no == 0) packet_size = PACKET_SIZE;
- else packet_size = PACKET_1K_SIZE;
+  if(block_no == 0) packet_size = PACKET_SIZE;
+  else packet_size = PACKET_1K_SIZE;
 
- crc = crc16(data, packet_size);
- /* 128 byte packets use SOH, 1K use STX */
- uart_putchar((block_no == 0) ? SOH : STX);
- uart_putchar(block_no & 0xFF);
- uart_putchar(~block_no & 0xFF);
+  crc = crc16(data, packet_size);
+  uart_putchar((block_no == 0) ? SOH : STX);
+  uart_putchar(block_no & 0xFF);
+  uart_putchar(~block_no & 0xFF);
 
- for(count = 0; count < packet_size; count++) uart_putchar(data[count]);
- uart_putchar((crc >> 8) & 0xFF);
- uart_putchar(crc & 0xFF);
+  for(count = 0; count < packet_size; count++) uart_putchar(data[count]);
+  uart_putchar((crc >> 8) & 0xFF);
+  uart_putchar(crc & 0xFF);
 }
 
 /* Send block 0 (the filename block). filename might be truncated to fit. */
@@ -267,7 +266,7 @@ static long send_data_packets(unsigned char *data, unsigned long size)
       blockno++; retry = 0;
       data += send_size;
       size -= send_size;
-      total_sent += send_size; // 已发送的字节数
+      total_sent += send_size; // 累加已发送的字节数
     }
     else if(ch == NAK || ch == -1)
     {
@@ -324,7 +323,7 @@ int ymodem_send_file(const char *path)
                            comio_data_recv_proc, NULL, NULL);
   if(!s_myUart.h) { ret = -5; goto ret_p; }
 
-  retry = 0; do { ch = uart_getchar(PACKET_TIMEOUT); } while(ch != CRC && ++retry < 30);
+  retry = 0; do { ch = uart_getchar(PACKET_TIMEOUT); } while(ch != CRC && ++retry < 30); // 等待接收CRC, 而后才开始发送文件
   if(ch != CRC) { uart_putchar(CAN); uart_putchar(CAN); ret = -6; goto ret_p; }
 
   retry = 0; do
@@ -342,6 +341,6 @@ int ymodem_send_file(const char *path)
 
 ret_p:
   if(file_buf) free(file_buf);
-  if(s_myUart.h) serial_close(s_myUart.h, WAITTHRD_SAFEEXIT_TIMEOUT); s_myUart.h = NULL;
+  if(s_myUart.h) serial_close(s_myUart.h, WAITTHRD_SAFEEXIT_TIMEOUT);
   return ret;
 }