嵌入式软件开发中一般会预留一些MCU资源(ROM,RAM,CPU Load等)以方便项目升级,即使是很成熟的产品,ROM资源也不会100%被使用。在嵌入式软件构建(Build)过程中,编译器(Compiler)和链接器(Linker)会放置对应的代码和常量数据到ROM中。没有被使用的ROM,编译器和链接器会填充0或者不做任何处理(保留ROM擦除之后的值):比如为了半字/字(16-bit Halfword/32-bit Word)对齐,编译器和链接器会填充0到相应的ROM字节 (8-bit Byte);而连续没有使用的ROM,编译器和链接器不做任何处理(保留ROM擦除之后的值0xFF)。正常情况下,MCU的程序指针(PC)会按照既定程序来运行。但是在有些极端情况下,程序指针有可能发生不可知的变化,从而指向了没有使用的ROM地址,如果相应地址包含的指令执行一些非期望的操作,产生的影响是未知的(注意:嵌入式系统中未知的影响有可能是非常严重的,特别是一些高安全性的嵌入式系统)。为了提高系统的健壮性,通常需要往没有使用的ROM填充相应的值,这个值可以让系统快速恢复到可靠的状态。
本文主要介绍如何在IAR Embedded Workbench中填充没有使用的ROM来提高系统的健壮性。
填充没有使用的ROM
在Linker中填充没有使用的ROM
在IAR Embedded Workbench工程选项(Options)里面Linker选项里面Checksum:勾选“Fill unused code memory”, Fill pattern里面填充相应的值(注意,该值与使用的MCU/CPU相关,具体需要参考对应的CPU指令手册。原则是该值能够让MCU/CPU快速恢复到指定的状态)。这里以ARM Cortex-M为例,0xFF对应的是未定义的指令(Undefined Instruction),运行改指令会触发对应的错误(Fault)。Start address和End address分别输入ROM的起始地址和结束地址。
构建(Build)成功之后,查看生成的map文件未使用的范围部分(Unused ranges):
下载到目标板进行调试。
首先打开Memory窗口查看未使用的ROM范围部分是不是之前指定填充的值:这里看到都是0xFF。
运行程序一段时间并暂停。打开Register窗口,查看PC值。正常情况下,PC值不会跑到未使用的范围部分:这里PC值是0x0800_89CA,不在未使用的范围部分(0x0800_221C ~ 0x0800_2FFF,0x0800_9274 ~ 0x080F_FFFF)。
强制将PC值改变到未使用的范围部分(0x0800_221C ~ 0x0800_2FFF,0x0800_9274 ~ 0x080F_FFFF),比如0x080F_FFFC:
运行程序。程序会跑到HardFault_Handler,因为执行未定义的指令会触发错误(Fault)。
(注意:HardFault_Handler里面具体的操作需要根据系统的需求来定,但是最终一定要复位让系统恢复到可靠的状态。)
可以查看对应的寄存器确认相关的Fault: Undefined instruction usage fault
总结
本文主要分析了没有使用的ROM的潜在风险并介绍了如何在IAR Embedded Workbench中填充没有使用的ROM来提高系统的健壮性。
审核编辑:郭婷
全部0条评论
快来发表一下你的评论吧 !