根據Cortex-M3(包括STM32F1)權威指南講解MCU內存架構與如何查看編譯器生成的地址具體位置

首先我們先查看官方對于Cortex-M3預定義的存儲器映射

1.存儲器映射

1.1?Cortex-M3架構的存儲器結構

內部私有外設總線:即AHB總線,包括NVIC中斷,ITM硬件調試,FPB, DWT。

外部私有外設總線:即APB總線,用于內部“外設”的操作(SPI,IIC,USART)等,也用于些片上APB外設到APB私有總線上(SD卡,LCD顯示屏)的訪問。

他們的物理地址關系如下圖所示:

2.RAM和FLASH的基本概念與作用

從上面的描述可以知道,其實Cortex-M3分配的地址很多都是不允許修改的,能修改的只有代碼區的FLASH和上電后代碼運行的片上SRAM區的RAM,我們這章就著重講一下這兩個地方。

1.2.1RAM的基本概念與作用

RAM(隨機存取存儲器)在STM32中主要用于存儲運行時的數據和變量。它是易失性存儲器,斷電后數據會丟失。RAM的作用包括:

  • 存儲程序運行時的臨時數據,如局部變量、堆棧和動態分配的內存。
  • 提供快速的數據訪問,支持CPU的高效運行。
  • 用于存儲中斷向量表、全局變量和靜態變量。

1.2.2?FLASH的基本概念與作用

FLASH存儲器在STM32中用于存儲程序代碼和常量數據。它是非易失性存儲器,斷電后數據不會丟失。FLASH的作用包括:

  • 存儲固件程序代碼,包括主程序、中斷服務程序和庫函數。
  • 存儲常量數據,如查找表、配置參數和字符串。
  • 支持程序更新和固件升級,通過編程接口可以擦除和寫入數據。

1.2.3?程序的典型內存分布和用途

內存分布:


+------------------+ 0x20005000 (RAM 結束)
|       Heap      |  動態分配(malloc)
+------------------+
|       Stack     |  棧(局部變量、返回地址)
+------------------+
|      .bss       |  未初始化數據(RAM)
+------------------+
|      .data      |  已初始化全局變量(RAM)
+------------------+ 0x20000000 (RAM 起始)+------------------+ 0x08010000 (Flash 結束)
|      .rodata    |  只讀數據(Flash)
+------------------+
|      .text      |  代碼段(Flash)
+------------------+ 0x08000000 (Flash 起始)

各個區域用途:

存儲區域用途存儲位置
.text(Code)存放編譯后的程序指令(代碼)Flash(只讀)
.rodata(RO-data)存放只讀常量const?變量等)Flash(只讀)
.data(RW-data)已初始化的全局/靜態變量Flash + RAM
.bss(ZI-data)未初始化的全局/靜態變量,啟動時清零RAM(自動清零)
Heap(堆)malloc()?動態分配的內存RAM(向上增長)
Stack(棧)局部變量、函數調用返回地址RAM(向下增長)

注意

  1. .data?段在?Flash?里存有初值,但運行時會被復制到?RAM
  2. .bss?段不會占用 Flash,但會在 RAM 里初始化為 0
  3. 棧和堆共享 RAM,棧 Stack 從 高地址→?低地址方向增長。
  4. 堆 Heap 從 低地址→?高地址 方向增長。
  5. 當 Stack 和 Heap 彼此增長到一個臨界點(即二者相遇),就會導致 Stack Overflow(棧溢出)。

下面舉一個例子供大家更深入了解代碼變量的存儲方式:


int a = 0;    //全局初始化區 
char *p1;    //全局未初始化區 
main() 
{ int b;//棧 char s[] = "abc";//棧 char * p2;//棧 char * p3 = "123456";//123456\0在常量區,p3在棧上。 static int c =0;//全局(靜態)初始化區 p1 = (char *)malloc(10);//堆 p2 = (char *)malloc(20);//堆 
}

3.如何查看自己代碼的各個區的地址位置

3.1 為什么要查看各個區的地址

雖然我們在官方文檔中知道了Cortex-M3的各個部分的大概范圍,但我們使用CUBEMX或者操作系統生成的項目肯定不會規規矩矩的完全按照官方文檔的推薦來配置各個區。有時候推薦的去大小沒占完,你不知道結束地址。比如RT-Thread的內存管理將.data段和.bss段也一起管理起來了,創建各種任務所使用的內存都由RT-Thread統一分配。或者在CUBEMX中你可以自行設計堆區和棧區的大小等等。

而我們在使用內存管理的時候開辟一個專門存放變量的空間,我們需要的不只是簡單的知道這個變量的大小,我們還需要知道它的地址要不然你使用這個變量,還要編譯器找這個地址在哪里,這樣才能提升項目的管理分配和運行效率,那根我直接開辟一個變量有什么區別?)而我開辟的地方也有講究,因為只有Heap(堆區)才能給與我們自由分配空間并進行讀寫的權利。因此找到各個區的地址我認為是有必要的。

那我們應該怎么找到各個區的地址呢?

那就是查看代碼編譯后生成的.map文件

3.2 解析查找地址的.map文件的代碼含義

代碼來源:https://www.waveshare.net/w/upload/3/39/E-Paper_code.7z

注意:你要使用了malloc等函數才會存在heap區的開辟,要不然你在.map文件中是找不到heap的創建地址的。

我們得到了下面的關于堆的說明

?HEAP? ? ? ? ? ? ? ? ? ? ?0x200002e0 ? Section ? ?49152 ?startup_stm32f103xe.o(HEAP)?
? ?

STACK? ? ? ? ? ? ? ? ? ??0x2000c2e0 ? Section ? ? 4096 ?startup_stm32f103xe.o(STACK)

__heap_base? ? ? ? ?0x200002e0 ? Data ? ? ? ? ? 0? ? ? ?startup_stm32f103xe.o(HEAP)
__heap_limit? ? ? ? ? 0x2000c2e0 ? Data ? ? ? ? ? 0? ? ? ?startup_stm32f103xe.o(HEAP)
__initial_sp? ? ? ? ? ? 0x2000d2e0 ? Data ? ? ? ? ? 0? ? ? ?startup_stm32f103xe.o(STACK)

HEAP:是堆的基地址

__initial_sp:是棧的起始地址(棧頂)

__heap_base:堆的??起始地址??。

__heap_limit:堆的??結束地址??。

示意圖如下

4. 總結

如果我們設置了堆的空間大小,但是我們程序中沒有進行malloc申請,那么在程序事假運行的時候,我們棧的空間超過本身設置的空間,進入到堆里面,那么程序是不會出錯的,但是超過了堆的空間了,進入到全局變量區域,就會出現莫名其妙的錯誤。

不使用malloc,我們可以將堆設置成0,這是沒有問題的,但是棧的空間大小要設置成合適的,不然就會因為棧溢出,進入harderror,程序奔潰。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/82555.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82555.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/82555.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux中硬件信息查詢利器——lshw命令詳解!

lshw(List Hardware)是 Linux 系統下的一款命令行工具,用于全面檢測并顯示詳細的硬件信息。它能夠報告 CPU、內存、主板、存儲設備、顯卡、網絡設備等幾乎所有硬件組件的詳細信息,適用于系統管理、故障排查和硬件兼容性檢查等場景…

用llama3微調了一個WiFiGPT 用于室內定位

一段話總結 本文提出WiFiGPT,一種基于Decoder-Only Transformer(如LLaMA 3)的室內定位系統,通過將WiFi遙測數據(如CSI、FTM、RSSI)轉換為文本序列進行端到端訓練,無需手工特征工程即可實現高精度定位。實驗表明,WiFiGPT在LOS環境中實現亞米級精度(MAE低至0.90米),在…

大模型系列22-MCP

大模型系列22-MCP 玩轉 MCP 協議:用 Cline DeepSeek 接入天氣服務什么是 MCP?環境準備:VScode Cline DeepSeek**配置 DeepSeek 模型:****配置 MCP 工具****uvx是什么?****安裝 uv(會自動有 uvx 命令&…

Go語言Map的底層原理

概念 map 又稱字典,是一種常用的數據結構,核心特征包含下述三點: (1)存儲基于 key-value 對映射的模式; (2)基于 key 維度實現存儲數據的去重; (3&#x…

循環神經網絡(RNN):原理、架構與實戰

循環神經網絡(Recurrent Neural Network, RNN)是一類專門處理序列數據的神經網絡,如時間序列、自然語言、音頻等。與前饋神經網絡不同,RNN 引入了循環結構,能夠捕捉序列中的時序信息,使模型在不同時間步之間…

java 項目登錄請求業務解耦模塊全面

登錄是統一的閘機; 密碼存在數據庫中,用的是密文,后端加密,和數據庫中做對比 1、UserController public class UserController{Autowiredprivate IuserService userservicepublic JsonResult login(Validated RequestBody UserLo…

【手寫數據庫核心揭秘系列】第9節 可重入的SQL解析器,不斷解析Structure Query Language,語言翻譯好幫手

可重入的SQL解析器 文章目錄 可重入的SQL解析器一、概述 二、可重入解析器 2.1 可重入設置 2.2 記錄狀態的數據結構 2.3 節點數據類型定義 2.4 頭文件引用 三、調整后的程序結構 四、總結 一、概述 現在就來修改之前sqlscanner.l和sqlgram.y程序,可以不斷輸入SQL語句,循環執…

微軟開源bitnet b1.58大模型,應用效果測評(問答、知識、數學、邏輯、分析)

微軟開源bitnet b1.58大模型,應用效果測評(問答、知識、數學、邏輯、分析) 目 錄 1. 前言... 2 2. 應用部署... 2 3. 應用效果... 3 1.1 問答方面... 3 1.2 知識方面... 4 1.3 數字運算... 6 1.4 邏輯方面... …

用HTML5+JavaScript實現漢字轉拼音工具

用HTML5JavaScript實現漢字轉拼音工具 前一篇博文(https://blog.csdn.net/cnds123/article/details/148067680)提到,當需要將拼音添加到漢字上面時,用python實現比HTML5JavaScript實現繁瑣。在這篇博文中用HTML5JavaScript實現漢…

鴻蒙OSUniApp 開發的動態背景動畫組件#三方框架 #Uniapp

使用 UniApp 開發的動態背景動畫組件 前言 在移動應用開發中,動態背景動畫不僅能提升界面美感,還能增強用戶的沉浸感和品牌辨識度。無論是登錄頁、首頁還是活動頁,恰到好處的動態背景都能讓產品脫穎而出。隨著鴻蒙(HarmonyOS&am…

云原生技術架構技術探索

文章目錄 前言一、什么是云原生技術架構二、云原生技術架構的優勢三、云原生技術架構的應用場景結語 前言 在當今的技術領域,云原生技術架構正以一種勢不可擋的姿態席卷而來,成為了眾多開發者、企業和技術愛好者關注的焦點。那么,究竟什么是…

AWS之AI服務

目錄 一、AWS AI布局 ??1. 底層基礎設施與芯片?? ??2. AI訓練框架與平臺?? ??3. 大模型與應用層?? ??4. 超級計算與網絡?? ??與競品對比?? AI服務 ??1. 機器學習平臺?? ??2. 預訓練AI服務?? ??3. 邊緣與物聯網AI?? ??4. 數據與AI…

lwip_bind、lwip_listen 是阻塞函數嗎

在 lwIP 協議棧中,lwip_bind 和 lwip_listen 函數本質上是非阻塞的。 通常,bind和listen在大多數實現中都是非阻塞的,因為它們只是設置套接字的屬性,不需要等待外部事件。阻塞通常發生在接受連接(accept)、…

【后端高階面經:消息隊列篇】28、從零設計高可用消息隊列

一、消息隊列架構設計的核心目標與挑戰 設計高性能、高可靠的消息隊列需平衡功能性與非功能性需求,解決分布式系統中的典型問題。 1.1 核心設計目標 吞吐量:支持百萬級消息/秒處理,通過分區并行化實現橫向擴展。延遲:端到端延遲控制在毫秒級,適用于實時業務場景。可靠性…

【運維實戰】Linux 內存調優之進程內存深度監控

寫在前面 內容涉及 Linux 進程內存監控 監控方式包括傳統工具 ps/top/pmap ,以及 cgroup 內存子系統,proc 內存偽文件系統 監控內容包括進程內存使用情況, 內存全局數據統計,內存事件指標,以及進程內存段數據監控 監控進程的內…

決策樹 GBDT XGBoost LightGBM

一、決策樹 1. 決策樹有一個很強的假設: 信息是可分的,否則無法進行特征分支 2. 決策樹的種類: 2. ID3決策樹: ID3決策樹的數劃分標準是信息增益: 信息增益衡量的是通過某個特征進行數據劃分前后熵的變化量。但是&…

java基礎學習(十四)

文章目錄 4-1 面向過程與面向對象4-2 Java語言的基本元素:類和對象面向對象的思想概述 4-3 對象的創建和使用內存解析匿名對象 4-1 面向過程與面向對象 面向過程(POP) 與 面向對象(OOP) 二者都是一種思想,面向對象是相對于面向過程而言的。面向過程&…

TCP 三次握手,第三次握手報文丟失會發生什么?

文章目錄 RTO(Retransmission Timeout)注意 客戶端收到服務端的 SYNACK 報文后,會回給服務端一個 ACK 報文,之后處于 ESTABLISHED 狀態 因為第三次握手的 ACK 是對第二次握手中 SYN 的確認報文,如果第三次握手報文丟失了,服務端就…

deepseek告訴您http與https有何區別?

有用戶經常問什么是Http , 什么是Https ? 兩者有什么區別,下面為大家介紹一下兩者的區別 一、什么是HTTP HTTP是一種無狀態的應用層協議,用于在客戶端瀏覽器和服務器之間傳輸網頁信息,默認使用80端口 二、HTTP協議的特點 HTTP協議…

openresty如何禁止海外ip訪問

前幾天,我有一個徒弟問我,如何禁止海外ip訪問他的網站系統?操作系統采用的是centos7.9,發布服務采用的是openresty。通過日志他發現,有很多類似以下數據 {"host":"172.30.7.95","clientip&q…