|
发表于 2019-1-13 18:40:10
|
显示全部楼层
随便传一个STM32CubeMX\Repository\STM32Cube_FW_F1_V1.7.0\Projects\STM3210C_EVAL\Applications\IAP\IAP_Main\Src\ymodem.c
其它F4,F7的都一样错:
- /**
- ******************************************************************************
- * @file IAP_Main/Src/ymodem.c
- * @author MCD Application Team
- * @version V1.6.0
- * @date 12-May-2017
- * @brief This file provides all the software functions related to the ymodem
- * protocol.
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright ?2016 STMicroelectronics International N.V.
- * All rights reserved.</center></h2>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted, provided that the following conditions are met:
- *
- * 1. Redistribution of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of other
- * contributors to this software may be used to endorse or promote products
- * derived from this software without specific written permission.
- * 4. This software, including modifications and/or derivative works of this
- * software, must execute solely and exclusively on microcontroller or
- * microprocessor devices manufactured by or for STMicroelectronics.
- * 5. Redistribution and use of this software other than as permitted under
- * this license is void and will automatically terminate your rights under
- * this license.
- *
- * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
- * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
- * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
- /** @addtogroup STM32F1xx_IAP
- * @{
- */
-
- /* Includes ------------------------------------------------------------------*/
- #include "flash_if.h"
- #include "common.h"
- #include "ymodem.h"
- #include "string.h"
- #include "main.h"
- #include "menu.h"
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- #define CRC16_F /* activate the CRC16 integrity */
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- /* @note ATTENTION - please keep this variable 32bit alligned */
- uint8_t aPacketData[PACKET_1K_SIZE + PACKET_DATA_INDEX + PACKET_TRAILER_SIZE];
- /* Private function prototypes -----------------------------------------------*/
- static void PrepareIntialPacket(uint8_t *p_data, const uint8_t *p_file_name, uint32_t length);
- static void PreparePacket(uint8_t *p_source, uint8_t *p_packet, uint8_t pkt_nr, uint32_t size_blk);
- static HAL_StatusTypeDef ReceivePacket(uint8_t *p_data, uint32_t *p_length, uint32_t timeout);
- uint16_t UpdateCRC16(uint16_t crc_in, uint8_t byte);
- uint16_t Cal_CRC16(const uint8_t* p_data, uint32_t size);
- uint8_t CalcChecksum(const uint8_t *p_data, uint32_t size);
- /* Private functions ---------------------------------------------------------*/
- /**
- * @brief Receive a packet from sender
- * @param data
- * @param length
- * 0: end of transmission
- * 2: abort by sender
- * >0: packet length
- * @param timeout
- * @retval HAL_OK: normally return
- * HAL_BUSY: abort by user
- */
- static HAL_StatusTypeDef ReceivePacket(uint8_t *p_data, uint32_t *p_length, uint32_t timeout)
- {
- uint32_t crc;
- uint32_t packet_size = 0;
- HAL_StatusTypeDef status;
- uint8_t char1;
- *p_length = 0;
- status = HAL_UART_Receive(&UartHandle, &char1, 1, timeout);
- if (status == HAL_OK)
- {
- switch (char1)
- {
- case SOH:
- packet_size = PACKET_SIZE;
- break;
- case STX:
- packet_size = PACKET_1K_SIZE;
- break;
- case EOT:
- break;
- case CA:
- if ((HAL_UART_Receive(&UartHandle, &char1, 1, timeout) == HAL_OK) && (char1 == CA))
- {
- packet_size = 2;
- }
- else
- {
- status = HAL_ERROR;
- }
- break;
- case ABORT1:
- case ABORT2:
- status = HAL_BUSY;
- break;
- default:
- status = HAL_ERROR;
- break;
- }
- *p_data = char1;
- if (packet_size >= PACKET_SIZE )
- {
- status = HAL_UART_Receive(&UartHandle, &p_data[PACKET_NUMBER_INDEX], packet_size + PACKET_OVERHEAD_SIZE, timeout);
- /* Simple packet sanity check */
- if (status == HAL_OK )
- {
- if (p_data[PACKET_NUMBER_INDEX] != ((p_data[PACKET_CNUMBER_INDEX]) ^ NEGATIVE_BYTE))
- {
- packet_size = 0;
- status = HAL_ERROR;
- }
- else
- {
- /* Check packet CRC */
- crc = p_data[ packet_size + PACKET_DATA_INDEX ] << 8;
- crc += p_data[ packet_size + PACKET_DATA_INDEX + 1 ];
- if (Cal_CRC16(&p_data[PACKET_DATA_INDEX], packet_size) != crc )
- {
- packet_size = 0;
- status = HAL_ERROR;
- }
- }
- }
- else
- {
- packet_size = 0;
- }
- }
- }
- *p_length = packet_size;
- return status;
- }
- /**
- * @brief Prepare the first block
- * @param p_data: output buffer
- * @param p_file_name: name of the file to be sent
- * @param length: length of the file to be sent in bytes
- * @retval None
- */
- static void PrepareIntialPacket(uint8_t *p_data, const uint8_t *p_file_name, uint32_t length)
- {
- uint32_t i, j = 0;
- uint8_t astring[10];
- /* first 3 bytes are constant */
- p_data[PACKET_START_INDEX] = SOH;
- p_data[PACKET_NUMBER_INDEX] = 0x00;
- p_data[PACKET_CNUMBER_INDEX] = 0xff;
- /* Filename written */
- for (i = 0; (p_file_name[i] != '\0') && (i < FILE_NAME_LENGTH); i++)
- {
- p_data[i + PACKET_DATA_INDEX] = p_file_name[i];
- }
- p_data[i + PACKET_DATA_INDEX] = 0x00;
- /* file size written */
- Int2Str (astring, length);
- i = i + PACKET_DATA_INDEX + 1;
- while (astring[j] != '\0')
- {
- p_data[i++] = astring[j++];
- }
- /* padding with zeros */
- for (j = i; j < PACKET_SIZE + PACKET_DATA_INDEX; j++)
- {
- p_data[j] = 0;
- }
- }
- /**
- * @brief Prepare the data packet
- * @param p_source: pointer to the data to be sent
- * @param p_packet: pointer to the output buffer
- * @param pkt_nr: number of the packet
- * @param size_blk: length of the block to be sent in bytes
- * @retval None
- */
- static void PreparePacket(uint8_t *p_source, uint8_t *p_packet, uint8_t pkt_nr, uint32_t size_blk)
- {
- uint8_t *p_record;
- uint32_t i, size, packet_size;
- /* Make first three packet */
- packet_size = size_blk >= PACKET_1K_SIZE ? PACKET_1K_SIZE : PACKET_SIZE;
- size = size_blk < packet_size ? size_blk : packet_size;
- if (packet_size == PACKET_1K_SIZE)
- {
- p_packet[PACKET_START_INDEX] = STX;
- }
- else
- {
- p_packet[PACKET_START_INDEX] = SOH;
- }
- p_packet[PACKET_NUMBER_INDEX] = pkt_nr;
- p_packet[PACKET_CNUMBER_INDEX] = (~pkt_nr);
- p_record = p_source;
- /* Filename packet has valid data */
- for (i = PACKET_DATA_INDEX; i < size + PACKET_DATA_INDEX;i++)
- {
- p_packet[i] = *p_record++;
- }
- if ( size <= packet_size)
- {
- for (i = size + PACKET_DATA_INDEX; i < packet_size + PACKET_DATA_INDEX; i++)
- {
- p_packet[i] = 0x1A; /* EOF (0x1A) or 0x00 */
- }
- }
- }
- /**
- * @brief Update CRC16 for input byte
- * @param crc_in input value
- * @param input byte
- * @retval None
- */
- uint16_t UpdateCRC16(uint16_t crc_in, uint8_t byte)
- {
- uint32_t crc = crc_in;
- uint32_t in = byte | 0x100;
- do
- {
- crc <<= 1;
- in <<= 1;
- if(in & 0x100)
- ++crc;
- if(crc & 0x10000)
- crc ^= 0x1021;
- }
-
- while(!(in & 0x10000));
- return crc & 0xffffu;
- }
- /**
- * @brief Cal CRC16 for YModem Packet
- * @param data
- * @param length
- * @retval None
- */
- uint16_t Cal_CRC16(const uint8_t* p_data, uint32_t size)
- {
- uint32_t crc = 0;
- const uint8_t* dataEnd = p_data+size;
- while(p_data < dataEnd)
- crc = UpdateCRC16(crc, *p_data++);
-
- crc = UpdateCRC16(crc, 0);
- crc = UpdateCRC16(crc, 0);
- return crc&0xffffu;
- }
- /**
- * @brief Calculate Check sum for YModem Packet
- * @param p_data Pointer to input data
- * @param size length of input data
- * @retval uint8_t checksum value
- */
- uint8_t CalcChecksum(const uint8_t *p_data, uint32_t size)
- {
- uint32_t sum = 0;
- const uint8_t *p_data_end = p_data + size;
- while (p_data < p_data_end )
- {
- sum += *p_data++;
- }
- return (sum & 0xffu);
- }
- /* Public functions ---------------------------------------------------------*/
- /**
- * @brief Receive a file using the ymodem protocol with CRC16.
- * @param p_size The size of the file.
- * @retval COM_StatusTypeDef result of reception/programming
- */
- COM_StatusTypeDef Ymodem_Receive ( uint32_t *p_size )
- {
- uint32_t i, packet_length, session_done = 0, file_done, errors = 0, session_begin = 0;
- uint32_t flashdestination, ramsource, filesize;
- uint8_t *file_ptr;
- uint8_t file_size[FILE_SIZE_LENGTH], tmp, packets_received;
- COM_StatusTypeDef result = COM_OK;
- /* Initialize flashdestination variable */
- flashdestination = APPLICATION_ADDRESS;
- while ((session_done == 0) && (result == COM_OK))
- {
- packets_received = 0;
- file_done = 0;
- while ((file_done == 0) && (result == COM_OK))
- {
- switch (ReceivePacket(aPacketData, &packet_length, DOWNLOAD_TIMEOUT))
- {
- case HAL_OK:
- errors = 0;
- switch (packet_length)
- {
- case 2:
- /* Abort by sender */
- Serial_PutByte(ACK);
- result = COM_ABORT;
- break;
- case 0:
- /* End of transmission */
- Serial_PutByte(ACK);
- file_done = 1;
- break;
- default:
- /* Normal packet */
- if (aPacketData[PACKET_NUMBER_INDEX] != packets_received)
- {
- Serial_PutByte(NAK);
- }
- else
- {
- if (packets_received == 0)
- {
- /* File name packet */
- if (aPacketData[PACKET_DATA_INDEX] != 0)
- {
- /* File name extraction */
- i = 0;
- file_ptr = aPacketData + PACKET_DATA_INDEX;
- while ( (*file_ptr != 0) && (i < FILE_NAME_LENGTH))
- {
- aFileName[i++] = *file_ptr++;
- }
- /* File size extraction */
- aFileName[i++] = '\0';
- i = 0;
- file_ptr ++;
- while ( (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH))
- {
- file_size[i++] = *file_ptr++;
- }
- file_size[i++] = '\0';
- Str2Int(file_size, &filesize);
- /* Test the size of the image to be sent */
- /* Image size is greater than Flash size */
- if (*p_size > (USER_FLASH_SIZE + 1))
- {
- /* End session */
- tmp = CA;
- HAL_UART_Transmit(&UartHandle, &tmp, 1, NAK_TIMEOUT);
- HAL_UART_Transmit(&UartHandle, &tmp, 1, NAK_TIMEOUT);
- result = COM_LIMIT;
- }
- /* erase user application area */
- FLASH_If_Erase(APPLICATION_ADDRESS);
- *p_size = filesize;
- Serial_PutByte(ACK);
- Serial_PutByte(CRC16);
- }
- /* File header packet is empty, end session */
- else
- {
- Serial_PutByte(ACK);
- file_done = 1;
- session_done = 1;
- break;
- }
- }
- else /* Data packet */
- {
- ramsource = (uint32_t) & aPacketData[PACKET_DATA_INDEX];
- /* Write received data in Flash */
- if (FLASH_If_Write(flashdestination, (uint32_t*) ramsource, packet_length/4) == FLASHIF_OK)
- {
- flashdestination += packet_length;
- Serial_PutByte(ACK);
- }
- else /* An error occurred while writing to Flash memory */
- {
- /* End session */
- Serial_PutByte(CA);
- Serial_PutByte(CA);
- result = COM_DATA;
- }
- }
- packets_received ++;
- session_begin = 1;
- }
- break;
- }
- break;
- case HAL_BUSY: /* Abort actually */
- Serial_PutByte(CA);
- Serial_PutByte(CA);
- result = COM_ABORT;
- break;
- default:
- if (session_begin > 0)
- {
- errors ++;
- }
- if (errors > MAX_ERRORS)
- {
- /* Abort communication */
- Serial_PutByte(CA);
- Serial_PutByte(CA);
- }
- else
- {
- Serial_PutByte(CRC16); /* Ask for a packet */
- }
- break;
- }
- }
- }
- return result;
- }
- /**
- * @brief Transmit a file using the ymodem protocol
- * @param p_buf: Address of the first byte
- * @param p_file_name: Name of the file sent
- * @param file_size: Size of the transmission
- * @retval COM_StatusTypeDef result of the communication
- */
- COM_StatusTypeDef Ymodem_Transmit (uint8_t *p_buf, const uint8_t *p_file_name, uint32_t file_size)
- {
- uint32_t errors = 0, ack_recpt = 0, size = 0, pkt_size;
- uint8_t *p_buf_int;
- COM_StatusTypeDef result = COM_OK;
- uint32_t blk_number = 1;
- uint8_t a_rx_ctrl[2];
- uint8_t i;
- #ifdef CRC16_F
- uint32_t temp_crc;
- #else /* CRC16_F */
- uint8_t temp_chksum;
- #endif /* CRC16_F */
- /* Prepare first block - header */
- PrepareIntialPacket(aPacketData, p_file_name, file_size);
- while (( !ack_recpt ) && ( result == COM_OK ))
- {
- /* Send Packet */
- HAL_UART_Transmit(&UartHandle, &aPacketData[PACKET_START_INDEX], PACKET_SIZE + PACKET_HEADER_SIZE, NAK_TIMEOUT);
- /* Send CRC or Check Sum based on CRC16_F */
- #ifdef CRC16_F
- temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
- Serial_PutByte(temp_crc >> 8);
- Serial_PutByte(temp_crc & 0xFF);
- #else /* CRC16_F */
- temp_chksum = CalcChecksum (&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
- Serial_PutByte(temp_chksum);
- #endif /* CRC16_F */
- /* Wait for Ack and 'C' */
- if (HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK)
- {
- if (a_rx_ctrl[0] == ACK)
- {
- ack_recpt = 1;
- }
- else if (a_rx_ctrl[0] == CA)
- {
- if ((HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == CA))
- {
- HAL_Delay( 2 );
- __HAL_UART_FLUSH_DRREGISTER(&UartHandle);
- result = COM_ABORT;
- }
- }
- }
- else
- {
- errors++;
- }
- if (errors >= MAX_ERRORS)
- {
- result = COM_ERROR;
- }
- }
- p_buf_int = p_buf;
- size = file_size;
- /* Here 1024 bytes length is used to send the packets */
- while ((size) && (result == COM_OK ))
- {
- /* Prepare next packet */
- PreparePacket(p_buf_int, aPacketData, blk_number, size);
- ack_recpt = 0;
- a_rx_ctrl[0] = 0;
- errors = 0;
- /* Resend packet if NAK for few times else end of communication */
- while (( !ack_recpt ) && ( result == COM_OK ))
- {
- /* Send next packet */
- if (size >= PACKET_1K_SIZE)
- {
- pkt_size = PACKET_1K_SIZE;
- }
- else
- {
- pkt_size = PACKET_SIZE;
- }
- HAL_UART_Transmit(&UartHandle, &aPacketData[PACKET_START_INDEX], pkt_size + PACKET_HEADER_SIZE, NAK_TIMEOUT);
-
- /* Send CRC or Check Sum based on CRC16_F */
- #ifdef CRC16_F
- temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], pkt_size);
- Serial_PutByte(temp_crc >> 8);
- Serial_PutByte(temp_crc & 0xFF);
- #else /* CRC16_F */
- temp_chksum = CalcChecksum (&aPacketData[PACKET_DATA_INDEX], pkt_size);
- Serial_PutByte(temp_chksum);
- #endif /* CRC16_F */
-
- /* Wait for Ack */
- if ((HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == ACK))
- {
- ack_recpt = 1;
- if (size > pkt_size)
- {
- p_buf_int += pkt_size;
- size -= pkt_size;
- if (blk_number == (USER_FLASH_SIZE / PACKET_1K_SIZE))
- {
- result = COM_LIMIT; /* boundary error */
- }
- else
- {
- blk_number++;
- }
- }
- else
- {
- p_buf_int += pkt_size;
- size = 0;
- }
- }
- else
- {
- errors++;
- }
- /* Resend packet if NAK for a count of 10 else end of communication */
- if (errors >= MAX_ERRORS)
- {
- result = COM_ERROR;
- }
- }
- }
- /* Sending End Of Transmission char */
- ack_recpt = 0;
- a_rx_ctrl[0] = 0x00;
- errors = 0;
- while (( !ack_recpt ) && ( result == COM_OK ))
- {
- Serial_PutByte(EOT);
- /* Wait for Ack */
- if (HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK)
- {
- if (a_rx_ctrl[0] == ACK)
- {
- ack_recpt = 1;
- }
- else if (a_rx_ctrl[0] == CA)
- {
- if ((HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == CA))
- {
- HAL_Delay( 2 );
- __HAL_UART_FLUSH_DRREGISTER(&UartHandle);
- result = COM_ABORT;
- }
- }
- }
- else
- {
- errors++;
- }
- if (errors >= MAX_ERRORS)
- {
- result = COM_ERROR;
- }
- }
- /* Empty packet sent - some terminal emulators need this to close session */
- if ( result == COM_OK )
- {
- /* Preparing an empty packet */
- aPacketData[PACKET_START_INDEX] = SOH;
- aPacketData[PACKET_NUMBER_INDEX] = 0;
- aPacketData[PACKET_CNUMBER_INDEX] = 0xFF;
- for (i = PACKET_DATA_INDEX; i < (PACKET_SIZE + PACKET_DATA_INDEX); i++)
- {
- aPacketData [i] = 0x00;
- }
- /* Send Packet */
- HAL_UART_Transmit(&UartHandle, &aPacketData[PACKET_START_INDEX], PACKET_SIZE + PACKET_HEADER_SIZE, NAK_TIMEOUT);
- /* Send CRC or Check Sum based on CRC16_F */
- #ifdef CRC16_F
- temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
- Serial_PutByte(temp_crc >> 8);
- Serial_PutByte(temp_crc & 0xFF);
- #else /* CRC16_F */
- temp_chksum = CalcChecksum (&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
- Serial_PutByte(temp_chksum);
- #endif /* CRC16_F */
- /* Wait for Ack and 'C' */
- if (HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK)
- {
- if (a_rx_ctrl[0] == CA)
- {
- HAL_Delay( 2 );
- __HAL_UART_FLUSH_DRREGISTER(&UartHandle);
- result = COM_ABORT;
- }
- }
- }
- return result; /* file transmitted successfully */
- }
- /**
- * @}
- */
- /*******************(C)COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
复制代码 |
|