STMCU小助手
发布时间:2022-2-18 21:02
|
前言 本文的内容为简单介绍 STM32F0 的启动模式,并重点介绍有可能产生的问题,很多均是在客户现场反馈的问题,经过不断的尝试与讨论,最终得到的一点经验并分享给大家. STM32F0XX 启动模式 STM32F0 系列 MCU 内置了 BOOT Loader 代码在 System Flash 中,它可以帮助我们在量产编程时提供一个方便的接口(比如 UART、SPI、CAN、USB 等等),因为不同芯片的接口与容量的不同,并不是每一个芯片都支持所有的这些接口,某一个芯片具体支持哪些协议,可以参考 AN2606 这篇文档,本文不再赘述。 案例一 客户在使用 STM32F091RCT6 时,使用 UART1 下载代码,代码在不重新上电的情况下不运行。经过与客户沟通,在客户处现场测试,果真如此,但是使用 ST-Link/V2 仿真器下载的代码就是没有问题的。 经过分析与查找用户代码,发现客户没有在应用代码中将中断向量表重新置回默认位置,且用户的代码中使用了中断功能,一旦中断发生,中断向量表异常,最红进入到 Hard Fault 这个中断里去了。但是在表现形式看就是没有运行,所以增加以下代码在 main()函数的起始位置即可解决.
问题分析: 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。 |
微信公众号
手机版