本帖最后由 香水城 于 2017-8-17 14:35 编辑
STM32F0启动模式相关问题探讨
前言
本文的内容为简单介绍STM32F0 的启动模式,并重点介绍有可能产生的问题,很多均是在客户现场反馈的问题,经过不断的尝试与讨论,最终得到的一点经验并分享给大家.
STM32F0XX启动模式
STM32F0系列MCU内置了BOOT Loader代码在System Flash中,它可以帮助我们在量产编程时提供一个方便的接口(比如UART、SPI、CAN、USB等等),因为不同芯片的接口与容量的不同,并不是每一个芯片都支持所有的这些接口,某一个芯片具体支持哪些协议,可以参考AN2606这篇文档,本文不再赘述。
案例一
客户在使用STM32F091RCT6时,使用UART1下载代码,代码在不重新上电的情况下不运行。经过与客户沟通,在客户处现场测试,果真如此,但是使用ST-Link/V2仿真器下载的代码就是没有问题的。经过分析与查找用户代码,发现客户没有在应用代码中将中断向量表重新置回默认位置,且用户的代码中使用了中断功能,一旦中断发生,中断向量表异常,最红进入到Hard Fault这个中断里去了。但是在表现形
式看就是没有运行,所以增加以下代码在main()函数的起始位置即可解决.
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
SYSCFG->CFGR1 = (uint32_t)0x00000000;
问题分析:
STM32F0系列MCU使用的是Cortex-M0的内核,此内核跟Cotex-M3的区别之一就是去掉了VTOR寄存器,这个就是中断向量表偏移寄存器。当没有此寄存器之后,中断向量表如果需要转移的话,就会比较麻烦。
ST提供了一种方案就是把这段中断向量表复制到SRAM中去,之后从SRAM启动。当客户使用了MCU片内的BOOT Loader程序来更新代码后,正常的情况下勾选上“Jump to application”选项在STMFlashLoader Demo这个软件中即可跳转到应用程序,并且正常运行。这是因为应用代码的中断向量表已经被正确的设置为从main flash启动.但是在STM32F0的bootloader代码中,并没重新设置向量表到main Flash的起始位置,所以需要用户自行设置。
案例二
客户写了一段代码在STM32F091RCT6上,其中没有使用任何的中断程序,就是简单的反转GPIO的代码,在使用MCU内部的Boot Loader下载到MCU之后,代码也能够正常的运行启动。但是发现如果此时按下reset按键,程序再也不启动了.
首先,根据前边的案例一,建议客户增加一段代码,结果现象依旧。又跟客户多次沟通是否有何其他的操作,客户讲每次烧写前,都全片擦除一次芯片,重新上电后,再进行ISP 编程。
本人在开发板上复现了这个现象(Nucleo-F091)。经过研究查找讨论,发现是STM32F0系列的MCU自带的查空标志位引起的。查空标志位在芯片配置为从Main Flash启动,且发现首地址(0x08000 0000)的内容为0xFFFFFFFF的时候置位。它会将启动地址强制的设置到System Flash的启动地址,它的本意是为了方便一个全新的芯片进行ISP的编写。客户每次烧写前都进过全片擦除+重新上电(注意:此时MCU就已经进入到了system Flash中了),当下载的代码运行时,empty flag还是在置位的,此时按下reset的按键,产生一个system reset,其并不会清除empty flag标志,那么重新启动之后就被这个标志位又强制的引导到了system flash中,运行了bootloader的代码。在客户看来就是应用程序没有运行.
解决办法:
首先,这问题只有在第一次运行的时候才会出现,当烧写完代码之后就重新上电,那么该问题就会解决。因为POR(上电复位)会更新这个empty flag,进而正确的引导代码到对应的用户代码区域。但是在客户的现场,有时候是不允许重新上电的(因为各种各样的原因),所以我们还有第二个办法。那就是强制重新加载OPTION BYTE(设置OBL_LAUNCH @FLASH_CR)。因为这个操作会使empty flag更新。(:这个操作也会引起一个system reset。)这个办法是最后客户可以接受的办法.
其次,我们可以内部大胆的猜测一下,因为强制重新加载OPTION BYTE会更新empty Flag 标志,且OPTION BYTE中本身有都包含了BOOT0和BOOT1的设置(只有STM32F04x和STM32F09x中的OPTION BYTE是这么设计的)那么我们其实就可以使用修改OPTION BYTE的方式来进行自动升级代码了.这样最直接的好处就是节省了外部的GPIO。
参考文献:
AN2606
AN3155
RM0091
对应的代码:STM32F0启动模式相关问题探讨
更多实战经验请看:【ST MCU实战经验汇总贴】
|