1. 程式人生 > >STM32F0開發筆記8: 在keil中使用不初始化變數

STM32F0開發筆記8: 在keil中使用不初始化變數

我們進行程式設計的時候,都會知道,系統上電或復位時,會執行變數初始化操作,但是有些情況下,我們並不希望變數初始化,例如,在系統異常復位發生後,我們希望系統能夠迅速恢復復位前的現場狀況,這樣就希望變數能夠保留原先的值,而不被初始化。實際上,大家都知道,變數是儲存在RAM中的,只要不掉電,變數的數值是不會改變的,只要我們不讓系統進行初始化操作就可以了。

    不同的編譯環境,有不同的設定方法,本文介紹在Keil中設定不初始化變數的方法。在這裡需要說明的是,網上介紹了許多的設定方法,但並不是所有的方法都起作用,本文將介紹一種最為直接的方法。

    1、開啟Options for Target對話方塊Linker標籤,勾選掉Use Memory Layout from Target Dialog,這個選項的意思是使用Target標籤進行連結設定,所以在其勾選的情況下,分散檔案是不能自己編輯的,勾選掉以後,我們就可以進行分散檔案的設定了。

    2、點選分散檔案後面的Edit按鈕,開啟分散檔案,按下圖所示的方法,增加節點。原先僅有一個RAM節點,其起始地址是0x20000000,其長度是0x00008000。我們新編輯的分散檔案,將RAM分為2部分,第1部分長度為0x7000,第2部分長度為0x1000,並將第2部分設定為UNINIT,也就是不初始化,顯式節點名為NO_INIT。

    3、有了上述設定後,我們就可以進行變數設定了,在這裡需要注意的是變數需定義為全域性變數,且不能賦初值,後面要加入存放的節點,如下面程式所示。我們定義了5個變數,第1個為u16_Start,後面為4個數組(僅是舉例子,沒有什麼實際意義)。

uint16_t u16_Start __attribute__((section("NO_INIT"),zero_init));                        
uint16_t u16_a[2]  __attribute__((section("NO_INIT"),zero_init));            
uint16_t u16_b[2]  __attribute__((section("NO_INIT"),zero_init));        
uint16_t u16_c[2]  __attribute__((section("NO_INIT"),zero_init));            
uint16_t u16_d[2]  __attribute__((section("NO_INIT"),zero_init));
    4、正確編譯後,將程式下載到目標板,我們就可以觀察到這些變數不會因為微控制器復位,而被初始化了。不過這又產生了一個新的問題,由於我們沒有給這些變數賦初值,當系統上電時,這些變數的值是隨機的,所以我們還需要辨別是系統上電,還是系統復位,使用下面的程式就可以了,這也是變數u16_Start的作用。當系統上電時,由於RAM是剛剛加電,所以變數u16_Start為12345的可能性幾乎為0,我們認為這是系統上電,將u16_Start設定為12345後,並初始化這些變數。當系統復位時,u16_Start中的數值仍然保留,所以還為12345,這樣就不再初始化變數。

    if (u16_Start != 12345)
    {
        u16_Start = 12345;
        u16_a[0] = 0;
        u16_a[1] = 0;
        u16_b[0] = 0;
        u16_b[1] = 0;
        u16_c[0] = 0;
        u16_c[1] = 0;
        u16_d[0] = 0;
        u16_d[1] = 0;
    }
原創性文章,轉載請註明出處
CSDN:http://blog.csdn.net/qingwufeiyang12346。
--------------------- 
作者:snmplink 
來源:CSDN 
原文:

https://blog.csdn.net/qingwufeiyang12346/article/details/79520095