/** * @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 }