STM32首次烧录选择erase sectors导致程序跑飞

一、故障现象

小批量打样回来的板子,烧录程序后一切正常,蜂鸣器响0.5s,LED闪烁等待握手;但是断电重启后蜂鸣器长鸣,LED不闪烁,无法正常运行。

二、分析解决过程

首先我看了一下电源,电压、电流都是对的,这说明硬件上没有短路等大毛病。

那么我感觉这是程序跑飞了,可能是程序启动有问题,是不是从SRAM起了,而不是从flash起的?

我第一怀疑板子焊接有问题,目检了一遍,特别是boot0引脚那边,重点检查了一下,没有任何毛病。谨慎起见,我还是将整个MCU重新加焊了一遍。可惜的是故障依旧,看来不是焊接的问题。

其实从故障现象来看,基本可以肯定是跟flash有关了。想一想,断电重启后到程序跑到main函数中间,芯片经过几个过程:

1、上电电源稳定后,硬件自动从flash起始地址0x80000000读取栈顶地址MSP,然后从0x80000004读取复位中断函数地址Reset_Handler,再设置堆栈指针MSP,最后跳转Reset_Handler。这个是硬件自动执行的,死规定,改不了的。

2、进入复位函数Reset_Handler干4件事:初始化数据段、清零BBS段、调用SystemInit()、调用_main入口。

在这个过程中,如果初始化没有完成,或者完成错误了,那也有可能程序跑飞。

这里有一定可能性的是时钟,如果用外部晶振的话,如果晶振坏掉了、没有焊接好,那么这里可能会有问题。但是我这个现象不是,我是烧完程序后是OK的,断电重启后不行了。看来很可能还是flash读前面两个地址的时候挂了。

我检查了一下KEIL中程序地址,都没有什么问题。

但是在检查算法ram的时候,我注意到擦除选项选的是erase sectors,这是之前为了烧录快一点而设置的。我们都知道擦sectors只擦除用到的扇区,会不会是这里有问题。

于是,我将擦除选项改成Erase Full Chip,烧录后再断电重启,这下子一切都正常了。

三、原因分析

首先Erase Full Chip和Erase Sectors的区别:

特性 Erase Full Chip Erase Sectors
擦除范围 整个flash (除OTP、选项字节) 用到的扇区
速度
数据 全部清除 保留未擦除扇区的数据
寿命 消耗1次flash擦写次数 消耗对应扇区擦鞋次数

这里要先讲一下flash的特性:只能从非FF写0,不能从非FF写1

这是因为STM32用的是浮栅型Flash,可以理解成每个bit有一个电子陷阱,电子在陷阱里=0,电子被拿走=1。而擦除动作是加高压,将所有浮栅上的电子全部抽走,这样所有的bit都变成了1。写入动作就是加低压,把电子注入某些bit,这样就把1变成了0。擦除是批量抽电子,写入是逐个塞电子。flash不支持批量塞电子,所以擦除后的部分变成了1。

还有一个事实是:虽然理论上flash出厂时应该是全0xFF,但是工程应用中拿到手的焊接成品的PCBA上,这颗MCU中的flash很有可能已经经过测试,甚至不能保证芯片是全新的。这种时候,拿到手的芯片中的数据是脏的,flash中可能是随机数据。

所以选择erase sectors后,只有用到的部分sectors变成了FF,但是其他部分很可能还有00存在,而写入只能将1变成0,而不能将0变成1。这就导致其他sectors中很可能还是乱码。

那么还有一个问题:为什么我用到的sectors已经擦除了,还会跑飞呢?

这是因为:

1、中断向量表附近有脏数据

例如程序占sector0,但中断向量表、堆栈指针在flash开头,这部分没有被擦除。如果这部分不干净,MCU一读就错,直接HardFault。

2、堆栈区域是脏数据

程序运行需要栈空间,如果栈所在的地址有脏数据,那么一进函数就死机。

3、编译器填充区域残留乱码

有些位置编译器会留空、填0xFF,实际却是乱码,这会导致程序判断逻辑出错。

4、选项字节/保护位干扰

有部分芯片会默认读保护,扇区擦除不会碰这些位置。

这些原因导致的现象一般有:

1、下载成功,但芯片不运行;

2、一运行就硬件错误中断Hardfault;

3、偶尔能跑,偶尔死机,不稳定;

4、仿真时,PC指针跳到很奇怪的地方。

四、工程建议

1、拿到手的板子,第一次烧录,选择Erase Full Chip;

2、开发调试优先用Erase Full Chip;

3、只有明确要保留Flash里的数据,例如配置、序列号时,采用扇区擦除。

相关推荐
DA02219 小时前
系统移植-STM32MP1_Buildroot根文件系统移植
stm32·单片机·嵌入式硬件·bsp·系统移植
cmpxr_9 小时前
【单片机】STM32晶振引脚不连晶振时的做法
stm32·单片机·嵌入式硬件
cmpxr_10 小时前
【单片机】STM32Fxx中RTC掉电不走
stm32·单片机
qq_1508419910 小时前
关于TTL单端到RS485差分
嵌入式硬件
cmpxr_10 小时前
【单片机】STM32的FSMC总线什么情况需要复用
stm32·单片机·嵌入式硬件
记录无知岁月11 小时前
【GD32】(二) 基本外设使用
单片机·can·iic·gd32·dwt
划水的code搬运工小李11 小时前
Ubuntu18.04读取串口信息
stm32·ubuntu·串口·嵌入式
LCG元11 小时前
STM32实战:基于STM32F103的智能药盒定时提醒系统
stm32·单片机·嵌入式硬件
小向是个Der12 小时前
嵌入式进阶——嵌入式MCU编译工具链总结
单片机·编译·嵌入式软件·cline+glm5.0