先了解一下修飾符知識
修飾符是用于限定類型以及類型成員申明的一種符號。如C語言中常見的修飾符:
1.static靜態(tài)修飾符:修飾變量,函數(shù)。作用域:變量僅僅在本文件可見,函數(shù)在本文件可以被調(diào)用;
2.extern聲明修飾符:修飾變量,函數(shù)。修飾變量時候,變量的聲明在外面;
3.const常量修飾符:修飾變量,函數(shù)。修飾變量時候,不能被重復(fù)賦值,只能放在只讀段中;
4.volatile不穩(wěn)定變量修飾符:這個變量不好翻譯,在c中的作用大概有兩點意思:A.表示變量是易失的,易變的;B.強制訪存操作,防止編譯器去優(yōu)化,告訴編譯器每次必須去內(nèi)存中取值,而不是從寄存器或者緩存。
public公共訪問修飾符、private私有訪問修飾符、protected保護訪問修飾符、friendly、abstract等。
了解了修飾符之后,看見本文標題就知道本文提供的那個修飾符對于變量來說是比較重要的。
之前寫過一篇文章【CM3(STM32)內(nèi)核復(fù)位與系統(tǒng)復(fù)位區(qū)別及應(yīng)用】,講述了系統(tǒng)和內(nèi)核復(fù)位之后存在差異,其實主要就是說內(nèi)核復(fù)位之后,芯片外設(shè)資源沒有進行復(fù)位的操作。
而本文說的修飾符,修飾的變量位于RAM中,在默認情況下,編譯器會將其變量存放在主RAM中,并在啟動時對其進行初始化。而本文說的__no_init類型修飾符使編譯器把變量放在非易失RAM區(qū)中,在啟動時也不對它們進行初始化,也就是說__no_init在系統(tǒng)啟動時不初始化變量。
什么情況下使用這修飾符使系統(tǒng)禁止變量的初始化?
看門狗復(fù)位的現(xiàn)場恢復(fù),如果初始化了就完全不可恢復(fù)了。
在Keil和IAR集成開發(fā)環(huán)境下,這個修飾符有所不同;Keil中不集成這個修飾符,需要配置; 而IAR中集成這個修飾符,可直接使用。
Ⅰ
Keil中__no_init的配置和使用
在Keil中,__no_init不是集成在開發(fā)環(huán)境中,故需要配置,配置之后就可以使用了。
1.宏定義__no_init
#define __no_init __attribute__((zero_init))
2.在工程選項中配置__no_init
Project -> Options for Targets -> Target,里面右下有個NoInit,這個就是需要我們配置的區(qū)域(可設(shè)定某一區(qū)域);
3.使用方法
__no_init uint16_t Cnt_NoInit;
提示:不能初始化這個變量。
Ⅱ
IAR中的__no_init
IAR中的“__no_init”是一個關(guān)鍵字,你會發(fā)現(xiàn)在使用這個修飾符之后,字體都是關(guān)鍵字顏色。
__no_init uint16_t Cnt_NoInit;
Ⅲ
例程源代碼下載與說明
代碼下載地址:
http://pan.baidu.com/s/1hskScba
兩個工程名稱:
1.STM32F103ZE(Keil)_復(fù)位不初始化變量NoInit
2.STM32F103ZE(IAR)_復(fù)位不初始化變量NoInit
本文提供的例程是一個Demo比較簡單,但具有實際意義。Keil和IAR工程實現(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ù)位
}
}
不初始化變量,則會打印如下消息:
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;
則會打印出如下信息
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
相信聰明的你,看了上面例子會明白為什么沒有初始化的變量“Cnt_NoInit”在變化,而初始化了的“Cnt_Init”一直不變。
-
處理器
+關(guān)注
關(guān)注
68文章
19435瀏覽量
231306 -
C語言
+關(guān)注
關(guān)注
180文章
7615瀏覽量
137827 -
static
+關(guān)注
關(guān)注
0文章
33瀏覽量
10413 -
初始化
+關(guān)注
關(guān)注
0文章
50瀏覽量
11954
發(fā)布評論請先 登錄
相關(guān)推薦
EE-88:使用21xx編譯器在C中初始化變量
![EE-88:使用21xx編譯<b class='flag-5'>器</b><b class='flag-5'>在</b>C中<b class='flag-5'>初始化</b><b class='flag-5'>變量</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
OMAP5912多媒體處理器初始化參考指南
![OMAP5912多媒體<b class='flag-5'>處理器</b><b class='flag-5'>初始化</b>參考指南](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
Keil中變量不被初始化方法
![Keil中<b class='flag-5'>變量</b><b class='flag-5'>不被</b><b class='flag-5'>初始化</b>方法](https://file.elecfans.com/web2/M00/09/16/pYYBAGD0FvWAeWpFAAAb1Fux1oA753.jpg)
鴻蒙原生應(yīng)用元服務(wù)開發(fā)-倉頡基本概念程序結(jié)構(gòu)
DSP復(fù)位地址不在0x20b00000導(dǎo)致仿真時初始化失敗
ESP32S2在復(fù)位初始化的時最初的GPIO的狀態(tài)是什么樣的?
請問STM8S207如何讓編譯器stvd+cosmic復(fù)位后不給這個變量初始化成0?
STM32F103RC變量初始化問題求解
鴻蒙ArkUI開發(fā)實戰(zhàn):制作一個【簡單計數(shù)器】
![鴻蒙ArkUI開發(fā)實戰(zhàn):制作<b class='flag-5'>一</b>個【簡單計數(shù)<b class='flag-5'>器</b>】](https://file1.elecfans.com/web2/M00/C8/58/wKgaomYTwG6AFPeZAAKTNzXb_ig342.jpg)
stm32如何設(shè)置ADC初始化才能使能改寄存器位?
字符型、指針型等變量等該如何初始化
MCU單片機GPIO初始化該按什么順序配置?為什么初始化時有電平跳變?
![MCU單片機GPIO<b class='flag-5'>初始化</b>該按什么順序配置?為什么<b class='flag-5'>初始化</b>時有電平跳變?](https://file1.elecfans.com/web2/M00/C1/7A/wKgaomXWul2AKoIuAAAxlaP9tbg978.png)
評論