记一次SM32F407ZG死机原因分析

news/2024/11/7 13:58:09/

主芯片:STM32F407ZG
产品软件架构:

  1. bootloader + upgrader / application (upgrader 是一个系统升级器,升级系统专用)
  2. 在bootloader模式下可以加载upgrader或application并启动
  3. 在upgrader模式下可以更新bootloader和整个application.
  4. upgrader和appplication同时只存在一个,由bootloader从文件系统载入STM32F407ZG应用区.

问题描述:两台故障产品在使用过程中意外死机,无法开机,分别编号为1号和2号。
故障机分析处理:
1号已经被重刷程序后修复,故障无法再复现,怀疑是STM32 flash程序区被改,所以首先分析了操作flash的代码,经查擦写flash只发生在成功开机进入系统或者在"系统升级"选项中进行操作时,其他使用过程中不涉及flash擦写。同时编写程序,每隔1秒擦除flash一次,一共执行2万次擦写, 在擦写期间进行各种操作,均无发现死机现象。
2号机拆机检查: 系统上电,STM32 3V3电压正常,但串口无法检测到系统log输出,无法正常开机。

尝试用Jlink Command测试:
撤掉USB和电池供电,飞线连接3V3,SWDIO,SWCLK,GND至JLink Command
执行connect指令,成功连接STM32F407ZG主控
执行halt停机指令,成功停机
J-Link>halt
PC = 08000294, CycleCnt = 00000000
R0 = 00000000, R1 = 00000000, R2 = 00000000, R3 = 00000000
R4 = 00000000, R5 = 00000000, R6 = 00000000, R7 = 00000000
R8 = 00000000, R9 = 00000000, R10= 00000000, R11= 00000000
R12= 00000000
SP(R13)= 20013378, MSP= 20013378, PSP= 00000000, R14(LR) = FFFFFFFF
XPSR = 01000000: APSR = nzcvq, EPSR = 01000000, IPSR = 000 (NoException)
CFBP = 00000000, CONTROL = 00, FAULTMASK = 00, BASEPRI = 00, PRIMASK = 00
FPU regs: FPU not enabled / not implemented on connected CPU.
执行go全速运行,指令响应OK,但是产品仍无法成功进开机流程,再次执行halt指令:
J-Link>halt
PC = 0800022E, CycleCnt = 06EA7AC4
R0 = 0805A76C, R1 = 20001E78, R2 = 00011500, R3 = 00000000
R4 = 00000000, R5 = 00000000, R6 = 00000000, R7 = 08059AAF
R8 = 00000000, R9 = 00000000, R10= 08059AD0, R11= 08059AD0
R12= 00000000
SP(R13)= 20013378, MSP= 20013378, PSP= 00000000, R14(LR) = 0800019F
XPSR = 21000000: APSR = nzCvq, EPSR = 01000000, IPSR = 000 (NoException)
CFBP = 00000000, CONTROL = 00, FAULTMASK = 00, BASEPRI = 00, PRIMASK = 00
FPS0 = 00000000, FPS1 = 00000000, FPS2 = 00000000, FPS3 = 00000000
FPS4 = 00000000, FPS5 = 00000000, FPS6 = 00000000, FPS7 = 00000000
FPS8 = 00000000, FPS9 = 00000000, FPS10= 00000000, FPS11= 00000000
FPS12= 00000000, FPS13= 00000000, FPS14= 00000000, FPS15= 00000000
FPS16= 00000000, FPS17= 00000000, FPS18= 00000000, FPS19= 00000000
FPS20= 00000000, FPS21= 00000000, FPS22= 00000000, FPS23= 00000000
FPS24= 00000000, FPS25= 00000000, FPS26= 00000000, FPS27= 00000000
FPS28= 00000000, FPS29= 00000000, FPS30= 00000000, FPS31= 00000000
FPSCR= 00000000
初步发现PC和MSP数值正常,但PC停留在代码很靠前的部分,怀疑是反复重启,并且是指在很小一段代码内反复执行,尝试用savebin指令dump芯片内部flash,成功读取1MB的flash数据,经过对flash数据的分析,发现如下信息:
1. app程序区起始地址为0x8080000, 关键字符串upgrader,确定app区域存储的是升级程序upgrader, 版本未定
2. bootloader区起始地址为0x8000000, 经匹配,bootloader程序为xx.x.x版本,为产品发布的第一个正式版本。其中bootloader偏移0x4000-0x8000一共16KB的数据被改写,解析偏移16KB前64字节发现刚好与系统保存的参数格式匹配,但部分参数无法解析
3. 根据上述信息得知upgrader程序是新版本,参数区使用了flash偏移0x4000-0x8000的区域,那么原来的参数在偏移0x60000出原因该会有保留。尝试读取解析:

5E 4F B5 63 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 		FF FF FF FF FF FF FF 0F 00 00 00 38 30 30 31 30 31 59 44 33 31 30 36 30 39 38 37 00 AA AA

解析得到SN号:xxxxxxxxxxxxxxxx,其中生产日期为xxxx.xx.xx,可知原来app区域运行的是xxxx.xx.xx版本,现在已被upgrader程序代替.
4. 根据第3步得到的版本信息,查找对应版本的upgrader文件,与芯片dump出来的upgrader完全匹配得到上述信息后,查看该upgrader的MSP地址(0-3)和程序入口地址(4-7)分别为: 0x2000EA, 0x808029d,使用setPC指令重置MCU PC指针,然后执行go指令,成功跳过bootloader直接开机运行upgrader代码,成功进入upgrader后,通过串口可以登录系统,查看文件系统和关键文件,可以佐证前面步骤的信息

经过上述分析得知: 不开机的原因是bootloader被非法改写。
根据flash镜像的分析推测故障发生的场景: 用户版本为xxxx.xx.xx,用户想要升级系统到xxxx.xx.xy版本,其中upgrader程序已经成功刷到了MCU的应用区,新版本的upgrader会将参数保存在0x4000处,此处会破坏旧版本bootloader, 但是后续没有升级成功,新版本的bootloader没有被写入,此时用户关机、断电、重启等操作将会导致系统完全变砖。联想到最近由于软件架构调整,各个模块的flash地址偏移发生了很大变化,xxxx.xx.xx升级到xxxx.xx.xy及以上版本时存在参数区地址调整,存在此问题,xxxx.xx.xy及以上系统升级不存在这个问题。

解决办法: 修改upgrader程序,在新版本的bootloader成功升级前,不可操作新的参数区,避免旧版本bootloader被非法改写

总结:

  1. 针对这种需要修改底层bootloader和系统更新的系统,还是需要完善的测试
  2. flash空间的划分一定要慎重,避免在中途调整,本案例就是由于前期bootloader和application的地址空间分配不合理,application空间过小,需要缩小bootloader的空间来增大application空间,涉及到底层程序的更新,这给对已量产的产品带来很大风险。
  3. 善于使用工具,jlink command是个好东西
  4. 遇事不慌,仔细分析,芯片一般不会有问题,不稳定的外围电路和软件bug带来问题的可能性更大

http://www.ppmy.cn/news/428418.html

相关文章

定时任务执行时间设置详解

目录 前提实践举例定时任务执行时间设置详解定时器包含的子表达式和对应子表达式允许的值子表达式中特殊字符含义的解释和相应示例 前提 一般在处理业务过程中,都需要在特定的时间点执行特定的任务,尤其是业务复杂且执行时间很长,业务之间关…

家中群晖NAS遇到断电如何自动关机

群晖NAS遇到断电时如何自动关机 前置条件实现功能的想法具体实施的步骤开启群晖Linux的SSH登陆安装Putty或是Xshell远程登陆上群晖创建计划任务 前置条件 需要一台UPS(品牌功能不限,只需续航5分钟以上就可以) 实现功能的想法 通过监控网卡…

分布式安装配置spark-3.2.3

Spark是一个基于内存的大数据计算框架,可以与Hadoop集成,提供更快速的数据处理能力。本文将介绍如何在三个Ubuntu系统上搭建一个Spark集群。 主要步骤包括: 准备工作:下载安装包,设置环境变量,解压安装包…

01_03_插入排序(Insertion Sort)

插入排序(Insertion Sort) 插入排序(Insertion Sort)介绍: 是一种简单的排序算法。它的原理是将待排序的元素逐个插入到已排序序列中的合适位置,从而逐步构建有序序列。 插入排序(Insertion …

vue3+ts:shims-vue.d.ts

一、本文引子 uniapp(3.8.4.20230531) vue3 ts vite 项目 在搭建这个base项目的时候出现红素波浪线如图,代码运行正常,但是看起来很难受,于是各种查找,能找到的资料很少,可能和我提问不够准…

Java之数组

Java之数组 数组也是对象。数组只是相同类型的、用一个标识符名称封装到一起的一个对象序列或基本类型数据序列。数组是通过方括号下标操作符[]来定义和使用的。所有的数组类型,不管是对象数组还是基本类型的数组都扩展了Object类。当创建一个数组对象时&#xff0…

英特尔处理器能用鸿蒙系统吗,鸿蒙系统能不能兼容windows的所有应用软件?

众所周知,鸿蒙系统是一个跨平台的系统,支持电脑、手机、平板、智能穿戴等硬件设备。如果鸿蒙系统,同时支持所有的win应用、android应用,那么岂不是不用担心“生态”问题,实现“一统江湖”了吗?下文具体说一…

x86服务器能装64位系统吗,x86处理器能装64位系统吗_64位系统装32位的可以么

2019-02-04 10:08:44  浏览量:6162 32位处理器支持安装64位系统吗?处理器就是我们熟知的cpu,处理器分32位和64位,现在处理器几乎都是64位,不过早期的处理器普遍是32位,那么32位处理器能装64位系统吗?从技术角度看,32位处理器是不能装64位系统的,因为不支持,不确定的…