|
1 简介 客户在使用STM32G474RE进行产品开发的时候,操作系统软件使用了RT-Thread 5.0,同时由于要做ClassB认证,所以在RT-Thread系统上,移植了ClassB 2-3-0版本安全库。用户程序另外一个功能是固件升级,在调试固件升级程序的过程中,发现一旦执行了ClassB的启动自检,就会出现固件升级失败。调试发现,固件升级失败的原因是写Flash的时候发现Flash状态寄存器的错误标志被置位,导致Flash写操作失败。客户根据现此象反馈ClassB的自检代码有隐患,导致Flash出错。# d N. ~; U" U. I% `0 C7 D 本文分析了出现该错误的原因以及解决办法。- s: t5 f6 a+ I6 L3 _+ S- j9 N) A 4 G$ `7 P+ G" b4 C6 M. c - k ]- k8 S5 Y% @; R$ { 2 问题描述 * {8 @) }% ]1 q; G% } 根据客户的问题反馈,我在NUCLEO-G474RE开发板上单独移植ClassB,通过调试,没有发现类似问题。为了复现该问题,从RT-Thread官方网站上下载了5.0版本的RT-Thread代码。RT-Thread对STM32的支持是相当友好的,代码中包含了对多数STM32开发板的支持,所以对于NUCLEO-G474RE开发板,只需要找到对应的目录,打开工程即可,如下图。
▲ 图1. RT-Thread工程目录 在上述工程下,直接添加ClassB的启动自检代码即可生成客户出现问题的软硬件环境。1 C, g9 q& P2 ~( \7 ]6 ?! n0 v! M 移植完ClassB的启动自检代码,通过NUCLEO-G474RE开发板调试发现,当执行启动自检,跳转到主函数之后,通过查看Flash的寄存器,发现Flash状态寄存器的PGAERR,PGSERR标志被置位,如下图所示。9 y& ^2 s& K! q( E/ N6 x' ]
▲ 图2. Flash错误标志 从RM0440参考手册上关于PGAERR和PGSERR的描述可知,这两个标志位只能由硬件置起,而且是由于写Flash才会导致该错误标志被置起,而在测试的代码中,并没有Flash的写操作,由于之前有发现Keil调试器导致G0出现的Flash错误标志的问题,刚开始也怀疑Keil调试器导致类似问题,实际测试发现该问题与调试器无关。3' r) U& b1 X. T, f 问题分析与解决 9 |5 D) q8 \/ p0 C . U9 z% _6 |: Z ~5 W. B( J 结合参考手册对PGAERR以及PGSERR的描述,只能从写Flash的角度去分析问题产生的原因,最终通过单步调试,发现其中一句代码导致了该错误标志位的置起,如下图所示。8 V5 y& C7 i$ Q2 C5 A
▲ 图3. 错误代码 在SysTick_Handler中断服务程序中,调用了RT-Thread的函数rt_tick_increase,该函数中的变量thread为一个空指针,其地址为0x000000,在STM32G4中,该地址恰好映射为Flash的地址,从上面语句--thread->remaining_tick实际上产生了Flash写操作,所以最终导致了Flash的错误标志置位。 找到该问题原因之后,反馈给客户,客户在其板子上验证了同样的现象,所以该问题与ClassB的自检代码没有关系,而是由于指针变量没有赋值,导致指针指向的地址为Flash地址,如果此时对该指针变量进行赋值操作,就会产生Flash错误标志位被置位的现象。 % V2 b9 [+ Z: {) K. r 4 小结 " Q. t2 c2 H) ]6 g5 g 在STM32软件开发中,不当的指针操作,尤其使用未经初始化的指针可能会引起莫名奇妙的问题,所以在使用指针变量的时候,需要注意指针地址的正确性。9 c! @, t$ O9 `- K/ j) C# b: T8 v7 j % ]3 H7 o2 y. i1 o& x% r% l |
STM32C542RC开发板实现长短按键识别功能
【新品测评】STM32WL3R芯片测评,从点亮第一个LED到subGhz启动
[GPIO] 使用新型抽象开始C++嵌入式编程,从GPIO开始
STM32L562DK探索板——继续深入了解Audio Play的工作流程
STM32L562DK探索板——触摸菜单实验之触摸测试
STM32L562DK探索板——触摸菜单实验之LED闪烁
STM32L562DK探索板——给Audio Play添加音量控制功能
STM32L562DK探索板——重写Led闪烁demo
STM32L562DK探索板——触摸菜单的实验
STM32L562DK探索板——简单的显示变量函数
微信公众号
手机版