你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F091 从自举程序向应用程序跳转的问题与解决

[复制链接]
STMCU小助手 发布时间:2022-2-18 20:41
前言
当使用 STM32 的 Bootloader 中的 GO 命令进行从 Bootloader 向用户代码进行跳转时,需要正确地在用户代码中设置向量表,才能正常地运行用户代码。
问题
某客户在其产品的设计中,使用了 STM32F091RCT6,由于特殊的功能需求,将会使用到使用 Flash Loader Demonstrator对芯片进行串口烧写后,直接跳入程序,但是客户发现烧写后根本就没有执行用户代码。

调研
1.还原问题现象
我们使用 NUCLEO-F091RC 工具板来还原这个问题的现象。

[OY{TI8AGDHFO5JQ_B4ZN1S.png

再到 STM32Cube_FW_F0_V1.2.0 中找个例程来测试一下,为了方便观察,我们使用 Examples 中的 GPIO_IOToggle 来测试,因为这是一个闪灯的程序。位置如下图所示:

2I747WO[SM{XWU$}D_ZJPTH.png

使用 IAR 将项目打开,进行编译,生成 STM32F091RC-Nucleo.hex 文件,可在\Examples\GPIO\GPIO_IOToggle\EWARM\STM32F091RC-Nucleo\Exe 文件夹中找到。使用 USB 线连接 NUCLEO-F091RC,使用 STM32 ST-LINK Utility 软件将 STM32F091RC-Nucleo.hex 代码下载到 NUCLEO-F091RC,观察 LD2 灯,可见其闪烁。我们再用 STM32 ST-LINK Utility 软件将代码擦除掉。
确认了 STM32F091RC-Nucleo.hex 没有问题之后,我们开始使用 Flash Loader Demonstrator 这个串口烧写软件进行测试。由于 Nucleo 板上的 ST-LINK 自带虚拟串口驱动,所以我们无需另接串口工具,就可以直接使用。在“我的电脑”点右键,进入“属性”,选择“设备管理器”,可以看到:

6ZTQ0X381N8`Q6CGZFF[V{D.png

也就是说,虚拟串口为 COM16。

所以我们打开 Flash Loader Demonstrator,做以下的配置:

886)DKK$)O9C`3_`JSK1U3F.png

我们从 Nucleo 的用户手册 UM1724 中找到以下这张图:

{$)K[%6%N[9NOX7WZ(WC2$A.png

在 Nucleo 上用跳线帽将 CN7 中的第 5 脚和第 7 脚短路,拉高 BOOT0 脚,按一下 RESET 按键,从 System Memory 启动


我们回到 Flash Loader Demonstrator 的启动界面,点“Next”进入下一个界面,再点“Next ”再进入下一个界面,再点“Next ”进入下一个界面,我们在这个页面中选择下载代码“Download to device”,导入刚才编译生成的 STM32F091RCNucleo.hex,选中“Jump to the user program ”,意思就是通过串口烧写完毕后,直接跳到用户代码去运行。如图:

@$GJ@EW`9S$O6UM]TOJTQ.png

点击“Next”进行代码烧写。我们发现代码烧写完成后,按道理从 System Memory 中的 Bootloader 跳转到用户代码后,我们应该看到 LD2 灯在闪烁。但是,我们发现,确实没有在闪烁!
将刚才放在 CN7 中的那个跳线帽拔掉,按下 RESET 键,可以看到 LD2 灯在正常闪烁,也就是说,程序正常下载进去了,看起来像是没有跳转。

2.问题分析
现在我们开始来分析这个问题。

我们打开 AN3155 这个应用笔记,这是关于 STM32 Bootloader 所使用的 USART 协议的描述。由于 STM32F091RCT6 中还是有代码存在的,所以我们直接使用 GO 命令来测试一下跳转的情况。

再将 CN7 的第 5 脚和第 7 脚用跳线帽短接起来,按下 RESET 按键从 System Memory 的 Bootloader 启动。我们使用串口工具来进行分析,将串口工具配置为:端口号 COM16,波特率 115200,奇偶校验设置为 EVEN,数据位为 8,停止位为 1。打开连接。

我们先发送“0x7F”给 STM32,与 Bootloader 确认 USART 口,Bootloader 确认后,回送 ACK(0x79),我们可以看到正常收到0x79,所以通讯建立。现在开始测试 GO 命令。按照 GO 命令的流程,我们发送“0x21 0xDE”启动 GO 命令,Bootloader 正常回应 ACK(0x79)。现在要测试跳转到用户代码那边运行用户代码,所以我们发送 Main Flash memory 的地址 0x0800 0000 和 Checksum(XOR(0x08, 0x00, 0x00,0x00)=0x08),也就是发送“0x08 0x00 0x00 0x00 0x08”,这个时候,Bootloader 也正常地回应了 ACK(0x79)。那么看起来,程序是正常跳转了,可是为什么就是看不到运行用户代码而能看到的 LD2 闪烁呢。看起来,很有可能会是从 Bootloader 跳转到用户代码后,在用户代码执行过程中出错了,导致复位,并回到了 Bootloader 程序。那么,从 Bootloader 跳转到用户代码之后执行出错的最可能原因就是向量表设置不对。我们从AN3155 中看到这么一句话:“The Jump to the application works only if the user application sets the vector table correctly to point to the application address.”也就是说,我们必须在用户代码中设置正确的向量表。所以我们回到 GPIO_IOToggle 的例程,加入代码将向量表从 Bootloader 修改回用户代码的向量表。

我们在参考手册 RM0091 的“System configuration controller (SYSCFG)”这一章中的 SYSCFG 配置寄存器 1(SYSCFG_CFGR1)中看到 MEM_MODE[1:0]的描述:



于是,我们将以下代码加入到例程中 main 函数最开始的地方。
  1. RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
  2. SYSCFG->CFGR1 = (uint32_t)0x00000000;
复制代码

重新编译,生成新的 STM32F091RC-Nucleo.hex,我们再按之前测试时使用 Flash Loader Demonstrator 的步骤再测试一遍,这次终于可以看到在串口烧写代码之后,可以正常进入用户代码并正常工作了——LD2 在闪烁。用串口工具直接发 GO 命令,也可以进入用户代码并正常工作了。

结论
由于在用户代码中没有重新定位向量表,导致从 Bootloader 跳转到用户代码区后,无法正常工作,产生 Hard fault 后系统复位,又回到了 Bootloader。

处理
当需要使用 GO 命令从 Bootloader 直接跳转到用户代码时,必须注意在用户代码中要加入代码正确地设置向量表。

收藏 评论0 发布时间:2022-2-18 20:41

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版