我們在使用Keil編譯程序成功后會,有一行各部分占用內存的提示信息,如下
Program Size:Code=7492 RO-data=556 Rw-data=72 ZI-data=11688,這是stm32代碼編譯后的提示
我們分析一下這個編譯輸出:
- Code: 7492字節 -> 代碼部分(存放在Flash)
- RO-data: 556字節 -> 只讀數據(存放在Flash)
- RW-data: 72字節 -> 已初始化的讀寫數據(在Flash中存儲初始值,運行時拷貝到RAM)
- ZI-data: 11688字節 -> 未初始化的數據(運行時在RAM中初始化為零)
所以,占用Flash的空間為:Code + RO-data + RW-data(因為RW-data的初始值需要存儲在Flash中) 即:7492 + 556 + 72 = 8120字節 ,但是注意,ZI-data不占用Flash空間,因為它只需要在程序運行時在RAM中分配并初始化為零。
因此,這個程序占用的Flash空間為8120字節。 另外,程序運行時占用的RAM空間為:RW-data + ZI-data = 72 + 11688 = 11760字節。
總結:
?Flash占用:8120字節? 約7.93KB
?RAM占用:11760字節? 約11.48kB
并且我們在購買單片機的時候會經常看到一下字樣,Flash ,RAM等今天我們將解密他們究竟是什么
簡單來說:
Flash大小:決定了你的程序代碼能寫多大,以及能存儲多少常量數據(如圖片、字體等)。如果你的程序很大,就要選Flash大的型號。
RAM大小:決定了你的程序運行時能同時使用多少變量和數據。如果你的程序需要處理大量數據、有很多全局變量、或者使用了復雜的算法和遞歸,就需要更大的RAM。RAM不足是導致程序莫名崩潰的常見原因。
要想深入了解這些東西 需要我們對STM32存儲器劃分結構有一定了解
STM32的存儲器結構采用了哈佛架構(Harvard Architecture),這意味著程序存儲器(Flash)和數據存儲器(RAM)在物理上是分開的,并且有獨立的地址總線和數據通路,這使得CPU可以同時取指和訪問數據,提高了執行效率。
地址劃分 | |||
Flash (ROM) | 0x0800 0000- | 程序存儲器 | 存儲C語言編譯之后的代碼 |
0x1FFF F000- | 系統存儲器 | 存儲BootLoader,用于串口下載 | |
0x1FFF F800- | 選項字節 | 存儲一些獨立于代碼的配置參數 | |
RAM | 0x2000 0000- | 運行內存SRAM | 存儲運行中的臨時變量 |
0x4000 0000- | 外設寄存器 | 存儲各個外設的配置參數 | |
0xE000 0000- | 內核外設寄存器 | 存儲內核各個外設的配置參數 |
當芯片手冊上標稱?“64KB Flash”?時,這個總容量通常包含了主Flash、系統存儲器和選項字節等所有部分。需要查閱芯片的內存映射圖來了解具體是如何劃分的。例如,一顆62KB Flash的STM32芯片,其內存映射可能是:62KB的主Flash + 2KB的系統存儲器 + 一小部分(如16字節)的選項字節。
什么是Flash和RAM?
1.Flash (閃存)
它是什么:是一種非易失性存儲器。意思是即使斷電,里面存儲的數據也不會丟失。
在辦公室比喻中:它就是你的文件柜。你把不經常用但很重要的東西(比如項目文檔、參考資料、年度報告)長期存放在這里。
在單片機中的作用:
存儲程序代碼:你編寫好的程序,經過編譯后生成的機器碼,就永久地燒錄(存儲)在Flash中。單片機一上電,就從這里讀取指令來執行。
存儲常量數據:比如固定的字體、圖片、音樂數據、配置參數等只讀不寫的數據。
特點:速度較慢(相比RAM)、容量較大(相比RAM)、斷電數據不丟失、可擦寫(但次數有限,通常10萬次以上)。
簡單記:Flash是放程序的地方,斷電還在。
2. RAM (隨機存取存儲器)
它是什么:是一種易失性存儲器。意思是只有在通電時才能保持數據,一旦斷電,里面的所有數據都會丟失。
在辦公室比喻中:它就是你的辦公桌面。你正在處理的文件、臨時記下的筆記、計算中的草稿紙都放在桌面上。這些東西只是暫時用一下,工作結束就收走或扔掉。
在單片機中的作用:
存儲變量:程序運行中產生的臨時變量、中間計算結果、函數調用的堆棧等都放在RAM里。
動態內存分配:像
malloc()
或new
申請的內存空間,也位于RAM中。
特點:速度極快、容量較小(在單片機里通常是KB級別)、斷電數據丟失、可無限次讀寫。
簡單記:RAM是程序運行時的臨時工作區,斷電就清空。
了解完什么是Flash我們來看看STM32的Flash劃分了那幾部分
1. 主Flash存儲器 (Main Flash Memory)
位置:Flash的絕大部分區域。
功能:這就是我們通常說的“Flash”,用來存儲你編寫的應用程序代碼和常量數據。
權限:用戶程序可以自由地讀取這里的數據。在允許自我編程(IAP)的單片機上,用戶程序也可以擦寫這個區域(比如用于固件升級)。
比喻:大樓里開放的辦公區域,員工可以自由進出和使用。
2. 系統存儲器 (System Memory)
位置:Flash中一段固定的、出廠前預設好的區域。
功能:里面存儲的是芯片制造商預先燒錄好的Bootloader程序。這個Bootloader通常是用于通過某種串行接口(如USART, USB, CAN等)來下載用戶程序到主Flash存儲器。最常見的例子就是STM32的USB DFU或UART燒錄功能。你選擇從“系統存儲器啟動”時,芯片就會運行這里的程序。
權限:這段區域是只讀的。用戶無法修改或擦除這里的內容,這是芯片廠商寫死的,為了防止用戶誤操作導致芯片“變磚”。
比喻:大樓里一個上了鎖的機房,里面放著大樓的基礎控制系統(如消防、供電)。只有大樓管理員(芯片廠商)有鑰匙,普通員工(用戶)只能使用它提供的功能(比如通過它來部署新程序),但不能改動里面的設備。
3. 選項字節 (Option Bytes)
位置:Flash中一個非常小但極其重要的特殊區域。
功能:它不是用來存儲程序或數據的,而是用來配置單片機的硬件特性的,可以看作是芯片的“配置開關”。常見的配置包括:
讀寫保護:給主Flash上鎖,防止別人通過調試器讀取或抄襲你的程序代碼。
寫保護:保護Flash的某些扇區不被意外擦寫。
硬件看門狗:配置看門狗是硬件開啟還是軟件開啟。
復位級別:配置NRST引腳是作為復位引腳還是普通IO。
啟動配置:決定芯片上電后從主Flash、系統存儲器還是RAM啟動。
權限:用戶可以通過特定的編程流程(通常需要先解鎖)來修改選項字節。修改后需要觸發一個系統復位才能生效。
比喻:大樓總電箱里的那些開關和保險絲。它們不參與日常辦公,但決定了整個大樓的用電安全、照明方式等基礎設置。改動它們需要謹慎并有特定權限。
4. Bootloader (引導加載程序)
概念:這是一個程序,而不是一個存儲區域。它是一段特殊的代碼,負責在單片機正式運行用戶主程序之前,完成一些初始化工作,或者決定從哪里、如何加載主程序。
存放位置:它可能存放在兩個地方:
系統存儲器:即芯片廠商自帶的,如上所述。
主Flash存儲器:用戶自己編寫的Bootloader。比如你想通過網絡來升級固件,你就可以自己寫一個更強大的Bootloader,把它放在主Flash的開頭部分。芯片上電后先運行你的Bootloader,你的Bootloader再決定是跳轉到主應用程序,還是進入升級模式。
比喻:大樓的前臺接待員或門衛。每天早上(上電后),他先到崗,檢查今天有沒有新的快遞(新的固件包)要接收,或者決定是讓員工直接進入辦公區(跳轉到主程序),還是先組織一個安全會議(系統配置)。
RAM內存布局示例