关于boot对app的校验
基础知识 :对单片机程序中.data、.bss和.text三种数据的解读 ;ARM C语言编程优化策略
UM2262_X_CUBE_SBSFU安全启动和固件更新软件入门
1、.bss段(Block Started by Symbol)
BSS段通常是指用来存放程序中未初始化的或者初始化为0的全局变量和静态变量的一块内存区域。特点是可读写的,在程序执行之前BSS段会被系统自动清0。。
2、.data段(data segment)
数据段通常是指用来存放程序中已初始化(非0)的全局变量的一块内存区域。数据段属于静态内存分配,特点是可读写的。
3、.text段(code segment/text segment)
代码段通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,通常属于只读,在代码段中也可能包含一些只读的常数变量。
2 为防止非赋值的变量被系统清零,可以用两种方法:主要用于参数的掉电存储(软复位设置保持RAM的供电),
MDK平台下Nordic系列芯片Noinit RAM的设置和应用探讨
应用场景的一些探讨:
- 在某些不掉电场景下代替flash存储达到变量的保持功能
这个功能可以配合flash存储,在短期内以Noinit RAM保持数据,在关键节点再将数据写进flash,以达到减少flash擦写次数的操作次数(特别是Nordic在协议栈操作下,flash写操作容易失败的情况下)。
- 系统的DEBUG定位
系统出现硬件错误的时候往往会进入到harfault中断服务线程,此时可以将系统进入harfault前的PC指针和一些详细的DEBUG信息写入Noinit RAM保存起来,等到复位启动后也可以将错误的DEBUG信息拿出来分析。
- 模拟RTC实时时钟的可记忆寄存器
这个用法下,RTC几乎可以不受复位的影响。
- 防止某些需要保持的数据在复位下不丢失
如果没有任何flash存储方式,可以尝试使用Noinit RAM代替其功能,在某些场景很实用
- 检测一个系统是否是人为复位还是意外硬件复位
人为复位之前,Nonit RAM写入某个非0xff的特定值,如果是人为操做复位,则复位后的变量是对应的特定值。如果是意外硬件复位,则就可以通过Nonit RAM检查出来
-
__attribute__((section("no_initialized"))) int i, j;
zidata = "non_initialized"
/* uninitialized data in non_initialized section * (without the pragma, would be in .bss section by default) */ int i, j; #pragma arm section zidata /* back to default (.bss section) */ int k = 0, l = 0; /* zero-initialized data in .bss section */
-
-
在ram里面设置noinit的范围,如何有bootload时,需要相同的设置,
将RAM映射到0x2000FFF0地址,也就是Noinit RAM部分 #define __noinit__ __attribute__((at(0x2000FFF0))) __noinit__ u32 noinit_data;
-
debug数据可以保持,system off唤醒后,数据改变有人说需要设置ram供电。
后备寄存器:
STM32共有42个16位后备寄存器,可以用来存储84个字节的用户数据。而所谓的后备寄存器,并不是真正的EEPROM。当VDD电源被切断,VBAT仍然保持供电,后备寄存器的内容才不会丢失。
在需要使用BKP寄存器时,需要先使能
IAP中的校验:
bootload利用eeprom/flash的一个变量来判断是否需要IAP升级的隐患,当APP存在看门狗,加入升级过程或其它原因APP出现问题时,系统会在《引导--引导程序检测到不需要IAP--跳转到应用程序--看门狗咬死--复位--引导》进入死循环,系统因为无法识别这种情况所以必须工程师亲自去现场解决。通过禁止系统启动时的变量初始化。在BootLoader与应用程序,都在同一个地址定义相同的变量,在非断电初始化的时候,此变量是不会复位的。在BootLoader中每初始化1次加1,在app中程序正常运行的地方清零。如果出现上述死循环超过一定次数,bootload就认为app出现问题,进行重新iap.
嵌入式程序中,为了增加对升级文件的校验,通常会在boot中对升级的bin文件读取一部分进行校验,通过则说明文件可靠否则丢弃。
具体办法:在keil的启动汇编文件定义一个段,然后在link.sct中将其加载上去,
eg1 :在起始0地址添加,缺点是因为起始0地址所以没有boot,app是不能单独启动的。
eg:利用中断向量表中的缺省(DCD后面为0)的部分进行校验
引申阅读:STM32启动文件详解, STM32F4的sct文件理解,STM32高级开发(8)-链接器与启动文件,gcc链接脚本和启动文件详解,《The GNU linker》
将变量和函数存在指定位置:__attribute__ ((attribute-list))
attribute-list:
- at addr存储在指定位置(flash :不小于0x08000000;RAM:不小于0X20000000)
- section "name"存在指定的段
- aligned (n):指定对齐方式,同时要考虑编译器平台的最小的字节对齐
- (__packed__):内存约束
__attribute__ ((packed)) 的做用就是告诉编译器取消结构在编译过程当中的优化对齐,按照实际占用字节数进行对齐,是GCC特有的语法(一大特点)。
packed属性:使用该属性可使得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,对域(field)是位对齐
- __attribute__函数属性(Function Attribute):
- 变量属性(Variable Attribute)
- 类型属性(Type Attribute)