先了解一下修飾符知識(shí)
修飾符是用于限定類型以及類型成員申明的一種符號(hào)。如C語(yǔ)言中常見(jiàn)的修飾符:
1.static靜態(tài)修飾符:修飾變量,函數(shù)。作用域:變量?jī)H僅在本文件可見(jiàn),函數(shù)在本文件可以被調(diào)用;
2.extern聲明修飾符:修飾變量,函數(shù)。修飾變量時(shí)候,變量的聲明在外面;
3.const常量修飾符:修飾變量,函數(shù)。修飾變量時(shí)候,不能被重復(fù)賦值,只能放在只讀段中;
4.volatile不穩(wěn)定變量修飾符:這個(gè)變量不好翻譯,在c中的作用大概有兩點(diǎn)意思:A.表示變量是易失的,易變的;B.強(qiáng)制訪存操作,防止編譯器去優(yōu)化,告訴編譯器每次必須去內(nèi)存中取值,而不是從寄存器或者緩存。
public公共訪問(wèn)修飾符、private私有訪問(wèn)修飾符、protected保護(hù)訪問(wèn)修飾符、friendly、abstract等。
了解了修飾符之后,看見(jiàn)本文標(biāo)題就知道本文提供的那個(gè)修飾符對(duì)于變量來(lái)說(shuō)是比較重要的。
之前寫過(guò)一篇文章【CM3(STM32)內(nèi)核復(fù)位與系統(tǒng)復(fù)位區(qū)別及應(yīng)用】,講述了系統(tǒng)和內(nèi)核復(fù)位之后存在差異,其實(shí)主要就是說(shuō)內(nèi)核復(fù)位之后,芯片外設(shè)資源沒(méi)有進(jìn)行復(fù)位的操作。
而本文說(shuō)的修飾符,修飾的變量位于RAM中,在默認(rèn)情況下,編譯器會(huì)將其變量存放在主RAM中,并在啟動(dòng)時(shí)對(duì)其進(jìn)行初始化。而本文說(shuō)的__no_init類型修飾符使編譯器把變量放在非易失RAM區(qū)中,在啟動(dòng)時(shí)也不對(duì)它們進(jìn)行初始化,也就是說(shuō)__no_init在系統(tǒng)啟動(dòng)時(shí)不初始化變量。
什么情況下使用這修飾符使系統(tǒng)禁止變量的初始化?
看門狗復(fù)位的現(xiàn)場(chǎng)恢復(fù),如果初始化了就完全不可恢復(fù)了。
在Keil和IAR集成開(kāi)發(fā)環(huán)境下,這個(gè)修飾符有所不同;Keil中不集成這個(gè)修飾符,需要配置; 而IAR中集成這個(gè)修飾符,可直接使用。
Ⅰ
Keil中__no_init的配置和使用
在Keil中,__no_init不是集成在開(kāi)發(fā)環(huán)境中,故需要配置,配置之后就可以使用了。
1.宏定義__no_init
#define __no_init __attribute__((zero_init))
2.在工程選項(xiàng)中配置__no_init
Project -> Options for Targets -> Target,里面右下有個(gè)NoInit,這個(gè)就是需要我們配置的區(qū)域(可設(shè)定某一區(qū)域);
3.使用方法
__no_init uint16_t Cnt_NoInit;
提示:不能初始化這個(gè)變量。
Ⅱ
IAR中的__no_init
IAR中的“__no_init”是一個(gè)關(guān)鍵字,你會(huì)發(fā)現(xiàn)在使用這個(gè)修飾符之后,字體都是關(guān)鍵字顏色。
__no_init uint16_t Cnt_NoInit;
Ⅲ
例程源代碼下載與說(shuō)明
代碼下載地址:
http://pan.baidu.com/s/1hskScba
兩個(gè)工程名稱:
1.STM32F103ZE(Keil)_復(fù)位不初始化變量NoInit
2.STM32F103ZE(IAR)_復(fù)位不初始化變量NoInit
本文提供的例程是一個(gè)Demo比較簡(jiǎn)單,但具有實(shí)際意義。Keil和IAR工程實(shí)現(xiàn)的功能一樣。
源代碼:
__no_inituint16_t Cnt_NoInit;
uint16_t Cnt_Init = 100;
intmain(void)
{
System_Initializes();
printf("Start...\n"); //復(fù)位打印
while(1)
{
printf("Cnt_NoInit = %d\n", Cnt_NoInit); //打印變量
Cnt_NoInit++;
if(Cnt_NoInit > 1000)
{
Cnt_NoInit = 0;
}
printf("Cnt_Init = %d\n", Cnt_Init);
Cnt_Init++;
if(Cnt_Init > 1000)
{
Cnt_Init = 0;
}
LED_ON;
TIMDelay_Nms(500);
LED_OFF;
TIMDelay_Nms(500);
NVIC_SystemReset(); //系統(tǒng)復(fù)位
}
}
不初始化變量,則會(huì)打印如下消息:
Start...
Cnt_NoInit = 0
Cnt_Init = 100
Start...
Cnt_NoInit = 1
Cnt_Init = 100
Start...
Cnt_NoInit = 2
Cnt_Init = 100
Start...
Cnt_NoInit = 3
Cnt_Init = 100
如果Cnt_NoInit不被修飾成不初始化
uint16_t Cnt_NoInit;
uint16_t Cnt_Init = 100;
則會(huì)打印出如下信息
Start...
Cnt_NoInit = 0
Cnt_Init = 100
Start...
Cnt_NoInit = 0
Cnt_Init = 100
Start...
Cnt_NoInit = 0
Cnt_Init = 100
Start...
Cnt_NoInit = 0
Cnt_Init = 100
相信聰明的你,看了上面例子會(huì)明白為什么沒(méi)有初始化的變量“Cnt_NoInit”在變化,而初始化了的“Cnt_Init”一直不變。
-
處理器
+關(guān)注
關(guān)注
68文章
19740瀏覽量
232918 -
C語(yǔ)言
+關(guān)注
關(guān)注
180文章
7628瀏覽量
139758 -
static
+關(guān)注
關(guān)注
0文章
34瀏覽量
10571 -
初始化
+關(guān)注
關(guān)注
0文章
50瀏覽量
12029
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
EE-88:使用21xx編譯器在C中初始化變量

OMAP5912多媒體處理器初始化參考指南

基于旋轉(zhuǎn)平移解耦框架的視覺(jué)慣性初始化方法

TMS320C6000 McBSP初始化

復(fù)位電路介紹 復(fù)位電路的原理及作用
如何在i.MX RT微控制器上初始化LWIP協(xié)議棧

Keil中變量不被初始化方法

評(píng)論