前言
这几天遇到一个bootloader升级的奇怪问题,分析问题的过程使用了一些常用的分析工具和方法觉得很有普遍性,这里记录一下Bug分析、复现最后解决的整个过程,希望能给大家带来一些启发。
正文
环境描述
ECU使用瑞萨公司的RH850芯片,bootloader支持应用的双分区刷写。
测试用例
当前程序处于A分区 --> 开始升级,跳入bootloader --> 升级A分区程序 --> 故障注入,跳过升级的0x34服务,直接开始0x36服务传输升级包程序
图1:Bootloader故障注入测试
图2:Bootloader升级常用的UDS服务ID
期望结果
Bootloader升级失败,0x11 01软件复位后Bootloader校验A分区失败(默认跳到A分区),程序跳到B分区,正常运行B分区程序。
图3:A分区升级失败后跳到B分区期望正常通信状态
实际结果
Bootloader升级失败,0x11 01软件复位后Bootloader校验A分区失败(默认跳到A分区),程序跳到B分区,程序的通信都异常(每次重启后只发出一帧报文,间隔很久又会发出一帧报),但是诊断功能是OK的。
图4:A分区升级失败后跳到B分区实际异常通信状态
问题分析
1)诊断功能OK的,说明程序没有跑死,上电只发一帧报文很像是应用满足条件关闭通信了。ECU在以下三个状态下会关闭通信。
. IGOFF
.低电压(低于6.5V)
.低功耗模式 && 没有处于EOL(End Of Line,下线模式)
第一个和第二个条件直接测试外部硬件输入可以确定不可能满足。第三个条件需要诊断触发,理论上是不可能满足条件。
初步结论1:不是外部硬件输入状态导致关闭通信,也不是诊断时间关闭通信。
2)尝试各种正常情况下的刷写操作
. 处于A分区,刷A分区
. 处于A分区,刷B分区
. 处于B分区,刷A分区
. 处于B分区,刷B分区
结果,无论最后是在A分区还是B分区,通信都是正常的。
初步结论2:正常情况下的程序刷写都成功,且通信正常。
3)问题发生后ECU就一直处于故障状态了,这个时候可以考虑使用调试器的热插拔功能(Hot Plug-in,不重新Download程序到ECU当中,直接进入调试模式,ECU中运行的还是故障状态下的程序)。
调试上位机:RH850提供的CS+
调试仿真器:瑞萨专用的E2
图5:CS+的热插拔选项
图6:CS+的调试器E2配置
图7:程序进入了低功耗状态下关闭通信的分支
按照1)中的分析,程序不可能进入低功耗状态下关闭通信的分支,除非是进行分支判断的全局变量被异常篡改了。
初步结论3:启动模式的全局变量被异常篡改,导致程序进入到低功耗模式下关闭通信了。
全局变量被异常篡改,一般是数组越界或者是指向全局变量的指针操作异常导致的,但是如果是这样的话,和升级没啥关系,无论最后跳到A分区还是B分区都会出现异常,所以应该不是程序本身的问题。
4)让测试同事在B分区进行故障注入测试。
. 当前处于B分区
. 升级B分区
. 跳过0x34开始传输数据服务
最后升级B分区失败,跳到A分区,A分区的通信是正常的。
初步结论4:B分区升级B分区进行故障注入后跳到A分区是正常的。
5)尝试自己复现问题。测试同事的测试用例是跳过0x34服务后开始传输数据,其实也就是A分区被擦除后升级失败,跳到了B分区。那么理论上我复现问题的时候,只要满足以下条件就能复现文:
. 当前处于A分区
. 开始升级程序
. 擦除完A分区数据
. 还没升级完A分区程序就断开物理连接,确保A分区升级失败
最后确实升级A分区失败,跳到了B分区,但是B分区的通信却是正常的。为什么自己的测试结果和测试同事的测试结果不一样了?-- 分析测试同事的测试用例:
. 开始升级
. 跳过0x34服务
. 0x36开始传输数据
和上面我的复现步骤对比,测试同学的测试用例因为跳过了0x34服务,所以ECU的A分区是完全被擦除的状态,我的操作是在程序刷写了一部分的情况下断开物理连接,所以A分区被擦除后又被写入部分数据。
6)模拟测试同事的测试步骤。
擦除完A分区数据后还没开始传输A分区的数据就立马断开物理连接。
成功复现问题!!!
分析5)和6)两种操作,不同点就是擦除完A分区后数据后又往A分区写入了部分数据。写入的部分数据影响了A分区程序的运行。
7)使用瑞莎公司提供的RFPV(Renesas Flash Programmer)将5)和6)两种操作后的程序都读出来进行对比。
图8:读取两种操作下的Flash中的程序
图9:使用hexview工具对比B分区通信异常和B分区通信正常下的程序
异常情况下的程序从0x40000开始处数据是被擦除的,正常情况下的程序的0x40000开始的程序是有数据的。
为啥A分区0x40000处开始的数据会影响B分区的程序运行?
8)查看A分区和B分区的链接文件
图10:A分区链接文件
图11:B分区链接文件
找到问题,A分区和B分区的标定数据用的是同一块Flash地址!
9)修改B分区链接文件
图12:修改B分区链接文件的标定量起始地址
最后上板验证通过,问题解决。
10)为啥标定量的数据被擦除后会影响到通信?-- 猜测是标定段数据被擦除后标定相关的协议数据读写异常,最后导致进行分支判断的全局变量被异常篡改了。目前还未想到验证猜想的办法。
总结
这个问题分析了足足一天,分析问题的过程很具有代表性:发现问题 --> 推测原因 -->验证猜想 --> 验证失败 -->对比分析推测-->猜测验证 -->成功解决,逐步抽丝剥茧,层层递进,最后解决问题。
希望对各位看官有所启示。中间还用到了调试器的热插拔功能,编程器的读取ECU程序的功能,hexview对比Hex文件的功能,这些功能在分析问题中经常用到。
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !