0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一種修飾符能使變量在處理器復(fù)位而不被初始化

黃工的嵌入式技術(shù)圈 ? 來源:黃工的嵌入式技術(shù)圈 ? 2020-03-14 15:01 ? 次閱讀

先了解一下修飾符知識

修飾符是用于限定類型以及類型成員申明的一種符號。如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)存中取值,而不是從寄存器或者緩存。

C++ JAVA中還有更多:

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”一直不變。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 處理器
    +關(guān)注

    關(guān)注

    68

    文章

    18926

    瀏覽量

    227218
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7575

    瀏覽量

    134046
  • static
    +關(guān)注

    關(guān)注

    0

    文章

    33

    瀏覽量

    10321
  • 初始化
    +關(guān)注

    關(guān)注

    0

    文章

    49

    瀏覽量

    11742
收藏 人收藏

    評論

    相關(guān)推薦

    Keil中變量不被初始化方法

    有些時候我們的應(yīng)用過程中要求變量有連續(xù)性,或者現(xiàn)場保留,例如Bootloader跳轉(zhuǎn),某種原因的復(fù)位過程中我們有些關(guān)鍵變量不能被初始化
    的頭像 發(fā)表于 08-30 11:47 ?195次閱讀
    Keil中<b class='flag-5'>變量</b><b class='flag-5'>不被</b><b class='flag-5'>初始化</b>方法

    DSP復(fù)位地址不在0x20b00000導(dǎo)致仿真時初始化失敗

    在對dsp仿真時,點擊systeam reset后,復(fù)位地址不在0x20b00000,出現(xiàn)這種現(xiàn)象后,使用XDS560仿真仿真程序的初始化就會出問題,初始化失敗,使用XDS100的仿
    發(fā)表于 08-12 09:56

    請問STM8S207如何讓編譯stvd+cosmic復(fù)位后不給這個變量初始化成0?

    ,上電時開始為0V,過會充滿電為VCC),上電標志0則讀出EEPROM數(shù)據(jù),為1則為看門狗熱復(fù)位不讀EEPROM,變量value仍保持原數(shù)據(jù)繼續(xù)計數(shù)。 我沒有初始化但編譯
    發(fā)表于 05-09 08:01

    淺析C語言中的變量修飾符

    、修飾符類型51單片機采用哈佛結(jié)構(gòu)。內(nèi)存空間編址有重疊??梢?b class='flag-5'>在不同總線上定義不同的變量KEILC51中定義了data、idata、xd
    的頭像 發(fā)表于 04-15 08:10 ?337次閱讀
    淺析C語言中的<b class='flag-5'>變量</b><b class='flag-5'>修飾符</b>

    鴻蒙ArkUI開發(fā)實戰(zhàn):制作個【簡單計數(shù)

    `@Entry`?修飾符表示個頁面的入口,它需要在?`main_pages.json`?配置才可以設(shè)備上正常顯示,?`@Component`?修飾符表示?`Index`?是
    的頭像 發(fā)表于 04-08 18:05 ?444次閱讀
    鴻蒙ArkUI開發(fā)實戰(zhàn):制作<b class='flag-5'>一</b>個【簡單計數(shù)<b class='flag-5'>器</b>】

    字符型、指針型等變量等該如何初始化

     對于數(shù)值類型的變量往往初始化為0,但對于其他類型的變量,如字符型、指針型等變量等該如何初始化呢?
    的頭像 發(fā)表于 03-18 11:02 ?892次閱讀

    rtc時鐘如何在啟動后會不被初始化為默認值?

    請教個關(guān)于rtc的問題。 1.我發(fā)現(xiàn)我的rtc時鐘根據(jù)例子,啟動后會被初始化為默認值。 但是如果我想在軟件復(fù)位或者看門狗復(fù)位的情況下,不
    發(fā)表于 02-21 06:08

    使用SEGGER Embedded Studio編譯發(fā)現(xiàn)變量無法自動初始化

    使用SEGGER Embedded Studio編譯發(fā)現(xiàn)變量無法自動初始化, 例如聲明靜態(tài)變量static uint8_t i = 0;這種寫法i成了靜態(tài)
    發(fā)表于 01-11 14:21

    labview運行后如何初始化

    LabVIEW是款強大的圖形編程軟件,在運行之前通常需要進行初始化操作。本文將詳細介紹LabVIEW運行前的初始化過程,并提供了
    的頭像 發(fā)表于 12-28 17:24 ?2065次閱讀

    自動初始化機制原理詳解

    自動初始化機制是指初始化函數(shù)不需要被顯式調(diào)用,只需要在函數(shù)定義處通過宏定義的方式進行申明,就會在系統(tǒng)啟動過程中被執(zhí)行。這篇文章就來探索下其中的奧秘, 簡單理解其原理!
    的頭像 發(fā)表于 12-16 09:33 ?825次閱讀
    自動<b class='flag-5'>初始化</b>機制原理詳解

    C語言編程時,各種類型的變量該如何初始化?

    C語言編程時,各種類型的變量該如何初始化? C語言中,每個變量都需要在使用之前進行初始化。初始化
    的頭像 發(fā)表于 12-07 13:53 ?936次閱讀

    嵌入式軟件開發(fā)常用的關(guān)鍵字和運算

    volatile是個特征修飾符,提醒編譯它后面所定義的變量隨時都有可能改變,因此編譯后的程序每次需要存儲或讀取這個變量的時候,告訴編譯
    的頭像 發(fā)表于 12-04 12:22 ?504次閱讀

    實戰(zhàn)經(jīng)驗 | Keil、IAR、CubeIDE 中變量不被初始化方法

    關(guān)鍵詞:不被初始化,編譯環(huán)境 目錄預(yù)覽 1、前言 2、IAR 實現(xiàn)變量初始化方法 3、Keil 實現(xiàn)變量
    的頭像 發(fā)表于 11-24 18:05 ?3020次閱讀

    java內(nèi)部類可以用public修飾

    使用任意訪問權(quán)限修飾符,包括public、protected、默認和private。 方法內(nèi)部類只能使用默認訪問權(quán)限,即不加任何訪問修飾符。 使用public修飾的內(nèi)部類 內(nèi)部類使用p
    的頭像 發(fā)表于 11-21 10:23 ?847次閱讀

    嵌入式全局變量初始化原理詳解

    全局變量初始值,是在哪里賦值的?
    的頭像 發(fā)表于 10-27 10:15 ?970次閱讀
    嵌入式全局<b class='flag-5'>變量</b>的<b class='flag-5'>初始化</b>原理詳解