• HC32F120开发之IAP


            之前做过STM32F107的 UART IAP功能,是使用ST官方提供的bootloader程序,官方的例程是基于YMODE协议进行固件传输的。但是HDSC官方没有提供UART IAP的例程,现将ST官方bootloader例程中关键代码移植到HC32F120的工程中。

    1.新建一个HC32F120H6的基础工程

    过程略。

    2.划分Flash区域

    HC32F120H6的FLASH总容量为32KB,一个扇区512字节,总共64个扇区。

    ------------------------------------------
    -               BootLoader              -
    -                    12kB                   -
    -                                               -
    -------------0x00003000-------------
    -               Boot Param              -
    -                   512B                     -
    -------------0x00003200-------------
    -               User Code                -
    -                 18.5kB                    -
    -                                                -
    -                                                -
    -------------0x00007C00-------------
    -               User Param               -
    -                   1kB                        -
    -------------------------------------------

    3.移植文件

            将ST bootloader例程下的ymodem.c、ymodem.h、flash_if.c、flash_if.h、common.c、common.h、menu.c、menu.h移植到HC32F120H6工程下。

    flash_if.c文件主要是一些对flash进行读、写、擦除的接口函数,需要根据HC32F120的flash驱动函数进行修改。修改之后的flash_if.c代码如下:

    1. /* Includes ------------------------------------------------------------------*/
    2. #include "flash_if.h"
    3. /* Private typedef -----------------------------------------------------------*/
    4. /* Private define ------------------------------------------------------------*/
    5. /* Private macro -------------------------------------------------------------*/
    6. /* Private variables ---------------------------------------------------------*/
    7. /* Private function prototypes -----------------------------------------------*/
    8. /* Private functions ---------------------------------------------------------*/
    9. /**
    10. * @brief Unlocks Flash for write access
    11. * @param None
    12. * @retval None
    13. */
    14. void FLASH_If_Init(void)
    15. {
    16. /* Unlock the Program memory */
    17. EFM_Unlock();
    18. /* Clear all FLASH flags */
    19. EFM_ClearFlag(EFM_FLAG_CLR_OPTEND | EFM_FLAG_CLR_PEPRTERR | EFM_FLAG_CLR_PEWERR);
    20. /* Unlock the Program memory */
    21. EFM_Lock();
    22. }
    23. /**
    24. * @brief This function does an erase of all user flash area
    25. * @param start: start of user flash area
    26. * @retval FLASHIF_OK : user flash area successfully erased
    27. * FLASHIF_ERASEKO : error occurred
    28. */
    29. uint32_t FLASH_If_Erase(uint32_t start)
    30. {
    31. uint32_t NbrOfPages = 0;
    32. uint32_t PageError = 0;
    33. en_result_t result = Ok;
    34. /* Unlock the Flash to enable the flash control register access *************/
    35. EFM_Unlock();
    36. /* Get the sector where start the user flash area */
    37. uint32_t StartAddr = start/FLASH_PAGE_STEP * FLASH_PAGE_STEP;
    38. NbrOfPages = (USER_FLASH_END_ADDRESS - StartAddr)/FLASH_PAGE_STEP;
    39. for( uint16_t i = 0; i < NbrOfPages; i++ )
    40. {
    41. if( EFM_SectorErase( StartAddr + i*FLASH_PAGE_STEP ) != Ok )
    42. {
    43. result = Error;
    44. break;
    45. }
    46. }
    47. /* Lock the Flash to disable the flash control register access (recommended
    48. to protect the FLASH memory against possible unwanted operation) *********/
    49. EFM_Lock();
    50. if (result != Ok)
    51. {
    52. /* Error occurred while page erase */
    53. return FLASHIF_ERASEKO;
    54. }
    55. return FLASHIF_OK;
    56. }
    57. /* Public functions ---------------------------------------------------------*/
    58. /**
    59. * @brief This function writes a data buffer in flash (data are 32-bit aligned).
    60. * @note After writing data buffer, the flash content is checked.
    61. * @param destination: start address for target location
    62. * @param p_source: pointer on buffer with data to write
    63. * @param length: length of data buffer (unit is 32-bit word)
    64. * @retval uint32_t 0: Data successfully written to Flash memory
    65. * 1: Error occurred while writing data in Flash memory
    66. * 2: Written Data in flash memory is different from expected one
    67. */
    68. uint32_t FLASH_If_Write(uint32_t destination, uint32_t *p_source, uint32_t length)
    69. {
    70. uint32_t i = 0;
    71. /* Unlock the Flash to enable the flash control register access *************/
    72. EFM_Unlock();
    73. for (i = 0; (i < length) && (destination <= (USER_FLASH_END_ADDRESS-4)); i++)
    74. {
    75. /* Device voltage range supposed to be [2.7V to 3.6V], the operation will
    76. be done by word */
    77. if( EFM_ProgramWord( destination, *(uint32_t*)(p_source+i) ) == Ok )
    78. {
    79. /* Check the written value */
    80. if (*(uint32_t*)destination != *(uint32_t*)(p_source+i))
    81. {
    82. /* Flash content doesn't match SRAM content */
    83. return(FLASHIF_WRITINGCTRL_ERROR);
    84. }
    85. /* Increment FLASH destination address */
    86. destination += 4;
    87. }
    88. else
    89. {
    90. /* Error occurred while writing data in Flash memory */
    91. return (FLASHIF_WRITING_ERROR);
    92. }
    93. }
    94. /* Lock the Flash to disable the flash control register access (recommended
    95. to protect the FLASH memory against possible unwanted operation) *********/
    96. EFM_Lock();
    97. return (FLASHIF_OK);
    98. }

    修改之后的flash_if.h代码如下:

    1. /* Define to prevent recursive inclusion -------------------------------------*/
    2. #ifndef __FLASH_IF_H
    3. #define __FLASH_IF_H
    4. /* Includes ------------------------------------------------------------------*/
    5. #include "hc32_ddl.h"
    6. /* Exported types ------------------------------------------------------------*/
    7. /* Exported constants --------------------------------------------------------*/
    8. /* Error code */
    9. enum
    10. {
    11. FLASHIF_OK = 0,
    12. FLASHIF_ERASEKO,
    13. FLASHIF_WRITINGCTRL_ERROR,
    14. FLASHIF_WRITING_ERROR,
    15. FLASHIF_PROTECTION_ERRROR
    16. };
    17. /* protection type */
    18. enum{
    19. FLASHIF_PROTECTION_NONE = 0,
    20. FLASHIF_PROTECTION_PCROPENABLED = 0x1,
    21. FLASHIF_PROTECTION_WRPENABLED = 0x2,
    22. FLASHIF_PROTECTION_RDPENABLED = 0x4,
    23. };
    24. /* protection update */
    25. enum {
    26. FLASHIF_WRP_ENABLE,
    27. FLASHIF_WRP_DISABLE
    28. };
    29. /* Define the address from where user application will be loaded.
    30. Note: this area is reserved for the IAP code */
    31. #define FLASH_PAGE_STEP 0x200 /* Size of page : 2 Kbytes */
    32. #define APPLICATION_ADDRESS (uint32_t)0x00003200 /* Start user code address: ADDR_FLASH_PAGE_8 */
    33. /* Notable Flash addresses */
    34. #define USER_FLASH_END_ADDRESS 0x00007C00
    35. /* Define the user application size */
    36. #define USER_FLASH_SIZE ((uint32_t)0x00004A00) /* Small default template application */
    37. /* Define bitmap representing user flash area that could be write protected (check restricted to pages 8-39). */
    38. #define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES8TO9 | OB_WRP_PAGES10TO11 | OB_WRP_PAGES12TO13 | OB_WRP_PAGES14TO15 | \
    39. OB_WRP_PAGES16TO17 | OB_WRP_PAGES18TO19 | OB_WRP_PAGES20TO21 | OB_WRP_PAGES22TO23 | \
    40. OB_WRP_PAGES24TO25 | OB_WRP_PAGES26TO27 | OB_WRP_PAGES28TO29 | OB_WRP_PAGES30TO31 | \
    41. OB_WRP_PAGES32TO33 | OB_WRP_PAGES34TO35 | OB_WRP_PAGES36TO37 | OB_WRP_PAGES38TO39 )
    42. /* Exported macro ------------------------------------------------------------*/
    43. /* ABSoulute value */
    44. #define ABS_RETURN(x,y) ((x) < (y)) ? ((y)-(x)) : ((x)-(y))
    45. /* Get the number of sectors from where the user program will be loaded */
    46. #define FLASH_SECTOR_NUMBER ((uint32_t)(ABS_RETURN(APPLICATION_ADDRESS,FLASH_START_BANK1))>>12)
    47. /* Compute the mask to test if the Flash memory, where the user program will be
    48. loaded, is write protected */
    49. #define FLASH_PROTECTED_SECTORS (~(uint32_t)((1 << FLASH_SECTOR_NUMBER) - 1))
    50. /* Exported functions ------------------------------------------------------- */
    51. void FLASH_If_Init(void);
    52. uint32_t FLASH_If_Erase(uint32_t StartSector);
    53. uint32_t FLASH_If_GetWriteProtectionStatus(void);
    54. uint32_t FLASH_If_Write(uint32_t destination, uint32_t *p_source, uint32_t length);
    55. uint32_t FLASH_If_WriteProtectionConfig(uint32_t modifier);
    56. #endif /* __FLASH_IF_H */

    common.c为字符类的转换函数,不用修改。common.h只需将包含的头文件修改下即可。

    新增ymodem_uart.c、ymodem_uart.h文件,主要是UART相关的功能函数,发送、接收、初始化。STM32F10x例程里UART功能函数时调用HAL库编写的,用到了中断接收以及接收数据缓存。HC32F120没有HAL库,所以这部分的改动比较大。UART的发送我使用阻塞模式发送,接收使用中断模式+RIngBuffer的方式,就是接收一直开启,接收的到的数据放在buffer里,应用程序从buffer里读出数据,buffer的大小为1500B,ymodem 1k size一包数据为1030字节。ymodem函数中用到的uart接收函数的参数有一个是接收超时时间,我在uart的接收功能函数中用了SysTick的时钟节拍来判断接收超时,当没有读取到足够的长度,并且buffer一直为空且超过一定的节拍数就认定为超时,函数立即返回。ymodem_uart.c代码如下:

    1. /**
    2. ******************************************************************************
    3. * File Name : uartDebug.c
    4. * Description : Code for net applications
    5. ******************************************************************************
    6. */
    7. /* includes ------------------------------------------------------------------*/
    8. #include "stdbool.h"
    9. #include "stdint.h"
    10. #include "string.h"
    11. #include "hc32_ddl.h"
    12. #include "ymodem_uart.h"
    13. /* typedef -------------------------------------------------------------------*/
    14. /* define --------------------------------------------------------------------*/
    15. /* UART RX/TX Port/Pin definition */
    16. #define UART_RX_PORT (GPIO_PORT_1)
    17. #define UART_RX_PIN (GPIO_PIN_4) /* P11: USART3_RX */
    18. #define UART_TX_PORT (GPIO_PORT_1)
    19. #define UART_TX_PIN (GPIO_PIN_3) /* P12: USART3_TX */
    20. /* UART unit definition */
    21. #define UART_UNIT (M0P_USART3)
    22. /* UART unit interrupt definition */
    23. #define UART_UNIT_ERR_INT (INT_USART_3_EI)
    24. #define UART_UNIT_ERR_IRQn (Int013_IRQn)
    25. #define UART_UNIT_RX_INT (INT_USART_3_RI)
    26. #define UART_UNIT_RX_IRQn (Int015_IRQn)
    27. /* Function clock gate definition */
    28. #define FUNCTION_CLK_GATE (CLK_FCG_UART3)
    29. #define IS_RING_BUFFER_EMPTY(x) (0U == ((x)->u16UsedSize))
    30. /* macro ---------------------------------------------------------------------*/
    31. /* variables -----------------------------------------------------------------*/
    32. static stc_ring_buffer_t m_stcRingBuf = {
    33. .u16InIdx = 0,
    34. .u16OutIdx = 0,
    35. .u16UsedSize = 0,
    36. .u16Capacity = RING_BUFFER_SIZE,
    37. };
    38. static uint8_t m_u8Status = 0U;
    39. /* function prototypes -------------------------------------------------------*/
    40. static void UartErrIrqCallback(void);
    41. static void UartRxIrqCallback(void);
    42. static en_result_t RingBufWrite(stc_ring_buffer_t *pstcBuffer, uint8_t u8Data);
    43. static en_result_t RingBufRead(stc_ring_buffer_t *pstcBuffer, uint8_t *pu8Data);
    44. /**
    45. * @brief : None.
    46. * @param : None.
    47. * @retval : None.
    48. */
    49. bool ymodemUartInit( void )
    50. {
    51. stc_irq_regi_config_t stcIrqRegiConf;
    52. const stc_uart_init_t stcUartInit = {
    53. .u32Baudrate = 57600UL,
    54. .u32ClkPrescaler = USART_CLK_PRESCALER_DIV1,
    55. .u32BitDirection = USART_LSB,
    56. .u32StopBit = USART_STOP_BITS_1,
    57. .u32Parity = USART_PARITY_NONE,
    58. .u32DataWidth = USART_DATA_WIDTH_BITS_8,
    59. .u32ClkMode = USART_INTCLK_NONE_OUTPUT,
    60. .u32OversamplingBits = USART_OVERSAMPLING_BITS_8,
    61. .u32NoiseFilterState = USART_NOISE_FILTER_DISABLE,
    62. .u32SbDetectPolarity = USART_SB_DETECT_FALLING,
    63. };
    64. CLK_FcgPeriphClockCmd(FUNCTION_CLK_GATE, Enable);
    65. /* Configure USART RX/TX pin. */
    66. GPIO_SetFunc(UART_RX_PORT, UART_RX_PIN, GPIO_FUNC_3_USART1);
    67. GPIO_SetFunc(UART_TX_PORT, UART_TX_PIN, GPIO_FUNC_3_USART1);
    68. /* Enable peripheral clock */
    69. CLK_FcgPeriphClockCmd(FUNCTION_CLK_GATE, Enable);
    70. /* Initialize UART function. */
    71. if (Ok != USART_UartInit(UART_UNIT, &stcUartInit))
    72. {
    73. return false;
    74. }
    75. /* Register error IRQ handler && configure NVIC. */
    76. stcIrqRegiConf.enIRQn = UART_UNIT_ERR_IRQn;
    77. stcIrqRegiConf.enIntSrc = UART_UNIT_ERR_INT;
    78. stcIrqRegiConf.pfnCallback = &UartErrIrqCallback;
    79. INTC_IrqRegistration(&stcIrqRegiConf);
    80. NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);
    81. NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_03);
    82. NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);
    83. /* Register RX IRQ handler && configure NVIC. */
    84. stcIrqRegiConf.enIRQn = UART_UNIT_RX_IRQn;
    85. stcIrqRegiConf.enIntSrc = UART_UNIT_RX_INT;
    86. stcIrqRegiConf.pfnCallback = &UartRxIrqCallback;
    87. INTC_IrqRegistration(&stcIrqRegiConf);
    88. NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);
    89. NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_03);
    90. NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);
    91. m_stcRingBuf.u16InIdx = 0,
    92. m_stcRingBuf.u16OutIdx = 0,
    93. m_stcRingBuf.u16UsedSize = 0,
    94. m_stcRingBuf.u16Capacity = RING_BUFFER_SIZE;
    95. /* Enable RX function */
    96. USART_FuncCmd(UART_UNIT, ( USART_TX | USART_RX | USART_INT_RX ), Enable);
    97. return true;
    98. }
    99. /**
    100. * @brief USART error IRQ callback.
    101. * @param None
    102. * @retval None
    103. */
    104. static void UartErrIrqCallback( void )
    105. {
    106. USART_ClearFlag(UART_UNIT, (USART_CLEAR_FLAG_PE | USART_CLEAR_FLAG_FE | USART_CLEAR_FLAG_ORE));
    107. }
    108. /**
    109. * @brief USART RX IRQ callback
    110. * @param None
    111. * @retval None
    112. */
    113. static void UartRxIrqCallback(void)
    114. {
    115. uint16_t u16Data = USART_RecData(UART_UNIT);
    116. RingBufWrite(&m_stcRingBuf, (uint8_t)u16Data);
    117. }
    118. /**
    119. * @brief Write ring buffer.
    120. * @param [in] pstcBuffer Pointer to a @ref stc_ring_buffer_t structure
    121. * @param [in] u8Data Data to write
    122. * @retval An en_result_t enumeration value:
    123. * - Ok: Write success.
    124. * - ErrorBufferFull: Buffer is full.
    125. */
    126. static en_result_t RingBufWrite(stc_ring_buffer_t *pstcBuffer, uint8_t u8Data)
    127. {
    128. en_result_t enRet = Ok;
    129. if (pstcBuffer->u16UsedSize >= pstcBuffer->u16Capacity)
    130. {
    131. enRet = ErrorBufferFull;
    132. }
    133. else
    134. {
    135. pstcBuffer->au8Buf[pstcBuffer->u16InIdx++] = u8Data;
    136. pstcBuffer->u16InIdx %= pstcBuffer->u16Capacity;
    137. pstcBuffer->u16UsedSize++;
    138. }
    139. return enRet;
    140. }
    141. /**
    142. * @brief Write ring buffer.
    143. * @param [in] pstcBuffer Pointer to a @ref stc_ring_buffer_t structure
    144. * @param [in] pu8Data Pointer to data buffer to read
    145. * @retval An en_result_t enumeration value:
    146. * - Ok: Write success.
    147. * - ErrorNotReady: Buffer is empty.
    148. */
    149. static en_result_t RingBufRead(stc_ring_buffer_t *pstcBuffer, uint8_t *pu8Data)
    150. {
    151. en_result_t enRet = Ok;
    152. if (!pstcBuffer->u16UsedSize)
    153. {
    154. enRet = ErrorNotReady;
    155. }
    156. else
    157. {
    158. *pu8Data = pstcBuffer->au8Buf[pstcBuffer->u16OutIdx++];
    159. pstcBuffer->u16OutIdx %= pstcBuffer->u16Capacity;
    160. pstcBuffer->u16UsedSize--;
    161. }
    162. return enRet;
    163. }
    164. /**
    165. * @brief Receives an amount of data in blocking mode.
    166. * @param pData: Pointer to data buffer
    167. * @param Size: Amount of data to be received
    168. * @param Timeout: Timeout duration
    169. * @retval : None.
    170. */
    171. en_result_t ymodemUartReceive( uint8_t *pData, uint16_t Size, uint32_t Timeout )
    172. {
    173. uint32_t tickstart = 0;
    174. uint8_t u8Data = 0U;
    175. /* Get tick */
    176. tickstart = SysTick_GetTick();
    177. while( ( Size > 0 ) && ((SysTick_GetTick() - tickstart ) < Timeout) )
    178. {
    179. if( RingBufRead(&m_stcRingBuf, &u8Data) == Ok )
    180. {
    181. *pData = u8Data;
    182. pData++;
    183. Size --;
    184. tickstart = SysTick_GetTick();
    185. }
    186. }
    187. if( Size > 0 )
    188. {
    189. return ErrorTimeout;
    190. }
    191. return Ok;
    192. }
    193. /**
    194. * @brief Receives an amount of data in blocking mode.
    195. * @param pData: Pointer to data buffer
    196. * @param Size: Amount of data to be received
    197. * @param Timeout: Timeout duration
    198. * @retval : None.
    199. */
    200. en_result_t ymodemUartTransmit( uint8_t *pData, uint16_t Size, uint32_t Timeout )
    201. {
    202. uint32_t tickstart = 0;
    203. /* Get tick */
    204. tickstart = SysTick_GetTick();
    205. while( ( Size > 0 ) && ((SysTick_GetTick() - tickstart ) < Timeout))
    206. {
    207. if( USART_GetFlag( UART_UNIT, USART_FLAG_TXE ) == Set )
    208. {
    209. USART_SendData(UART_UNIT, (uint16_t)(*pData));
    210. pData++;
    211. Size --;
    212. tickstart = SysTick_GetTick();
    213. }
    214. }
    215. if( Size > 0 )
    216. {
    217. return ErrorTimeout;
    218. }
    219. return Ok;
    220. }

    ymodem_uart.h代码如下:

    1. #ifndef __YMODEM_UART_H
    2. #define __YMODEM_UART_H
    3. #ifdef __cplusplus
    4. extern "C" {
    5. #endif
    6. /* Includes ------------------------------------------------------------------*/
    7. #include "stdint.h"
    8. #include "stdbool.h"
    9. #include "hc32_ddl.h"
    10. /* Private includes ----------------------------------------------------------*/
    11. /* Exported types ------------------------------------------------------------*/
    12. /* Private defines -----------------------------------------------------------*/
    13. /* Ring buffer size */
    14. #define RING_BUFFER_SIZE (1500U)
    15. #define IS_RING_BUFFER_EMPTY(x) (0U == ((x)->u16UsedSize))
    16. /* Exported constants --------------------------------------------------------*/
    17. /* Exported macro ------------------------------------------------------------*/
    18. /* Exported variable prototypes ----------------------------------------------*/
    19. typedef struct
    20. {
    21. uint16_t u16Capacity;
    22. __IO uint16_t u16UsedSize;
    23. uint16_t u16InIdx;
    24. uint16_t u16OutIdx;
    25. uint8_t au8Buf[RING_BUFFER_SIZE];
    26. } stc_ring_buffer_t;
    27. /* Exported functions prototypes ---------------------------------------------*/
    28. bool ymodemUartInit( void );
    29. en_result_t ymodemUartReceive( uint8_t *pData, uint16_t Size, uint32_t Timeout );
    30. en_result_t ymodemUartTransmit( uint8_t *pData, uint16_t Size, uint32_t Timeout );
    31. #ifdef __cplusplus
    32. }
    33. #endif
    34. #endif /* __YMODEM_UART_H */

    menu.c为控制下载过程的代码,只需做少量的修改,替换UART发送和接收函数即可。

    ymodem.c为ymodem协议相关的一些发送、接收、解析、封包函数,改动比较小,替换UART发送和接收函数、修改超时相关参数的值,因为时间单位变了。

    4.编写main.c

            初始化SysTick,节拍周期1ms,如果上电时KEY被按下,则进入下载模式,否则跳转到应用程序。

    1. /*******************************************************************************
    2. * Include files
    3. ******************************************************************************/
    4. #include "string.h"
    5. #include "hc32_ddl.h"
    6. #include "led.h"
    7. #include "gpioinput.h"
    8. #include "board.h"
    9. #include "menu.h"
    10. #include "ymodem_uart.h"
    11. #include "flash_if.h"
    12. /**
    13. * @addtogroup HC32F120_DDL_Examples
    14. * @{
    15. */
    16. /**
    17. * @addtogroup Templates
    18. * @{
    19. */
    20. /*******************************************************************************
    21. * Local type definitions ('typedef')
    22. ******************************************************************************/
    23. /*******************************************************************************
    24. * Local pre-processor symbols/macros ('#define')
    25. ******************************************************************************/
    26. /*******************************************************************************
    27. * Global variable definitions (declared in header file with 'extern')
    28. ******************************************************************************/
    29. static pFunction JumpToApplication;
    30. static uint32_t JumpAddress;
    31. /*******************************************************************************
    32. * Local function prototypes ('static')
    33. ******************************************************************************/
    34. static void SystemClockConfig(void);
    35. /*******************************************************************************
    36. * Local variable definitions ('static')
    37. ******************************************************************************/
    38. /*******************************************************************************
    39. * Function implementation - global ('extern') and local ('static')
    40. ******************************************************************************/
    41. /**
    42. * @brief Main function of template project
    43. * @param None
    44. * @retval int32_t return value, if needed
    45. */
    46. int32_t main(void)
    47. {
    48. uint32_t RunCnt = 0;
    49. /* Add your code here */
    50. DDL_PrintfInit( );
    51. SysTick_Init( 1000 );
    52. BoardInit( );
    53. gpioInputInit( );
    54. LedInit( );
    55. uint8_t keyCheckCnt;
    56. for( keyCheckCnt = 0;keyCheckCnt < 10; keyCheckCnt++ )
    57. {
    58. DDL_Delay1ms( 10 );
    59. if( gpioInputLowDetect( KEY_INPUT ) == true )
    60. {
    61. keyCheckCnt++;
    62. }
    63. else
    64. {
    65. break;
    66. }
    67. }
    68. if( keyCheckCnt > 7 )
    69. {
    70. LedxOn( LED1 );
    71. LedxOn( LED3 );
    72. printf("Firmware update!\n");
    73. /* Initialise Flash */
    74. FLASH_If_Init();
    75. if( ymodemUartInit( ) == false )
    76. {
    77. printf("uartUpgradeInit fail!\n");
    78. }
    79. /* Display main menu */
    80. Main_Menu();
    81. }
    82. else
    83. {
    84. printf("Jump App!\r\n");
    85. /* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */
    86. if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
    87. {
    88. /* Jump to user application */
    89. JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
    90. JumpToApplication = (pFunction) JumpAddress;
    91. SysTick_Suspend();
    92. /* Initialize user application's Stack Pointer */
    93. __set_MSP( *(__IO uint32_t*) APPLICATION_ADDRESS );
    94. __set_PSP( *(__IO uint32_t*) APPLICATION_ADDRESS );
    95. __set_CONTROL(0);
    96. __disable_irq();
    97. JumpToApplication();
    98. }
    99. }
    100. if( ymodemUartInit( ) == false )
    101. {
    102. printf("uartUpgradeInit fail!\n");
    103. }
    104. while (1)
    105. {
    106. if( RunCnt ++ > 10000 )
    107. {
    108. RunCnt = 0;
    109. LedxToggle( LED1 );
    110. }
    111. }
    112. }
    113. /**
    114. * @}
    115. */
    116. /**
    117. * @}
    118. */
    119. /**
    120. * @brief Configure system clock.
    121. * @param None
    122. * @retval None
    123. */
    124. static void SystemClockConfig(void)
    125. {
    126. stc_clk_xtal_init_t stcXTALInit;
    127. /* Configure XTAL */
    128. stcXTALInit.u8XtalState = CLK_XTAL_ON;
    129. stcXTALInit.u8XtalMode = CLK_XTALMODE_OSC;
    130. stcXTALInit.u8XtalDrv = CLK_XTALDRV_HIGH;
    131. stcXTALInit.u8XtalSupDrv = CLK_XTAL_SUPDRV_OFF;
    132. stcXTALInit.u8XtalStb = CLK_XTALSTB_8;
    133. /* Initialize XTAL clock */
    134. CLK_XTALInit(&stcXTALInit);
    135. /* Switch system clock from HRC(default) to XTAL */
    136. CLK_SetSysclkSrc(CLK_SYSCLKSOURCE_XTAL);
    137. }

    5.生成应用程序BIN文件

    将应用程序的起始地址设为0x3200,大小设为0x4A00:

     添加编译指令以生成BIN文件:

     main()函数开头设置中断向量表偏移:

    1. /**
    2. * @brief Main function of template project
    3. * @param None
    4. * @retval int32_t return value, if needed
    5. */
    6. int32_t main(void)
    7. {
    8. #ifndef VECT_TAB_OFFSET
    9. SCB->VTOR = 0x00003200;
    10. #else
    11. SCB->VTOR = 0x00003200 + VECT_TAB_OFFSET;
    12. #endif
    13. ...
    14. }

    修改hc32f120_interrupts.c中void SysTick_Handler(void)函数:

    1. /**
    2. * @brief SysTick IRQ handler
    3. * @param None
    4. * @retval None
    5. */
    6. void SysTick_Handler(void)
    7. {
    8. SysTick_IrqHandler();
    9. }

    如果DDL_ICG_ENABLE定义为DDL_ON,那么还需要修改hc32f120_icg.c文件中的代码:

    1. #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
    2. const uint32_t u32ICG[] __attribute__((section(".ARM.__at_0x32C0"))) = //改
    3. #elif defined (__GNUC__) && !defined (__CC_ARM)
    4. const uint32_t u32ICG[] __attribute__((section(".icg_sec"))) =
    5. #elif defined (__CC_ARM)
    6. const uint32_t u32ICG[] __attribute__((at(0x00003200 + 0xC0))) = //改
    7. #elif defined (__ICCARM__)
    8. #pragma location = 0x00003200 + 0xC0
    9. __root static const uint32_t u32ICG[] =
    10. #else
    11. #error "unsupported compiler!!"
    12. #endif
    13. {
    14. /* ICG 0~ 3 */
    15. ICG0_REGISTER_CONSTANT,
    16. ICG1_REGISTER_CONSTANT,
    17. ICG2_REGISTER_CONSTANT,
    18. ICG3_REGISTER_CONSTANT,
    19. /* ICG 4~ 6 */
    20. ICG4_REGISTER_CONSTANT,
    21. ICG5_REGISTER_CONSTANT,
    22. ICG6_REGISTER_CONSTANT,
    23. };

    也是地址的修改,不然无法生成bin文件。

    6.升级固件

    上位机使用的SecureCRT 8工具:

     波特率57600,之前用115200,下载过程会出错,目前还未找到问题。

    源代码下载。

  • 相关阅读:
    ​7.1 项目1 学生通讯录管理:文本文件增删改查(C++版本)(自顶向下设计+断点调试) (A)​
    JavaScript之数组操作增删改、冒泡排序
    【宠物用品】宠物饮水机方案
    【Go】单例模式与Once源码
    Mybatis的动态SQL和分页
    基于Java+Spring+vue+element社区疫情服务平台设计和实现
    Stable Diffusion 模型分享:CG texture light and shadow(CG纹理光影)
    pnpm 升级
    k8s暴露集群内和集群外服务的方法
    如何安装GCC?
  • 原文地址:https://blog.csdn.net/professionalmcu/article/details/126272883