之前做过STM32F107的 UART IAP功能,是使用ST官方提供的bootloader程序,官方的例程是基于YMODE协议进行固件传输的。但是HDSC官方没有提供UART IAP的例程,现将ST官方bootloader例程中关键代码移植到HC32F120的工程中。
过程略。
HC32F120H6的FLASH总容量为32KB,一个扇区512字节,总共64个扇区。
------------------------------------------
- BootLoader -
- 12kB -
- -
-------------0x00003000-------------
- Boot Param -
- 512B -
-------------0x00003200-------------
- User Code -
- 18.5kB -
- -
- -
-------------0x00007C00-------------
- User Param -
- 1kB -
-------------------------------------------
将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代码如下:
- /* Includes ------------------------------------------------------------------*/
- #include "flash_if.h"
-
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- /* Private function prototypes -----------------------------------------------*/
-
- /* Private functions ---------------------------------------------------------*/
-
- /**
- * @brief Unlocks Flash for write access
- * @param None
- * @retval None
- */
- void FLASH_If_Init(void)
- {
- /* Unlock the Program memory */
- EFM_Unlock();
-
- /* Clear all FLASH flags */
- EFM_ClearFlag(EFM_FLAG_CLR_OPTEND | EFM_FLAG_CLR_PEPRTERR | EFM_FLAG_CLR_PEWERR);
-
- /* Unlock the Program memory */
- EFM_Lock();
- }
-
- /**
- * @brief This function does an erase of all user flash area
- * @param start: start of user flash area
- * @retval FLASHIF_OK : user flash area successfully erased
- * FLASHIF_ERASEKO : error occurred
- */
- uint32_t FLASH_If_Erase(uint32_t start)
- {
- uint32_t NbrOfPages = 0;
- uint32_t PageError = 0;
- en_result_t result = Ok;
- /* Unlock the Flash to enable the flash control register access *************/
- EFM_Unlock();
-
- /* Get the sector where start the user flash area */
- uint32_t StartAddr = start/FLASH_PAGE_STEP * FLASH_PAGE_STEP;
-
- NbrOfPages = (USER_FLASH_END_ADDRESS - StartAddr)/FLASH_PAGE_STEP;
-
- for( uint16_t i = 0; i < NbrOfPages; i++ )
- {
- if( EFM_SectorErase( StartAddr + i*FLASH_PAGE_STEP ) != Ok )
- {
- result = Error;
-
- break;
- }
- }
-
- /* Lock the Flash to disable the flash control register access (recommended
- to protect the FLASH memory against possible unwanted operation) *********/
- EFM_Lock();
-
- if (result != Ok)
- {
- /* Error occurred while page erase */
- return FLASHIF_ERASEKO;
- }
-
- return FLASHIF_OK;
- }
-
- /* Public functions ---------------------------------------------------------*/
- /**
- * @brief This function writes a data buffer in flash (data are 32-bit aligned).
- * @note After writing data buffer, the flash content is checked.
- * @param destination: start address for target location
- * @param p_source: pointer on buffer with data to write
- * @param length: length of data buffer (unit is 32-bit word)
- * @retval uint32_t 0: Data successfully written to Flash memory
- * 1: Error occurred while writing data in Flash memory
- * 2: Written Data in flash memory is different from expected one
- */
- uint32_t FLASH_If_Write(uint32_t destination, uint32_t *p_source, uint32_t length)
- {
- uint32_t i = 0;
-
- /* Unlock the Flash to enable the flash control register access *************/
- EFM_Unlock();
-
- for (i = 0; (i < length) && (destination <= (USER_FLASH_END_ADDRESS-4)); i++)
- {
- /* Device voltage range supposed to be [2.7V to 3.6V], the operation will
- be done by word */
- if( EFM_ProgramWord( destination, *(uint32_t*)(p_source+i) ) == Ok )
- {
- /* Check the written value */
- if (*(uint32_t*)destination != *(uint32_t*)(p_source+i))
- {
- /* Flash content doesn't match SRAM content */
- return(FLASHIF_WRITINGCTRL_ERROR);
- }
- /* Increment FLASH destination address */
- destination += 4;
- }
- else
- {
- /* Error occurred while writing data in Flash memory */
- return (FLASHIF_WRITING_ERROR);
- }
- }
-
- /* Lock the Flash to disable the flash control register access (recommended
- to protect the FLASH memory against possible unwanted operation) *********/
- EFM_Lock();
-
- return (FLASHIF_OK);
- }
修改之后的flash_if.h代码如下:
- /* Define to prevent recursive inclusion -------------------------------------*/
- #ifndef __FLASH_IF_H
- #define __FLASH_IF_H
-
- /* Includes ------------------------------------------------------------------*/
- #include "hc32_ddl.h"
-
- /* Exported types ------------------------------------------------------------*/
- /* Exported constants --------------------------------------------------------*/
-
- /* Error code */
- enum
- {
- FLASHIF_OK = 0,
- FLASHIF_ERASEKO,
- FLASHIF_WRITINGCTRL_ERROR,
- FLASHIF_WRITING_ERROR,
- FLASHIF_PROTECTION_ERRROR
- };
-
- /* protection type */
- enum{
- FLASHIF_PROTECTION_NONE = 0,
- FLASHIF_PROTECTION_PCROPENABLED = 0x1,
- FLASHIF_PROTECTION_WRPENABLED = 0x2,
- FLASHIF_PROTECTION_RDPENABLED = 0x4,
- };
-
- /* protection update */
- enum {
- FLASHIF_WRP_ENABLE,
- FLASHIF_WRP_DISABLE
- };
-
- /* Define the address from where user application will be loaded.
- Note: this area is reserved for the IAP code */
- #define FLASH_PAGE_STEP 0x200 /* Size of page : 2 Kbytes */
- #define APPLICATION_ADDRESS (uint32_t)0x00003200 /* Start user code address: ADDR_FLASH_PAGE_8 */
-
- /* Notable Flash addresses */
- #define USER_FLASH_END_ADDRESS 0x00007C00
-
- /* Define the user application size */
- #define USER_FLASH_SIZE ((uint32_t)0x00004A00) /* Small default template application */
-
- /* Define bitmap representing user flash area that could be write protected (check restricted to pages 8-39). */
- #define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES8TO9 | OB_WRP_PAGES10TO11 | OB_WRP_PAGES12TO13 | OB_WRP_PAGES14TO15 | \
- OB_WRP_PAGES16TO17 | OB_WRP_PAGES18TO19 | OB_WRP_PAGES20TO21 | OB_WRP_PAGES22TO23 | \
- OB_WRP_PAGES24TO25 | OB_WRP_PAGES26TO27 | OB_WRP_PAGES28TO29 | OB_WRP_PAGES30TO31 | \
- OB_WRP_PAGES32TO33 | OB_WRP_PAGES34TO35 | OB_WRP_PAGES36TO37 | OB_WRP_PAGES38TO39 )
-
-
- /* Exported macro ------------------------------------------------------------*/
- /* ABSoulute value */
- #define ABS_RETURN(x,y) ((x) < (y)) ? ((y)-(x)) : ((x)-(y))
-
- /* Get the number of sectors from where the user program will be loaded */
- #define FLASH_SECTOR_NUMBER ((uint32_t)(ABS_RETURN(APPLICATION_ADDRESS,FLASH_START_BANK1))>>12)
-
- /* Compute the mask to test if the Flash memory, where the user program will be
- loaded, is write protected */
- #define FLASH_PROTECTED_SECTORS (~(uint32_t)((1 << FLASH_SECTOR_NUMBER) - 1))
- /* Exported functions ------------------------------------------------------- */
- void FLASH_If_Init(void);
- uint32_t FLASH_If_Erase(uint32_t StartSector);
- uint32_t FLASH_If_GetWriteProtectionStatus(void);
- uint32_t FLASH_If_Write(uint32_t destination, uint32_t *p_source, uint32_t length);
- uint32_t FLASH_If_WriteProtectionConfig(uint32_t modifier);
-
- #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代码如下:
- /**
- ******************************************************************************
- * File Name : uartDebug.c
- * Description : Code for net applications
- ******************************************************************************
- */
-
- /* includes ------------------------------------------------------------------*/
- #include "stdbool.h"
- #include "stdint.h"
- #include "string.h"
- #include "hc32_ddl.h"
-
- #include "ymodem_uart.h"
- /* typedef -------------------------------------------------------------------*/
- /* define --------------------------------------------------------------------*/
- /* UART RX/TX Port/Pin definition */
- #define UART_RX_PORT (GPIO_PORT_1)
- #define UART_RX_PIN (GPIO_PIN_4) /* P11: USART3_RX */
-
- #define UART_TX_PORT (GPIO_PORT_1)
- #define UART_TX_PIN (GPIO_PIN_3) /* P12: USART3_TX */
-
- /* UART unit definition */
- #define UART_UNIT (M0P_USART3)
-
- /* UART unit interrupt definition */
- #define UART_UNIT_ERR_INT (INT_USART_3_EI)
- #define UART_UNIT_ERR_IRQn (Int013_IRQn)
-
- #define UART_UNIT_RX_INT (INT_USART_3_RI)
- #define UART_UNIT_RX_IRQn (Int015_IRQn)
-
- /* Function clock gate definition */
- #define FUNCTION_CLK_GATE (CLK_FCG_UART3)
- #define IS_RING_BUFFER_EMPTY(x) (0U == ((x)->u16UsedSize))
- /* macro ---------------------------------------------------------------------*/
- /* variables -----------------------------------------------------------------*/
-
- static stc_ring_buffer_t m_stcRingBuf = {
- .u16InIdx = 0,
- .u16OutIdx = 0,
- .u16UsedSize = 0,
- .u16Capacity = RING_BUFFER_SIZE,
- };
-
- static uint8_t m_u8Status = 0U;
- /* function prototypes -------------------------------------------------------*/
- static void UartErrIrqCallback(void);
- static void UartRxIrqCallback(void);
- static en_result_t RingBufWrite(stc_ring_buffer_t *pstcBuffer, uint8_t u8Data);
- static en_result_t RingBufRead(stc_ring_buffer_t *pstcBuffer, uint8_t *pu8Data);
- /**
- * @brief : None.
- * @param : None.
- * @retval : None.
- */
- bool ymodemUartInit( void )
- {
- stc_irq_regi_config_t stcIrqRegiConf;
- const stc_uart_init_t stcUartInit = {
- .u32Baudrate = 57600UL,
- .u32ClkPrescaler = USART_CLK_PRESCALER_DIV1,
- .u32BitDirection = USART_LSB,
- .u32StopBit = USART_STOP_BITS_1,
- .u32Parity = USART_PARITY_NONE,
- .u32DataWidth = USART_DATA_WIDTH_BITS_8,
- .u32ClkMode = USART_INTCLK_NONE_OUTPUT,
- .u32OversamplingBits = USART_OVERSAMPLING_BITS_8,
- .u32NoiseFilterState = USART_NOISE_FILTER_DISABLE,
- .u32SbDetectPolarity = USART_SB_DETECT_FALLING,
- };
-
- CLK_FcgPeriphClockCmd(FUNCTION_CLK_GATE, Enable);
- /* Configure USART RX/TX pin. */
- GPIO_SetFunc(UART_RX_PORT, UART_RX_PIN, GPIO_FUNC_3_USART1);
- GPIO_SetFunc(UART_TX_PORT, UART_TX_PIN, GPIO_FUNC_3_USART1);
-
- /* Enable peripheral clock */
- CLK_FcgPeriphClockCmd(FUNCTION_CLK_GATE, Enable);
-
- /* Initialize UART function. */
- if (Ok != USART_UartInit(UART_UNIT, &stcUartInit))
- {
- return false;
- }
-
- /* Register error IRQ handler && configure NVIC. */
- stcIrqRegiConf.enIRQn = UART_UNIT_ERR_IRQn;
- stcIrqRegiConf.enIntSrc = UART_UNIT_ERR_INT;
- stcIrqRegiConf.pfnCallback = &UartErrIrqCallback;
- INTC_IrqRegistration(&stcIrqRegiConf);
- NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);
- NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_03);
- NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);
-
- /* Register RX IRQ handler && configure NVIC. */
- stcIrqRegiConf.enIRQn = UART_UNIT_RX_IRQn;
- stcIrqRegiConf.enIntSrc = UART_UNIT_RX_INT;
- stcIrqRegiConf.pfnCallback = &UartRxIrqCallback;
- INTC_IrqRegistration(&stcIrqRegiConf);
- NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);
- NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_03);
- NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);
-
-
- m_stcRingBuf.u16InIdx = 0,
- m_stcRingBuf.u16OutIdx = 0,
- m_stcRingBuf.u16UsedSize = 0,
- m_stcRingBuf.u16Capacity = RING_BUFFER_SIZE;
- /* Enable RX function */
- USART_FuncCmd(UART_UNIT, ( USART_TX | USART_RX | USART_INT_RX ), Enable);
-
- return true;
- }
-
- /**
- * @brief USART error IRQ callback.
- * @param None
- * @retval None
- */
- static void UartErrIrqCallback( void )
- {
- USART_ClearFlag(UART_UNIT, (USART_CLEAR_FLAG_PE | USART_CLEAR_FLAG_FE | USART_CLEAR_FLAG_ORE));
- }
- /**
- * @brief USART RX IRQ callback
- * @param None
- * @retval None
- */
- static void UartRxIrqCallback(void)
- {
- uint16_t u16Data = USART_RecData(UART_UNIT);
-
- RingBufWrite(&m_stcRingBuf, (uint8_t)u16Data);
- }
- /**
- * @brief Write ring buffer.
- * @param [in] pstcBuffer Pointer to a @ref stc_ring_buffer_t structure
- * @param [in] u8Data Data to write
- * @retval An en_result_t enumeration value:
- * - Ok: Write success.
- * - ErrorBufferFull: Buffer is full.
- */
- static en_result_t RingBufWrite(stc_ring_buffer_t *pstcBuffer, uint8_t u8Data)
- {
- en_result_t enRet = Ok;
-
- if (pstcBuffer->u16UsedSize >= pstcBuffer->u16Capacity)
- {
- enRet = ErrorBufferFull;
- }
- else
- {
- pstcBuffer->au8Buf[pstcBuffer->u16InIdx++] = u8Data;
- pstcBuffer->u16InIdx %= pstcBuffer->u16Capacity;
- pstcBuffer->u16UsedSize++;
- }
-
- return enRet;
- }
-
- /**
- * @brief Write ring buffer.
- * @param [in] pstcBuffer Pointer to a @ref stc_ring_buffer_t structure
- * @param [in] pu8Data Pointer to data buffer to read
- * @retval An en_result_t enumeration value:
- * - Ok: Write success.
- * - ErrorNotReady: Buffer is empty.
- */
- static en_result_t RingBufRead(stc_ring_buffer_t *pstcBuffer, uint8_t *pu8Data)
- {
- en_result_t enRet = Ok;
-
- if (!pstcBuffer->u16UsedSize)
- {
- enRet = ErrorNotReady;
- }
- else
- {
- *pu8Data = pstcBuffer->au8Buf[pstcBuffer->u16OutIdx++];
- pstcBuffer->u16OutIdx %= pstcBuffer->u16Capacity;
- pstcBuffer->u16UsedSize--;
- }
-
- return enRet;
- }
- /**
- * @brief Receives an amount of data in blocking mode.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be received
- * @param Timeout: Timeout duration
- * @retval : None.
- */
- en_result_t ymodemUartReceive( uint8_t *pData, uint16_t Size, uint32_t Timeout )
- {
- uint32_t tickstart = 0;
- uint8_t u8Data = 0U;
- /* Get tick */
- tickstart = SysTick_GetTick();
-
- while( ( Size > 0 ) && ((SysTick_GetTick() - tickstart ) < Timeout) )
- {
- if( RingBufRead(&m_stcRingBuf, &u8Data) == Ok )
- {
- *pData = u8Data;
- pData++;
- Size --;
- tickstart = SysTick_GetTick();
- }
- }
-
- if( Size > 0 )
- {
- return ErrorTimeout;
- }
-
- return Ok;
- }
-
- /**
- * @brief Receives an amount of data in blocking mode.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be received
- * @param Timeout: Timeout duration
- * @retval : None.
- */
- en_result_t ymodemUartTransmit( uint8_t *pData, uint16_t Size, uint32_t Timeout )
- {
- uint32_t tickstart = 0;
-
- /* Get tick */
- tickstart = SysTick_GetTick();
-
- while( ( Size > 0 ) && ((SysTick_GetTick() - tickstart ) < Timeout))
- {
- if( USART_GetFlag( UART_UNIT, USART_FLAG_TXE ) == Set )
- {
- USART_SendData(UART_UNIT, (uint16_t)(*pData));
- pData++;
- Size --;
- tickstart = SysTick_GetTick();
- }
- }
-
- if( Size > 0 )
- {
- return ErrorTimeout;
- }
-
- return Ok;
- }
ymodem_uart.h代码如下:
- #ifndef __YMODEM_UART_H
- #define __YMODEM_UART_H
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- /* Includes ------------------------------------------------------------------*/
- #include "stdint.h"
- #include "stdbool.h"
- #include "hc32_ddl.h"
- /* Private includes ----------------------------------------------------------*/
- /* Exported types ------------------------------------------------------------*/
-
- /* Private defines -----------------------------------------------------------*/
- /* Ring buffer size */
- #define RING_BUFFER_SIZE (1500U)
- #define IS_RING_BUFFER_EMPTY(x) (0U == ((x)->u16UsedSize))
- /* Exported constants --------------------------------------------------------*/
- /* Exported macro ------------------------------------------------------------*/
- /* Exported variable prototypes ----------------------------------------------*/
- typedef struct
- {
- uint16_t u16Capacity;
- __IO uint16_t u16UsedSize;
- uint16_t u16InIdx;
- uint16_t u16OutIdx;
- uint8_t au8Buf[RING_BUFFER_SIZE];
- } stc_ring_buffer_t;
- /* Exported functions prototypes ---------------------------------------------*/
- bool ymodemUartInit( void );
- en_result_t ymodemUartReceive( uint8_t *pData, uint16_t Size, uint32_t Timeout );
- en_result_t ymodemUartTransmit( uint8_t *pData, uint16_t Size, uint32_t Timeout );
- #ifdef __cplusplus
- }
- #endif
-
- #endif /* __YMODEM_UART_H */
menu.c为控制下载过程的代码,只需做少量的修改,替换UART发送和接收函数即可。
ymodem.c为ymodem协议相关的一些发送、接收、解析、封包函数,改动比较小,替换UART发送和接收函数、修改超时相关参数的值,因为时间单位变了。
初始化SysTick,节拍周期1ms,如果上电时KEY被按下,则进入下载模式,否则跳转到应用程序。
- /*******************************************************************************
- * Include files
- ******************************************************************************/
- #include "string.h"
- #include "hc32_ddl.h"
- #include "led.h"
- #include "gpioinput.h"
- #include "board.h"
- #include "menu.h"
- #include "ymodem_uart.h"
- #include "flash_if.h"
- /**
- * @addtogroup HC32F120_DDL_Examples
- * @{
- */
-
- /**
- * @addtogroup Templates
- * @{
- */
-
- /*******************************************************************************
- * Local type definitions ('typedef')
- ******************************************************************************/
-
- /*******************************************************************************
- * Local pre-processor symbols/macros ('#define')
- ******************************************************************************/
-
- /*******************************************************************************
- * Global variable definitions (declared in header file with 'extern')
- ******************************************************************************/
- static pFunction JumpToApplication;
- static uint32_t JumpAddress;
- /*******************************************************************************
- * Local function prototypes ('static')
- ******************************************************************************/
- static void SystemClockConfig(void);
- /*******************************************************************************
- * Local variable definitions ('static')
- ******************************************************************************/
-
- /*******************************************************************************
- * Function implementation - global ('extern') and local ('static')
- ******************************************************************************/
- /**
- * @brief Main function of template project
- * @param None
- * @retval int32_t return value, if needed
- */
- int32_t main(void)
- {
- uint32_t RunCnt = 0;
- /* Add your code here */
- DDL_PrintfInit( );
-
- SysTick_Init( 1000 );
-
- BoardInit( );
- gpioInputInit( );
- LedInit( );
-
- uint8_t keyCheckCnt;
- for( keyCheckCnt = 0;keyCheckCnt < 10; keyCheckCnt++ )
- {
- DDL_Delay1ms( 10 );
- if( gpioInputLowDetect( KEY_INPUT ) == true )
- {
- keyCheckCnt++;
- }
- else
- {
- break;
- }
- }
-
- if( keyCheckCnt > 7 )
- {
- LedxOn( LED1 );
- LedxOn( LED3 );
- printf("Firmware update!\n");
- /* Initialise Flash */
- FLASH_If_Init();
-
- if( ymodemUartInit( ) == false )
- {
- printf("uartUpgradeInit fail!\n");
- }
- /* Display main menu */
- Main_Menu();
-
- }
- else
- {
- printf("Jump App!\r\n");
- /* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */
- if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
- {
- /* Jump to user application */
- JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
- JumpToApplication = (pFunction) JumpAddress;
-
- SysTick_Suspend();
-
- /* Initialize user application's Stack Pointer */
- __set_MSP( *(__IO uint32_t*) APPLICATION_ADDRESS );
- __set_PSP( *(__IO uint32_t*) APPLICATION_ADDRESS );
- __set_CONTROL(0);
- __disable_irq();
- JumpToApplication();
- }
- }
-
- if( ymodemUartInit( ) == false )
- {
- printf("uartUpgradeInit fail!\n");
- }
-
- while (1)
- {
- if( RunCnt ++ > 10000 )
- {
- RunCnt = 0;
- LedxToggle( LED1 );
- }
- }
- }
-
- /**
- * @}
- */
-
- /**
- * @}
- */
- /**
- * @brief Configure system clock.
- * @param None
- * @retval None
- */
- static void SystemClockConfig(void)
- {
- stc_clk_xtal_init_t stcXTALInit;
-
- /* Configure XTAL */
- stcXTALInit.u8XtalState = CLK_XTAL_ON;
- stcXTALInit.u8XtalMode = CLK_XTALMODE_OSC;
- stcXTALInit.u8XtalDrv = CLK_XTALDRV_HIGH;
- stcXTALInit.u8XtalSupDrv = CLK_XTAL_SUPDRV_OFF;
- stcXTALInit.u8XtalStb = CLK_XTALSTB_8;
-
- /* Initialize XTAL clock */
- CLK_XTALInit(&stcXTALInit);
-
- /* Switch system clock from HRC(default) to XTAL */
- CLK_SetSysclkSrc(CLK_SYSCLKSOURCE_XTAL);
- }
将应用程序的起始地址设为0x3200,大小设为0x4A00:

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

main()函数开头设置中断向量表偏移:
- /**
- * @brief Main function of template project
- * @param None
- * @retval int32_t return value, if needed
- */
- int32_t main(void)
- {
- #ifndef VECT_TAB_OFFSET
- SCB->VTOR = 0x00003200;
- #else
- SCB->VTOR = 0x00003200 + VECT_TAB_OFFSET;
- #endif
-
- ...
- }
修改hc32f120_interrupts.c中void SysTick_Handler(void)函数:
- /**
- * @brief SysTick IRQ handler
- * @param None
- * @retval None
- */
- void SysTick_Handler(void)
- {
- SysTick_IrqHandler();
- }
如果DDL_ICG_ENABLE定义为DDL_ON,那么还需要修改hc32f120_icg.c文件中的代码:
- #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- const uint32_t u32ICG[] __attribute__((section(".ARM.__at_0x32C0"))) = //改
- #elif defined (__GNUC__) && !defined (__CC_ARM)
- const uint32_t u32ICG[] __attribute__((section(".icg_sec"))) =
- #elif defined (__CC_ARM)
- const uint32_t u32ICG[] __attribute__((at(0x00003200 + 0xC0))) = //改
- #elif defined (__ICCARM__)
- #pragma location = 0x00003200 + 0xC0
- __root static const uint32_t u32ICG[] =
- #else
- #error "unsupported compiler!!"
- #endif
- {
- /* ICG 0~ 3 */
- ICG0_REGISTER_CONSTANT,
- ICG1_REGISTER_CONSTANT,
- ICG2_REGISTER_CONSTANT,
- ICG3_REGISTER_CONSTANT,
- /* ICG 4~ 6 */
- ICG4_REGISTER_CONSTANT,
- ICG5_REGISTER_CONSTANT,
- ICG6_REGISTER_CONSTANT,
- };
也是地址的修改,不然无法生成bin文件。
上位机使用的SecureCRT 8工具:

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