static int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout) { uint16_t i, packet_size; uint8_t c; *length = 0; if (Receive_Byte(&c, timeout) != 0) return -1; switch (c) { case SOH: packet_size = PACKET_SIZE; break; case STX: packet_size = PACKET_1K_SIZE; break; case EOT: return 0; case CA: if ((Receive_Byte(&c, timeout) == 0) && (c == CA)) { *length = -1; return 0; } else return -1; case ABORT1: case ABORT2: return 1; default: return -1; } *data = c; for (i = 1; i < (packet_size + PACKET_OVERHEAD); i ++) { if (Receive_Byte(data + i, timeout) != 0) return -1; } if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff)) return -1; *length = packet_size; return 0; }
/******************************************************************************* * @函数名称 Receive_Packet * @函数说明 从发送端接收一个数据包 * @输入参数 data :数据指针 length:长度 timeout :超时时间 * @输出参数 无 * @返回参数 接收的结果 0: 正常返回 -1: 超时或者数据包错误 1: 用户取消 *******************************************************************************/ int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout) { uint16_t i, packet_size; uint8_t c; *length = 0; if (Receive_Byte(&c, timeout) != 0) //0:成功接收 { return -1; // -1: 超时,注意此时*length=0 } switch (c) { case SOH: packet_size = PACKET_SIZE; //包的数据区的大小为128 break; case STX: packet_size = PACKET_1K_SIZE; //包的数据区的大小为1024 break; case EOT: //结束传输 return 0; //0: 正常返回,注意此时*length=0 /***********************************/ case CA: //接受一个CA,再接受一个CA if ((Receive_Byte(&c, timeout) == 0) && (c == CA)) { *length = -1; //正常返回 return 0; //0: 正常返回,注意此时*length=-1 /***********************************/ } else { return -1; //-1: 超时或者数据包错误,注意此时*length=0 } case ABORT1: //A case ABORT2: //a return 1; //1: 用户取消,注意此时*length=0 default: return -1; //-1: 超时或者数据包错误,注意此时*length=0 } *data = c; for (i = 1; i < (packet_size + PACKET_OVERHEAD); i ++)//接受一个包除开始信号的剩余数据,最后接受整个数据包 { if (Receive_Byte(data + i, timeout) != 0) { return -1; //-1: 超时,注意此时*length=0 } } if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff)) //检验包编号是否正确 { return -1; //-1: 数据包错误,注意此时*length=0 } *length = packet_size; return 0; //0: 正常返回,注意此时*length=packet_size /***********************************/ }
//-------------------------------------------------------- static uint8_t Ymodem_WaitACK(uint8_t ackchr, uint8_t tmo) { uint8_t receivedC[2]; uint32_t errors = 0; do { if (Receive_Byte(&receivedC[0], NAK_TIMEOUT) == 0) { if (receivedC[0] == ackchr) { return 1; } else if (receivedC[0] == CA) { send_CA(); return 2; // CA received, Sender abort } else if (receivedC[0] == NAK) { return 3; } else { return 4; } } else { errors++; } luaWdgReload(); }while (errors < tmo); return 0; }
/** * @brief Transmit a file using the ymodem protocol * @param buf: Address of the first byte * @retval The size of the file */ uint8_t Ymodem_Transmit (uint8_t *buf, const uint8_t* sendFileName, uint32_t sizeFile) { uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD]; uint8_t filename[FILE_NAME_LENGTH]; uint8_t *buf_ptr, tempCheckSum; uint16_t tempCRC; uint16_t blkNumber; uint8_t receivedC[2], CRC16_F = 0, i; uint32_t errors, ackReceived, size = 0, pktSize; errors = 0; ackReceived = 0; for (i = 0; i < (FILE_NAME_LENGTH - 1); i++) { filename[i] = sendFileName[i]; } CRC16_F = 1; /* Prepare first block */ Ymodem_PrepareIntialPacket(&packet_data[0], filename, &sizeFile); do { /* Send Packet */ Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER); /* Send CRC or Check Sum based on CRC16_F */ if (CRC16_F) { tempCRC = Cal_CRC16(&packet_data[3], PACKET_SIZE); Send_Byte(tempCRC >> 8); Send_Byte(tempCRC & 0xFF); } else { tempCheckSum = CalChecksum (&packet_data[3], PACKET_SIZE); Send_Byte(tempCheckSum); } /* Wait for Ack and 'C' */ if (Receive_Byte(&receivedC[0], 10000) == 0) { if (receivedC[0] == ACK) { /* Packet transferred correctly */ ackReceived = 1; } } else { errors++; } } while (!ackReceived && (errors < 0x0A));
/******************************************************************************* * @函数名称 Ymodem_Transmit * @函数说明 通过ymodem协议传输一个文件 * @输入参数 buf :数据地址指针 sendFileName :文件名 sizeFile:文件长度 * @输出参数 无 * @返回参数 是否成功 0:成功 *******************************************************************************/ uint8_t Ymodem_Transmit (uint8_t *buf, const uint8_t* sendFileName, uint32_t sizeFile) { uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD]; uint8_t FileName[FILE_NAME_LENGTH]; uint8_t *buf_ptr, tempCheckSum ; uint16_t tempCRC, blkNumber; uint8_t receivedC[2], CRC16_F = 0, i; uint32_t errors, ackReceived, size = 0, pktSize; errors = 0; ackReceived = 0; for (i = 0; i < (FILE_NAME_LENGTH - 1); i++) { FileName[i] = sendFileName[i]; } CRC16_F = 1; //准备第一个数据包 Ymodem_PrepareIntialPacket(&packet_data[0], FileName, &sizeFile); do { //发送数据包 Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER); //发送CRC校验 if (CRC16_F) { tempCRC = Cal_CRC16(&packet_data[3], PACKET_SIZE); Send_Byte(tempCRC >> 8); Send_Byte(tempCRC & 0xFF); } else { tempCheckSum = CalChecksum (&packet_data[3], PACKET_SIZE); Send_Byte(tempCheckSum); } //等待响应 if (Receive_Byte(&receivedC[0], 10000) == 0) { if (receivedC[0] == ACK) { //数据包正确传输 ackReceived = 1; } } else { errors++; } } while (!ackReceived && (errors < 0x0A));
//-------------------------------------------------------------------------- static uint8_t Ymodem_Transmit (const char* sendFileName, uint32_t sizeFile) { uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD]; uint8_t filename[SPIFFS_OBJ_NAME_LEN]; uint16_t blkNumber; uint8_t receivedC[1], i, err; uint32_t size = 0; for (i = 0; i < (SPIFFS_OBJ_NAME_LEN - 1); i++) { filename[i] = sendFileName[i]; } while (MicoUartRecv( MICO_UART_1, &receivedC[0], 1, 10 ) == kNoErr) {}; // Wait for response from receiver err = 0; do { luaWdgReload(); Send_Byte(CRC16); } while (Receive_Byte(&receivedC[0], NAK_TIMEOUT) < 0 && err++ < 45); if (err >= 45 || receivedC[0] != CRC16) { send_CA(); return 99; } // === Prepare first block and send it ======================================= /* When the receiving program receives this block and successfully * opened the output file, it shall acknowledge this block with an ACK * character and then proceed with a normal YMODEM file transfer * beginning with a "C" or NAK tranmsitted by the receiver. */ Ymodem_PrepareIntialPacket(&packet_data[0], filename, &sizeFile); do { // Send Packet Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_OVERHEAD); // Wait for Ack err = Ymodem_WaitACK(ACK, 10); if (err == 0 || err == 4) { send_CA(); return 90; // timeout or wrong response } else if (err == 2) return 98; // abort }while (err != 1); // After initial block the receiver sends 'C' after ACK if (Ymodem_WaitACK(CRC16, 10) != 1) { send_CA(); return 90; } // === Send file blocks ====================================================== size = sizeFile; blkNumber = 0x01; // Resend packet if NAK for a count of 10 else end of communication while (size) { // Prepare and send next packet Ymodem_PreparePacket(&packet_data[0], blkNumber, size); do { Ymodem_SendPacket(packet_data, PACKET_1K_SIZE + PACKET_OVERHEAD); // Wait for Ack err = Ymodem_WaitACK(ACK, 10); if (err == 1) { blkNumber++; if (size > PACKET_1K_SIZE) size -= PACKET_1K_SIZE; // Next packet else size = 0; // Last packet sent } else if (err == 0 || err == 4) { send_CA(); return 90; // timeout or wrong response } else if (err == 2) return 98; // abort }while(err != 1); } // === Send EOT ============================================================== Send_Byte(EOT); // Send (EOT) // Wait for Ack do { // Wait for Ack err = Ymodem_WaitACK(ACK, 10); if (err == 3) { // NAK Send_Byte(EOT); // Send (EOT) } else if (err == 0 || err == 4) { send_CA(); return 90; // timeout or wrong response } else if (err == 2) return 98; // abort }while (err != 1); // === Receiver requests next file, prepare and send last packet ============= if (Ymodem_WaitACK(CRC16, 10) != 1) { send_CA(); return 90; } Ymodem_PrepareLastPacket(&packet_data[0]); do { Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_OVERHEAD); // Send Packet // Wait for Ack err = Ymodem_WaitACK(ACK, 10); if (err == 0 || err == 4) { send_CA(); return 90; // timeout or wrong response } else if (err == 2) return 98; // abort }while (err != 1); return 0; // file transmitted successfully }
//------------------------------------------------------------------------------ static int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout) { uint16_t i, packet_size; uint8_t c; //uint16_t tempCRC; *length = 0; luaWdgReload(); if (Receive_Byte(&c, timeout) != 0) { luaWdgReload(); return -1; } luaWdgReload(); switch (c) { case SOH: packet_size = PACKET_SIZE; break; case STX: packet_size = PACKET_1K_SIZE; break; case EOT: return 0; case CA: if ((Receive_Byte(&c, timeout) == 0) && (c == CA)) { *length = -1; luaWdgReload(); return 0; } else { luaWdgReload(); return -1; } case ABORT1: case ABORT2: luaWdgReload(); return 1; default: luaWdgReload(); return -1; } *data = c; luaWdgReload(); for (i = 1; i < (packet_size + PACKET_OVERHEAD); i ++) { if (Receive_Byte(data + i, 10) != 0) { luaWdgReload(); return -1; } } luaWdgReload(); if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff)) { return -1; } if (crc16(&data[PACKET_HEADER], packet_size + PACKET_TRAILER) != 0) { return -1; } *length = packet_size; return 0; }
/******************************************************************************* * 函数名称: download_program_to_meter * 输入参数: * 输出参数: * --返回值: * 函数功能: -- *******************************************************************************/ static void download_program_to_meter(void) { uint32_t status = 0u; uint8_t tick_C = 0u; uint8_t Rev_flag = 0u; uint8_t read_flash_check_flag = 0u; uint8_t file_size[FILE_SIZE_LENGTH] = {0}; /* wait for meter send 'C', meter printf something before send 'C' */ delay_ms(5000); /* 存在很低的概率, 会出现在进入升级的时候会停滞几秒 */ MFS_UARTErrorClr(UartUSBCh); //CLR error flag MFS_UARTSWRst(UART52_Ch); //reset UART UARTConfigMode(UART52_Ch, &tUARTModeConfigT); MFS_UARTEnableRX(UART52_Ch); MFS_UARTEnableTX(UART52_Ch); //SerialPutString("\n\n\rSelect Receive File ... \n\r"); Rev_flag = Receive_Byte(UART52_Ch , &tick_C, Rev_timeout); if (0u == Rev_flag) { if (tick_C == CRC16) { printf("Rev C. \r\n"); } } else { SerialPutString("\r\n no Rev 'C' .\r\n"); } if (tick_C == CRC16) { SerialPutString("downlod image .bin ... \r\n"); read_flash_check_flag = 0u; read_flash_check_flag = MX25L3206_Read((uint8_t*)(file_size), (uint32_t)FLASH_IMAGE_SIZE_ADDRESS, FILE_SIZE_LENGTH); if (OK != read_flash_check_flag) { __NOP(); } else { Str2Int(file_size, &flash_image_size); /* str to hex */ /* Transmit the flash image through ymodem protocol */ status = Ymodem_Transmit((uint8_t*)ApplicationAddress, //!!!!Note (const uint8_t*)"DownloadFlashImage.bin", flash_image_size); /* , ,FLASH_IMAGE_MAX_SIZE */ MFS_UARTDisableRX(UART52_Ch); // if (status != 0) { SerialPutString("\n\rError Occured while Transmitting File\n\r"); oneSound(10, 300); /* BUZZER 201 error buzz */ } else { SerialPutString("\n\rFile Trasmitted Successfully \n\r"); oneSound(10, 0); /* BUZZER 201 buzz */ } }//end if flash check } else { SerialPutString("\r\n\nAborted by user or no Rev 'C' .\n\r"); oneSound(10, 300); /* BUZZER 201 error buzz */ //while(1); //test!!! } bFM3_GPIO_PDOR0_PD = 1u; /* LED 201 light off */ bFM3_GPIO_PDOR0_PC = 1u; /* LED 202 light off */ MFS_UARTDisableRX(UART52_Ch); MFS_UARTDisableTX(UART52_Ch); }
/** * @brief Receive a packet from sender * @param data * @param length * @param timeout * 0: end of transmission * -1: abort by sender * >0: packet length * @retval 0: normally return * -1: timeout or packet error * 1: abort by user */ static int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout) { uint16_t i, packet_size, computedcrc; uint8_t c; *length = 0; if (Receive_Byte(&c, timeout) != 0) { return -1; } switch (c) { case SOH: packet_size = PACKET_SIZE; break; case STX: packet_size = PACKET_1K_SIZE; break; case EOT: return 0; case CA: if ((Receive_Byte(&c, timeout) == 0) && (c == CA)) { *length = -1; return 0; } else { return -1; } case ABORT1: case ABORT2: return 1; default: return -1; } *data = c; for (i = 1; i < (packet_size + PACKET_OVERHEAD); i ++) { if (Receive_Byte(data + i, timeout) != 0) { return -1; } } if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff)) { return -1; } /* Compute the CRC */ computedcrc = Cal_CRC16(&data[PACKET_HEADER], (uint32_t)packet_size); /* Check that received CRC match the already computed CRC value data[packet_size+3]<<8) | data[packet_size+4] contains the received CRC computedcrc contains the computed CRC value */ if (computedcrc != (uint16_t)((data[packet_size+3]<<8) | data[packet_size+4])) { /* CRC error */ return -1; } *length = packet_size; return 0; }
/******************************************************************************* * 函数名称: 比对版本号,返回提示 * 输入参数: * 输出参数: * --返回值: * 函数功能: -- *******************************************************************************/ uint8_t ReadVersion(void) { uint16_t i; uint8_t version_meter[FILE_NAME_LENGTH] = {0}; uint8_t version_buff[FILE_NAME_LENGTH] = {0}; volatile uint8_t ackReceived = 0; uint32_t errors = 0u; volatile uint8_t return_val = 0; UARTConfigMode(UART52_Ch,&tUART4800ModeConfigT); // 第一步, 初始化波特率,让表回到 300波特率 delay_ms(5); SendPacket((uint8_t *)&CommadSendB0,sizeof(CommadSendB0)); delay_ms(1000); UARTConfigMode(UART52_Ch,&tUART300ModeConfigT); //更改一下 波特率 300 delay_ms(5); SendPacket((uint8_t *)&Commadrequest,sizeof(Commadrequest)); //第二步, 发送请求命令 delay_ms(1000); SendPacket((uint8_t *)&CommadChangeBraud,sizeof(CommadChangeBraud)); //第三步, 发送表的更改波特率命令 delay_ms(500); Get_One_char(UART52_Ch, version_meter); UARTConfigMode(UART52_Ch,&tUART4800ModeConfigT); //更改一下 波特率 4800 delay_ms(5); do //读版本号 { //MFS_UARTEnableRX(UART52_Ch); ackReceived = 0; SendPacket((uint8_t *)&CommadReadProgamVersion, sizeof(CommadReadProgamVersion)); memset(version_meter,0,sizeof(version_meter)); Get_One_char(UART52_Ch, version_meter); //read a char CLR RDR MFS_UARTEnableRX(UART52_Ch); for(i=0;i<50;i++) { if (Receive_Byte(UART52_Ch, version_meter + i, 1000) != 0) { errors++; // ACC error break; } else { _NOP(); } } ackReceived = 1; MFS_UARTDisableRX(UART52_Ch); //#define VERSION_EN #ifdef VERSION_EN MX25L3206_Read((uint8_t*)version_buff, (uint32_t)VERSION_ADDRESS, FILE_NAME_LENGTH); if (memcmp(version_meter+7, &version_buff, 11) != 0) // 比对版本号 { return_val = METER_TYPE_ERR; } else { if (memcmp(version_meter+19, (uint8_t *)&version_buff+12, 11) < 0) { return_val = VERSION_OK; } else { return_val = VERSION_ERR; } } delay_ms(500); //loop interval #else /* version disable */ if (memcmp(version_meter+7, &sSoftWare_Versions_ASCLL, 11) != 0) // 比对版本号 { #ifdef METER_TYPE_EN return_val = METER_TYPE_ERR; #else return_val = VERSION_OK; #endif } else { if (memcmp(version_meter+19, (uint8_t *)&sSoftWare_Versions_ASCLL+12, 11) <= 0) { return_val = VERSION_OK; } else { return_val = VERSION_ERR; } } delay_ms(500); //loop interval #endif }while (!ackReceived && (errors < 3u)); return return_val; }
/** * @brief Receive a packet from sender * @param data * @param length * @param timeout * 0: end of transmission * -1: abort by sender * >0: packet length * @retval 0: normally return * -1: timeout or packet error * 1: abort by user */ static int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout) { uint16_t i, packet_size; uint8_t c; *length = 0; if (Receive_Byte(&c, timeout) != 0) { return -1; } switch (c) { case STX_8B: packet_size = PACKET_8B_SIZE; break; case STX_16B: packet_size = PACKET_16B_SIZE; break; case STX_32B: packet_size = PACKET_32B_SIZE; break; case STX_64B: packet_size = PACKET_64B_SIZE; break; case STX_128B: case SOH://为了兼容超级终端 packet_size = PACKET_128B_SIZE; break; case STX_256B: packet_size = PACKET_256B_SIZE; break; case STX_512B: packet_size = PACKET_512B_SIZE; break; case STX_1KB: case STX://为了兼容超级终端 packet_size = PACKET_1KB_SIZE; break; case STX_2KB: packet_size = PACKET_2KB_SIZE; break; case EOT: return 0; case CA: if ((Receive_Byte(&c, timeout) == 0) && (c == CA)) { *length = -1; return 0; } else { return -1; } case ABORT1: case ABORT2: return 1; default: return -1; } *data = c; for (i = 1; i < (packet_size + PACKET_OVERHEAD); i ++) { if (Receive_Byte(data + i, timeout) != 0) { return -1; } } if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff)) { return -1; } *length = packet_size; return 0; }
/* 接收一包数据 参数分别为 数据缓存 一包长度 超时时间 */ int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout) { uint16_t i, packet_size; //一包数据长度 uint8_t c; //接收一个字符的临时保存变量 crcvalue = 0; *length = 0; if (Receive_Byte(&c, timeout) != 0) { return -1; //如果在规定时间 没有字符传过来 就直接退出该函数 } //如果接收到一个字符了 说明收到一个串口命令 判断是什么命令 switch (c) { case 0x01://设置包长度为128字节命令 /* start of 128-byte data packet */ packet_size=128; break; // case 0x02://设置包长度为1024字节命令 /* start of 1024-byte data packet */ // packet_size=1024; // break; case 0x04:// 传输结束命令 /* end of transmission */ __NOP(); return 0; // break; case 0x18://传输成功后的结束命令 /* two of these in succession aborts transfer */ if ((Receive_Byte(&c, timeout) == 0) && (c == 0x18)) //接收到一个字符 并且收到结束命令 { *length = -1;//长度 return 0; //正常退出 } else { return -1; // 异常退出 } case 0x41: /* 'A' == 0x41, abort by user */ case 0x61: /* 'a' == 0x61, abort by user */ return 1; default: return -1; } *data = c; //保存收到的字符c for (i=1; i<(packet_size + 5); i ++) /* 接收一包的数据 (包括数据包头的3 + 数据包尾2) */ { if (Receive_Byte(data + i, timeout) != 0) /* 数据保存在data数组中 */ { return -1; } } //包头校验 if (data[1] != ((data[2] ^ 0xff) & 0xff)) //data[1] 中的数据必须等于data[2] 中的数据取反 { return -1; } //CRC校验 crcvalue = (data[132] | (data[131]<<8)); if (Cal_CRC16(&data[3], 128) != crcvalue) /* 将data数组中,其中128个纯数据取出做CRC校验 */ { return -1; //如果校验失败,则终止接收 } *length = packet_size; return 0; }