一、no_init段是什么
noinit段指的是芯片SRAM的一块内存区域(注意是RAM区而非Flash),在该段定义的变量、或者函数,在除了掉电之外的任何芯片复位的情况下都不会被重新初始化。
二、no_init有什么用处
no_init段常用来保存一些敏感信息,特殊应用场合下的不能被复位的数据或者做复位判断标志等数据,个人感觉这个数据段的用途还是非常广的,且很好用。
三、no_init变量、函数怎么创建
本章节以NXP S32K系列芯片为例介绍no_init段的内存分配,变量创建方法。
方法一:
直接使用__no_init关键字定义,例如:定义一个8位的无符号整型no_init的变量。
typedef unsigned char uint8;
__no_init uint8 temp;
方法二
使用预编译指令#pragma定义,例如:
#pragma object_attribute=__no_init
uint8 temp;
方法三
使用pragma location指定变量的位置,例如:
#pragma location =".noinit"
uint8 ResetNoinitCount;
以上几种方法,都是使用的芯片分配的no_init内存地址,函数的定义方法类似,这种方法可能存在问题。
下面将以NXP S32K系列芯片为例,介绍一种自己划分一块内存(ram),并将该内存空间设置为noinit段的方法,该块内存区域的init是通过startup文件由用户自己控制的。
自定义no_init块
首先,定义一块region区域NOINIT_RAM ,并为它在RAM中分配一块内存地址;然后定义一块block,用来表示Noinit的逻辑存储位置;最后把定义的block,存放到内存中。
/*首先定义一块region*/
define region NOINIT_RAM = int_memory:[from (0x1FFF8000) size (0x400)];
define block __NOINIT_RAM {
section .noinit_1,
};
place in NOINIT_RAM { block __NOINIT_RAM };
通过上面的方法,可以实现自定义no_init段,接着就可以使用第三节的方法定义变量和函数。
四、注意事项
在定义no_init变量时,有以下几点需要注意:
- no_init段内存块是分配的在RAM中,且不能超过芯片的RAM块内存地址。
- 确保no_init段所在的内存地址不会被初始化清空
五、疑问
为什么直接使用系统的no_init段创建的变量,不能够实现Noinit?