飞道的博客

STM32软件调用系统BootLoader

315人阅读  评论(0)

前言

  大家知道,STM32单片机有一块系统存储器(System Memory),存储的是芯片自带的BootLoader启动程序,可通过串口或USB口等来升级程序。但是要运行自带的BootLoader,需要设置BOOT0和BOOT1引脚的电平(有些型号是通过选项字节设置BOOT1)。之前的文章中介绍过通过硬件的方式来实现设置BOOT引脚电平和复位《STM32固件IAP程序实现》。这种电路只支持串口方式,其它接口的方式还需要自己设计硬件电路来设置BOOT引脚。

  有时候受产品的外观或尺寸等限制,不允许额外的电路来实现BOOT引脚电平的设置,但又不想自己编写IAP程序,这时可以通过软件调用芯片自带BootLoader的方式来实现。

可行性

  首先,STM32是支持通过软件来调用芯片自带BootLoader的,在官方提供的文档AN2606《STM32 microcontroller system memory boot mode》4.1节中有这样一段介绍:

  也就是说,在跳转到芯片自带BootLoader程序之前,需要执行以下操作:

  1)关闭所有外设的时钟

  2) 关闭使用的PLL

  3) 禁用所有中断 

  4) 清除所有挂起的中断标志位

  以上操作执行完毕后,直接使用跳转指令,跳转到System Memory地址即可。System Memory 的地址可以在数据手册中找到,下面是F407的地址:

程序设计

  跳转程序代码如下(代码参考安富莱开发板中程序),注释比较详细,直接看就行。


   
  1. static void JumpToBootloader(void)
  2. {
  3. uint32_t i= 0;
  4. void (*SysMemBootJump)( void); /* 声明一个函数指针 */
  5.      __IO  uint32_t BootAddr =  0x1FFF0000/* F407系统BootLoader地址 */
  6. /* 关闭全局中断 */
  7.     DISABLE_INT();
  8. /* 关闭滴答定时器,复位到默认值 */
  9.     SysTick->CTRL =  0;
  10.     SysTick->LOAD =  0;
  11.     SysTick->VAL =  0;
  12. /* 设置所有时钟到默认状态,使用HSI时钟 */
  13.     RCC_DeInit();
  14. /* 关闭所有中断,清除所有中断挂起标志 */
  15. for (i = 0; i < 8; i++)
  16.     {
  17.           NVIC->ICER[i]= 0xFFFFFFFF;
  18.           NVIC->ICPR[i]= 0xFFFFFFFF;
  19.     }       
  20. /* 使能全局中断 */
  21.     ENABLE_INT();
  22. /* 跳转到系统BootLoader,首地址是MSP,地址+4是复位中断服务程序地址 */
  23.     SysMemBootJump = ( void (*)( void)) (*(( uint32_t *) (BootAddr +  4)));
  24. /* 设置主堆栈指针 */
  25.     __set_MSP(*( uint32_t *)BootAddr);
  26. /* 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 */
  27.     __set_CONTROL( 0);
  28. /* 跳转到系统BootLoader */
  29.     SysMemBootJump();
  30. /* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */
  31. while ( 1)
  32.     {
  33.     }
  34. }

另外一种方法

  有些朋友可能觉得关闭外设时钟、中断等操作太复杂,可能会出错。这时也可以通过另外一种方式来实现上述操作:即软件复位。

  芯片复位后,外设时钟、中断等默认都是关闭的,只需要在初始化前完成跳转即可。我们知道,stm32在运行main.c函数之前会先执行system_stm32f4xx.c 中的SystemInit 函数,在标准库中该函数的功能是初始化时钟等,因此我们需要在该函数开始时添加跳转代码。而在HAL中,该函数只是配置了中断向量,因此可以直接在main.c函数的开始添加跳转代码。跳转代码可参考上面的程序。具体流程如下:

  1. 需要升级时,首先在flash某个地址将一个标志位置1;

  2. 产生软件复位;

  3. 判断标志位为1,需要升级,标志位清零,执行跳转程序。

  4. 标志位为0,直接运行程序。

测试

  跳转成功后,使用STM32CubeProgrammer即可升级程序。选择接口,点击连接(下图已经连接成功),然后选择程序文件烧录即可。

推荐阅读:

IAP源码分享

STM32F4通过U盘升级程序

远程升级单片机程序怎么设计?

    欢迎关注公众号"嵌入式技术开发",大家可以后台给我留言沟通交流。如果觉得该公众号对你有所帮助,也欢迎推荐分享给其他人。


转载:https://blog.csdn.net/zhang062061/article/details/115744216
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场