esp32 c2藍牙wifi芯片模塊樂鑫科技代理商嵌入式系統存儲資源,嵌入式系統通常包含多種類型的存儲器,例如 RAM,ROM 和寄存器等。而RAM又包括 CPU 內部RAM被外部 RAM。同一系統中,不同類型存儲器映射到處理器存儲空間的不同地址區間。嵌入式系統中存儲設備的多樣性和地址的不連續性,增加了在程序中管現內存的復雜程度。
C 語言存儲修飾符
在C語言中,可以使用修飾符指定變量的存儲特性。在聲明變量前加上特定修飾符,可以限定該變量的存儲類型。esp32 c2藍牙wifi芯片模塊樂鑫科技代理商常用的修飾符有 auto、static、extern、const、register 和 volatile。在嵌人式 C語言序中,const、register 和 volatile 有特殊的作用。
const 修飾的對象為常量。修飾對象可以是數據,也可以是指針。esp32 c2藍牙wifi芯片模塊樂鑫科技代理商在下列例子中,第 1行聲明常量k;第 2行聲明指針常量 ptr;第 3 行聲明常量數據。
1 const int k= 1024; //k 的值不可改變
2 int * const ptr; //ptr 地址不可改變
3 const int *ptr; //ptr 位置的數據不可改變
在嵌入式系統中,常把 const 修飾的全局和靜態變量分配到 ROM 空間。例如,“int;”中的 k分配在可寫的 RAM空間中,“const int k;”中的k分配在不可寫的 ROM空間。
用 register 修飾使用頻率較高的局部變量,命令編譯器盡可能地將變量存在CPU 內部寄存器中,而不是通過內存尋址訪問,以提高效率。RISC-V 有 32 個通用寄存器,可以同時存儲多個變量。esp32 c2藍牙wifi芯片模塊樂鑫科技代理商在示例 8.1 中,左側列出了使用修飾符 register后C 語言源程序編譯生成的匯編語言,右側是未使用 register C 語言源程序編譯后生成的匯編語言??梢钥闯?沒有使用修飾符時,變量 a 和 b 保存在棧中;添加修飾符后,變量 a 保存在寄存器 ra 中,變量 b 保存在寄存器 s0 中。
示例8.1: register 修飾符對編譯后生成代碼的影響。
/*
int main(void)
( register int a= 50, b = 150;
int value = max(a,b) ;
......}
*/
Main:
......
li ra,50 //ra= 50,ra寄存器變量
ali s0,150 //s0=150,s0 寄存器變量 b
mv a1,s0 //al = b
mv a0,ra //a0 = a
call max //調用函數 max
......
--------------------------------------------------------------------------------------------------
/*
int main(void)
( int a= 50, b = 150;
int value = max(a,b) ;
......}
*/
Main:
......
li a5,50 //a5 = 50
sw a5,8(sp) //a=a5,a在棧中
li a5,150 //a5 = 150
sw a5,4(sp) //b= 150,b在棧中
lw al,4(sp) //a1 = b
lw a0,8(sp) //a0 =a
call max //調用函數 max
......
使用register 修飾變時,要求變量必須是處理內核所支持的數據類型,并且數據不大于不大于處理器所支持的整數。esp32 c2藍牙wifi芯片模塊樂鑫科技代理商另外,使用 register修飾的變量不能使用“&”操作獲取地址。
如果使用 register 修飾的變量數目大于 RISC-V 可用的寄器數,則編譯器將自動忽略所添加的修飾符register。
在嵌入式系統應用程序中,通常在 I/0 端口指針變量前添加修飾符 volatile,保證訪問數據的時效性。常見的使用場景包括中斷服務程序、訪問系統中的外部器件以及多個任務訪問共享變量。
讀取 volatile 修飾后的變量時,將直接讀取目標內存地址或 I/0 寄存器中的內容,而不是從臨時寄存器、棧中的臨時變量以及系統緩存中復制內容。
經 volatile 修飾的任何變量的讀/寫操作語句都不會被優化。esp32 c2藍牙wifi芯片模塊樂鑫科技代理商例如,在示例 8.2中,使用賦值語句 ioport 產生脈沖,前 3 條寫語句可能被編譯器優化刪除,從而導致輸出波形錯誤。如果將“char * ioport”改寫成“volatile char * ioport”,那么前3條寫語句就不會被編譯器刪除。
示例8.2:I/O模擬輸出時序。
volatile unsigned char * ioport;
*ioport = 0;
*ioport = 1;
*ioport = 1;
*ioport= 0;