【嵌入式】__no_init不初始化变量的用法

in 默认分类 with 0 comment

前言

前些天写代码的时候遇到了一个情景,当使用者拿到一个新的卡片时,需要使用者插2次卡以激活读卡设备。这时候自然而然的我就想到了需要一个变量来保存插卡次数,但是这样问题来了,我们的读卡设备因为业务需要,在插卡后显示卡的状态后然后会马上进入休眠,那么我们定义的插卡次数变量就在重新激活时自然而然的就被复位初始化为0了,因此根本无法有效的记录插卡次数

解决

在推断出大概原因后,摆在我面前的就有2种方法可以解决。

解决方法 1 --- 永久存储
既然变量无法存在内存中,那么我们可以在掉电以前把这个变量写在永久存储里面,刚好我们选用的芯片就提供了2kb的内置FLASH供我们存储,我们可以在软件复位之前把这个变量写入到FLASH中,然后在上点的时候把它从FLASH中读取出来就好了。然后我上网查了查,发现读取芯片内置的FLASH速度挺慢的,而且这个读写FLASH的操作有点“重量级”,有没有一些更轻量级的方法呢?比如说,人为让他不会被初始化呢?

解决方法 2 --- __no_init
带着这样的疑问,我去咨询了大佬,他跟我说可以看看__no_init这个关键字,然后我上网查了查,才发现这个真的是一个神奇的关键字。
使用__no_init修饰的关键字,在系统上电的时候,将只会对这个关键字所修饰的变量分配内存空间但是却不会对其进行初始化!那么,我们的问题就迎刃而解了,用__no_init修饰这个变量,当它重新激活运行的时候,变量的值还会存在,而且速度比永久存储在FLASH或者EEPROM上快多了!

小尾巴

使用这个关键字,我们也可以在看门狗复位的时候记录下系统的状态,好及时做对应措施,恢复状态。

在使用的过程中,我想到了一个疑问,那就是这个变量在第一次上电的时候究竟是什么值?会是随机值吗?然后我又去问了问大佬,得到的回复是 0,后面,我用仿真器自己试了试(3次),发现读取到的值分别是 0x07,0x08, 0x08 样本太小也看不出个规律来,不过不是0,不知道是不是我的测试方法有问题?(全程连接ST-Link,但是每次都是重新烧录程序),后面我当它为0来进行测试,也没出现问题。有待仔细验证【我觉得是我的测试方法有问题啦,毕竟全程都是接着ST-Link,供电没停止过,而且读卡设备也有内置电池……】