全域性變數中斷原子操作 微控制器中斷全域性變數保護方法

2021-10-16 21:35:56 字數 2214 閱讀 6122

首先要明白這幾個知識點:關鍵字volatile的使用,原子操作,臨界區的使用。明白的直接跳到文中的4.全域性變數的使用及保護處檢視。

1.關鍵字volatile

關鍵字volatile用於告訴編譯器,說明被修身的變數可能會被意想不到地改變,防止編譯器對**進行優化。

比如如下程式:1ucnms=0x65;

2ucnms=0x66;

3ucnms=0x67;

4ucnms=0x68;

上述4條語句,如果變數在宣告的時候(unsigned char ucnms;)沒有使用volatile,那麼編譯器有可能對其優化,只編譯最後一條語句ucnms=0x68;(即忽略前三條語句,只產生一條機器彙編**);如果變數在宣告的時候(volatile unsigned char ucnms;)使用了volatile,則編譯器會逐一地進行編譯並產生四條相應的機器**(產生四條**)。

精確地說就是,編譯器在編譯這個變數語句時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。所以下面幾個情況在宣告的時候需要用volatile關鍵字對其修飾:

1)並行裝置的硬體暫存器(如:狀態暫存器)

2)乙個中斷服務子程式中會訪問到的非自動變數(non-automatic variables)

3)多執行緒應用中被幾個任務共享的變數

2.原子操作

原子操作可以理解為不被打斷的操作,可以是乙個步驟的操作,也可以是多個步驟的操作,總之確保操作不被打斷。

3.臨界區

指的是乙個訪問共用資源(例如:共用裝置或是共用儲存器)的程式片段,而這些共用資源又無法同時被多個執行緒訪問的特性。

4.全域性變數的使用及保護

微控制器裸機程式設計,使用全域性變數時,一般是乙個或多個*.c檔案(或模組)中會使用到某個全域性變數(假設為a),還有中斷中也會用到這個全域性變數。這樣在使用時就要考慮變數的安全性。微控制器裸機程式設計是前後臺系統,如下圖:

微控制器裸機程式設計前後臺系統

首先要明白大迴圈(後台)對這個變數的訪問是依次的,不管全域性變數a是在哪乙個模組或者*.c檔案中,每乙個時刻只有乙個地方對變數a訪問。然後中斷和中斷巢狀程式中也會有對全域性變數a的訪問。

於是就存在這樣的問題,大迴圈(後台)在訪問全域性變數a時(比如說訪問到一半時),被中斷(前台)程式打斷並修改了全域性變數a,這樣大迴圈(後台)程式再次對全域性變數a訪問,就會導致訪問到的a存在不確定性。從而會影響程式的不正常執行。

這樣就可以很明確的知道,只要在大迴圈(後台)訪問a時,不讓中斷(前台)打斷其訪問即可。確保對a的訪問是原子操作。於是就有這樣的解決方法:關中斷-->>全域性變數a-->>開中斷

有的時候,如果訪問變數a的過程比較長,可以對全域性變數a做乙個副本拷貝a,用拷貝的a作為模組處理的資料。於是就有了這樣:關中斷-->>訪問全域性變數a-->>副本拷貝a-->>開中斷->>操作副本拷貝a

這種複雜的情況也可以做乙個鎖這樣做:

大迴圈(後台):關中斷-->>上鎖-->>開中斷-->>訪問變數a-->>關中斷-->>解鎖-->>開中斷

中斷(前台):如果是解鎖的,操作全域性變數a,如果是上鎖的就不操作

當然,如果訪問全域性變數a本身就是乙個原子操作(比如一條指令就可以訪問完成),這樣也就不需要做開關中斷的處理了。

示例1:禁止中斷方法保護全域性變數

大迴圈(後台)et0=0; //禁止定時中斷

訪問全域性變數a;

其他**部分;

et0=1; //開啟允許定時中斷

定時器中斷(前台)操作全域性變數a;

示例2:加鎖的方法保護全域性變數

大迴圈(後台)et0=0; //禁止定時中斷

lock = 1;

et0=1; //開啟允許定時中斷

訪問全域性變數a;

其他**部分;

et0=0; //禁止定時中斷

lock =0;

et0=1; //開啟允許定時中斷

定時器中斷(前台)if(lock ==0) 操作全域性變數a;

else

示例3:加鎖的方法保護全域性變數

大迴圈(後台)lock = 1;//若此條語句對應彙編指令是原子操作可以不用開關中斷保護此鎖

訪問全域性變數a;

其他**部分;

lock =0;//若此條語句對應彙編指令是原子操作可以不用開關中斷保護此鎖

定時器中斷(前台)if(lock ==0) 操作全域性變數a;

else

總結下:中斷全域性變數盡量要用volatile修飾,中斷全域性變數要原子操作訪問,要時刻明白中斷全域性變數是臨界區資源,共享訪問時需要保護。

全域性變數中斷原子操作 微控制器中斷全域性變數保護方法

首先要明白這幾個知識點 關鍵字volatile的使用,原子操作,臨界區的使用。明白的直接跳到文中的4.全域性變數的使用及保護處檢視。1.關鍵字volatile 關鍵字volatile用於告訴編譯器,說明被修身的變數可能會被意想不到地改變,防止編譯器對 進行優化。比如如下程式 1ucnms 0x65 ...

51微控制器 中斷

一 中斷的概念 cpu在處理某一事件a時,發生了另一事件b請求cpu迅速去處理 中斷發生 cpu暫時中斷當前的工作,轉去處理事件b 中斷響應和中斷服務 待cpu將事件b處理完畢後,再回到原來事件a被中斷的地方繼續處理事件a 中斷返回 這一過程稱為中斷 二 中斷源 在51微控制器中有5個中斷源 中斷號...

微控制器中斷原理

微控制器在自主執行的時候一般是在執行乙個死迴圈程式,在沒有外界干擾 輸入訊號 的時候它基本處於乙個封閉狀態。比如乙個電子時鐘,它會按時 分 秒的規律來自主執行並通過輸出裝置 如液晶顯示屏 把時間顯示出來。在不需要對它進行調校的時候它不需要外部干預,自主封閉地執行。如果這個時鐘足夠準確而又不掉電的話,...