stm32 bootloader实现问题总结

技术原理

MCU启动后,从8000000H开始运行代码,此处是boot loader程序。

应用程序编译到8010000H位置,boot loader启动后,跳转到8010000H运行。

在进行OTA的时候,需要将IDE生成的hex文件转换为bin文件,使用工具转换即可:

fromelf.exe --bin .\app.axf --output .\app.bin

bootloader中的跳转

从应用程序开头读取栈顶,程序入口地址。

#define APP_BASE 0x8010000
void (*app)(void) ;

// 获取应用程序栈顶和入口地址
stack_addr = *(__IO uint32_t *) APP_BASE;
application_addr = *(__IO uint32_t *)( APP_BASE +4);

// 设置MP,运行app
app =(void(*)(void))application_addr;
__set_MSP( *(__IO uint32_t *) APP_BASE);
app();

app测试程序

app的测试程序,由STM32CubeMx生成,主要初始化打开led指示灯,循环间隔500ms发送串口数据。

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    HAL_Delay(500);
    while((USART1->ISR & 0X40) == 0);
    USART1->TDR = 0x55;
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

设置编译地址到8010000H,size变为1000H


遇到的问题

现象:

boot loader运行后,可以跳转到应用程序,可以打开led,串口没有发送数据。

查找原因:

用flash烧录工具,将app烧录到8010000H地址,在boot loader项目中在线调试,app启动后,可以看到Disassembly窗口中出现了app的汇编代码,单步调试发现CPU只在附近这几句跑:

用工具将app生成asm文件:

fromelf.exe --text -c -o .\app.asm .\app.axf

 查找汇编文件中对于地址的代码

 可以发现CPU一直停留在HAL_Delay方法中。

验证HAL_Delay的问题,将应用代码改为:

  while (1)
  {
	while((USART1->ISR & 0X40) == 0);
    USART1->TDR = 0x55;
  }

app启动后,串口可以收到数据。

总结:

跳转到APP后,Systick没有正常工作。

解决方案:

查看app的初始化代码,SysTick部分是CubeMx生成的,编译到8000000H地址可以正常运行,所以代码没问题;而SysTick没有变化,可能是中断未执行

void SysTick_Handler(void)
{
  HAL_IncTick();
}

检查中断向量表是否有问题,在system_stm32xxx.c文件中,有如下代码

#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
...
void SystemInit(void)
{
  /* Configure the Vector Table location -------------------------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
  SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation */
#endif /* USER_VECT_TAB_ADDRESS */
}

中断向量默认在8000000H位置,当中断向量发生变化后,应该在初始化的时候修改中断向量地址,所以将上述代码修改为

#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00010000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
...
void SystemInit(void)
{
  /* Configure the Vector Table location -------------------------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
  SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation */
#endif /* USER_VECT_TAB_ADDRESS */
}

在IDE中,添加宏

 再次启动,boot loader可以正常拉起app程序。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于HAL库的STM32F4 Bootloader是一种自定义引导程序,用于STM32F4 MCU。它通常由两部分组成,即Bootloader和应用程序(App)。 Bootloader是启动程序的一部分,位于用户的Flash区域的前部。它在芯片启动后首先运行,并负责进行硬件的初始化。初始化完成后,Bootloader会跳转到对应的应用程序。 使用HAL库可以方便地开发STM32F4 Bootloader。HAL库是一种硬件抽象层,提供了许多功能和API,使开发者能够更轻松地访问和控制硬件资源。通过HAL库,开发者可以编写自定义的Bootloader代码,实现芯片的初始化和应用程序的跳转。 总结起来,基于HAL库的STM32F4 Bootloader是一种自定义引导程序,用于进行硬件初始化并跳转到应用程序。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [stm32f446_custom_bootloader:基于STM32CUBE HAL的STM32F446 MCU的自定义引导程序](https://download.csdn.net/download/weixin_42136837/15649570)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [[笔记]STM32基于HAL编写Bootloader+App程序结构](https://blog.csdn.net/qq_33591039/article/details/121562204)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值