天天看點

在keil中使用不初始化變量

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

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

1、打開Options for Target對話框Linker标簽,勾選掉Use Memory Layout from Target Dialog,這個選項的意思是使用Target标簽進行連結設定,是以在其勾選的情況下,分散檔案是不能自己編輯的,勾選掉以後,我們就可以進行分散檔案的設定了。
           
在keil中使用不初始化變量

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

在keil中使用不初始化變量

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;
	}
           

//=====================================================================

可以有另外的方法:

最近一個項目需要儲存一下臨時資料,而産品容易受幹擾而複位。是以需要儲存一下資料,那麼隻有在系統複位時候不再初始化變量即可。對應MDK(keil)來說是一個比較麻煩的問題。通過網絡上找了大量資料和測試發現終于可以了。

如果要實作以上要求,必須設定兩點,缺一不可:
           
  1. 在MDK的選項中設定如下:

    2

    在keil中使用不初始化變量
  2. 必須在程式代碼中如下編寫:

#define noinit attribute((zero_init)) // 變量不初始化為0

noinit int tmp; // 變量前加上宏__noinit__

當然也可以直接:

attribute((zero_init)) int tmp;

說明:noinit 不是mdk的關鍵字

//====================================================

參考文章:http://blog.csdn.net/qingwufeiyang12346