RAM與ROM
- 1、RAM與ROM
- 2、 bss、data、heap、stack、text詳細講解
- 3、詳細探討 TCM、OCRAM 和 HBNRAM 之間的區別及其具體作用。
- 3.1、TCM(Tightly Coupled Memory)
- 3.2、 OCRAM(On Chip RAM)
- 3.3、HBNRAM (Hibernate RAM)
- 3.4、總結
1、RAM與ROM
keil編譯完成后,會有提示,形如:
其中:
-
Code為代碼,本質上就是一大堆ARM指令;
-
RO為只讀的數據,下文的text段和constdata段屬于此屬性區。例如,char *name = “TOM”;//TOM三個字符就存放在ROM中作為RO-DATA;char cmd[] = “AT”;AT兩個字符會在RAM和FLASH中各有一份。有些常量會在RO區中,有些例如立即數,會直接被編譯在code區中。
-
RW為非0初始化的全局變量和靜態變量占用的RAM大小,下文中的.data段和.bss屬于RW區。注意:同時還要占用等量的ROM大小用于存放這些非0變量的初值;
-
ZI(zero initialize)沒有進行初始化或者初始化為0。(該區域3個用途:0初始化的全局和靜態變量+堆區+棧區)。
下面是keil自動生成的.map文件中的信息:
Flash的占用量就是上圖中:
- ROM Size的大小,它包含了①+②+③的大小【ARM指令代碼+只讀數據+非0初始化變量的初值】(Flash 占用大小 = .text 大小 + .data大小 + 其它section(如.bss, .stack, .heap等) 位置信息大小)
- RAM的占用量包含上述③+④的大小,也即【非0初始化變量、0初始化RAM(又分為0初始化靜態變量區+堆區+棧區)】(SRAM 占用大小 = .data 大小 + .bss 大小 + .stack大小 + .heap大小)
2、 bss、data、heap、stack、text詳細講解
-
text代碼段:用來存放代碼和常量(const 關鍵字定義的變量)
-
.data數據段:用來存放有初始值非0的全局變量和靜態變量(static修飾的變量,包括全局靜態變量和靜態局部變量),在MCU啟動過程中,會被從 flash 內 copy 到 SRAM 內(各家的啟動代碼都會做此操作)。
-
.bss段:存儲未初始化或初始化為
0
的全局/靜態變量,不占用可執行文件的實際磁盤空間,僅在程序加載時由系統分配內存并清零。存儲已初始化為非零值的全局/靜態變量,需占用可執行文件空間保存初始數據。例如:static int arr[3] = {1, 2, 3};
需要在.data
段存儲這3
個值。 -
**.stack棧空間:**用來存放局部變量、入參參數、返回值等,由編譯器自動分配釋放,如一個函數被調用后,產生的臨時變量都會存到棧區的頂部,當函數完成后,會自動從頂部將剛使用的數據銷毀。棧區的地址是從高地址向下增長的。
-
.heap 堆區: 用來動態內存分配,如 malloc, new 申請的內存,由程序員手動分配釋放。程序中不釋放,則程序結束時,由OS回收;據說這個和數據結構中的堆 沒有什么關系;堆區使用時地址向上增長。
ROM與RAM數據比較
數據段 | 說明 | RAM | ROM |
---|---|---|---|
.bss | – | true | false |
.data | true | true | |
RO-data | 常量 | false | true |
.text | – | false | true |
stack | 局部變量等 | true | false |
heap | malloc | true | false |
示例代碼演示:
int init_nonzero_global = 0x55; //初始化的全局變量,存在.data
int init_zero_global =0; //初始化為0, 存在.bss
const int const_a = 0xaa; //常量, 在.text
static char uninit_global; //未初始化的靜態變量,在.bss
static char e = '123456'; //初始化的靜態變量,在 .data 的 static 區域
static char init_zero_global = 0; //初始化為0的全局靜態變量,存在.bss
void main (void)
{int f; //未初始化的局部變量, 在 .stackint g = 2; //初始化的局部變量, 在 .stackstatic int x; //未初始化的靜態變量,在 .bssstatic int y = 3; //初始化的靜態變量,在 .data 的 static 區域char *p1; //p1 .stackp1 = (char *)malloc(50); //分配得來的50個字節的區域在 .heapif(NULL == p1){free(p1); //釋放 .heap 50個字節}while(1){}
}
運行結果:在Nordic編譯環境進行測試只有未初始化的全局變量存放在bss中。
bss、data、heap、stack、text示意圖:
單片機的程序運行時,這 5 段在物理存儲器上的位置,如下圖所示:
3、詳細探討 TCM、OCRAM 和 HBNRAM 之間的區別及其具體作用。
3.1、TCM(Tightly Coupled Memory)
具體作用:
-
TCM 是一種緊耦合存儲器,通常用于實時計算的處理器中,如 ARM Cortex-M 系列。
-
與緩存相比,TCM 的訪問延遲較低,能夠提供確定性的訪問時間。
-
通常用于存放關鍵性代碼或數據,以減少訪問時間,提升系統性能。
特點與用途:
-
低延遲:因為與處理器緊密耦合,訪問速度非常快。
-
確定性:適用于要求嚴格實時性能的應用場景。
-
固定大小:通常較小且固定大小的內存區域。
3.2、 OCRAM(On Chip RAM)
具體作用:
- OCRAM 是片上隨機存取存儲器,與主存儲器(如 DRAM)相比,其訪問延遲較低。
- 一般用于存儲經常需要訪問的數據,以提高訪問效率。
特點與用途:
-
快速訪問:相比于外部存儲器(如 DRAM),訪問速度快,適用于需要頻繁訪問的數據。
-
中等容量:容量通常較大于 TCM,但仍然有限。
-
多用途:可以用來存儲代碼、數據,甚至可以作為緩沖區。
3.3、HBNRAM (Hibernate RAM)
具體作用:
- HBNRAM 是一種特定用途的內存,主要用于低功耗或休眠模式下的數據保持。
- 在系統進入休眠模式時,可以存儲一些重要數據,確保在喚醒時可以快速恢復。
特點與用:
-
低功耗:設計上強調低功耗,數據在休眠模式中保持。
-
數據保持:適用于需要在休眠狀態中保留關鍵數據的應用。
-
小容量:通常容量較小,主要存儲需要在低功耗模式下保留的數據。
3.4、總結
參數 | TCM | OCRAM | HBNRAM |
---|---|---|---|
作用 | 實時、低延遲訪問 | 快速訪問數據/代碼 | 低功耗數據保持 |
延遲 | 極低 | 低 | 低 |
容量 | 較小 | 中等 | 小 |
用途 | 存放關鍵代碼/數據 | 存放頻繁訪問的數據/代碼 | 休眠模式下維護重要數據 |
特點 | 低延遲、確定性 | 快速訪問、多用途 | 低功耗、數據保持 |