根據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/news/906715.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906715.shtml
英文地址,請注明出處:http://en.pswp.cn/news/906715.shtml

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

相關文章

軟件設計師“測試用例”考點分析——求三連

一、測試用例設計核心要點解析 1. 白盒測試覆蓋標準 (1)路徑覆蓋:需覆蓋程序中所有可能的路徑。如2018年真題路徑覆蓋需要3組測試用例(①②、①③、①③④),2020年流程圖則需4個用例覆蓋ace/abd/abe/acd四…

Linux 用戶無法遠程連接服務器

前言 昨天深夜一點多接到客戶電話,客戶說OS用戶下午下班前還能正常登錄。因為晚上一點半需要關閉所有服務進行遷移,但是用戶無法登錄了,導致后續流程無法執行。我讓他先通過root用戶緊急修改了密碼,先保證業務正常流轉。 問題 …

多模態大語言模型arxiv論文略讀(八十八)

MammothModa: Multi-Modal Large Language Model ?? 論文標題:MammothModa: Multi-Modal Large Language Model ?? 論文作者:Qi She, Junwen Pan, Xin Wan, Rui Zhang, Dawei Lu, Kai Huang ?? 研究機構: ByteDance, Beijing, China ?? 問題背景…

svn遷移到git保留記錄和Python字符串格式化 f-string的進化歷程

svn遷移到git保留記錄 and Python字符串格式化(二): f-string的進化歷程 在將項目從SVN遷移到Git時,保留完整的版本歷史記錄非常重要。下面是詳細的步驟和工具,可以幫助你完成這一過程: 安裝Git和SVN工具 首先&#…

springboot配置mysql druid連接池,以及連接池參數解釋

文章目錄 前置配置方式參數解釋 前置 springboot 項目javamysqldruid 連接池 配置方式 在 springboot 的 application.yml 中配置基本方式 # Druid 配置(Spring Boot YAML 格式) spring:datasource:url: jdbc:mysql://localhost:3306/testdb?useSSL…

vue實現高亮文字效果——advanced-mark.js

組件介紹-advanced-mark.js: advanced-mark.js 是一個用于 Vue 的高亮文字組件,它可以幫助你在文本中高亮顯示指定的關鍵詞或短語。 組件地址:https://angezid.github.io/advanced-mark.js/doc-v2/getting-started.html 主要功能&#xff1…

DC30V/2.5A同步降壓芯片SL1581 輸入24V降壓5V 12V2A電流

在工業自動化、汽車電子等領域,24V 電源系統向 5V/12V 雙軌供電的需求日益增長。針對這一痛點,森利威爾電子重磅推出 DC30V/2.5A 同步降壓芯片 SL1581,憑借卓越的性能和創新設計,為工程師提供高可靠性、高性價比的電源解決方案。 …

React 第四十四節Router中 usefetcher的使用詳解及注意事項

前言 useFetcher 是 React Router 中一個強大的鉤子,用于在不觸發頁面導航的情況下執行數據加載(GET)或提交(POST)。 一、useFetcher 應用場景: 1、后臺數據預加載(如鼠標懸停時加載數據&…

Jmeter(三) - 測試計劃(Test Plan)的元件

1.簡介 上一篇已經教你如何通過JMeter來創建一個測試計劃(Test Plan),那么這一篇我們就將JMeter啟動起來,創建一個測試計劃(Test plan),給大家介紹一下測試計劃(Test Plan&#xff…

應屆本科生簡歷制作指南

一、找一個專業的簡歷模板 首先,你需要訪問 Overleaf 的官方網站,也就是Overleaf, Online LaTeX Editor,進入頁面后,點擊注冊按鈕,按照提示填寫相關信息來創建一個屬于自己的賬號,通常需要填寫用戶名、郵箱…

[Spring Boot]整合Java Mail實現Outlook發送郵件

日常開發過程中,我們經常需要使用到郵件發送任務,比方說驗證碼的發送、日常信息的通知等。日常比較常用的郵件發送方包括:163、QQ等,本文主要講解Outlook SMTP的開啟方式、OutLook STARTTTL的配置、如何通過JavaMail來實現電子郵件的發送等。 Outlook作為微軟提供的企業電子…

【YOLOs-CPP-圖像分類部署】03-解決報錯

完整項目鏈接 點擊here下載! 上一篇問題 經過上一篇博客,我們得到了一個粗略版(會報錯)的項目。如何解決異常報錯呢? 我把問題在github上對作者進行了提問,但是2天后,依然沒有回復。 怎么辦呢?只能自己調試代碼了。 修改代碼 經過大量調試,修改了YOLO11CLASS.h…

Dockers Compose常用指令介紹

Dockers Compose常用指令 1、常用指令介紹 1.1、version 指令 頂級一級指令,指定 compose 指定文件格式版本 version: "3.8" services: 不同版本支持的功能不同。常用版本有 ‘2’, ‘3’, ‘3.8’ 等。 1.2、services 指令 頂級一級指令&#xff0…

謝飛機的Spring WebFlux面試之旅:從基礎到深入

謝飛機的Spring WebFlux面試之旅:從基礎到深入 面試場景:謝飛機的WebFlux面試 面試官:你好,謝飛機,請介紹一下你自己。 謝飛機:您好,我是一名有三年開發經驗的Java程序員,熟悉Spr…

Mysql增量備份與恢復

1.練習數據增量備份 增量備份:備份上次備份后,新產生的數據。 PERCONA Xtrabackup是一款強大的在線熱備份工具,備份過程中不鎖庫表,適合生產環境。支持完全備份與恢復、增量備份與恢復、差異備份與恢復。 安裝Xtrabackup 150、…

GStreamer (三)常?插件

常?插件 1、Source1.1、filesrc1.2. videotestsrc1.3. v4l2src1.4. rtspsrc和rtspclientsink 2、 Sink2.1. filesink2.2. fakesink2.3. xvimagesink2.4. kmssink2.5. waylandsink2.6. rkximagesink2.7. fpsdisplaysink 3 、視頻推流/拉流3.1. 本地推流/拉流3.1.1 USB攝像頭3.1…

Spring Boot與Kafka集成實踐:實現高效消息隊列

Spring Boot與Kafka集成實踐 引言 在現代分布式系統中,消息隊列是實現異步通信和解耦的重要組件。Apache Kafka作為一種高性能、分布式的消息隊列系統,被廣泛應用于大數據和實時數據處理場景。本文將介紹如何在Spring Boot項目中集成Kafka,…

Linux PXE批量裝機+無人值守技術(自動化裝機)

目錄 PXE所需條件 服務端所需服務 客戶端所需功能 1.準備系統安裝rpm倉庫 (1)安裝vsftpd服務 (2)啟動并設置開機自啟 (3)準備yum倉庫文件 2.安裝配置dhcpd服務 (1)安裝dhcoo軟件包 (2)配置dhcp服務 (3)啟動并設置開機自啟 3.部署TFTP服務 (1)安裝軟…

linux_cmake的筆記

include_directories()的使用 今天在運行一個cmakelist.txt如下所示時候,發現一個問題: cmake_minimum_required(VERSION 3.28) project(l_trajectoryError CXX) option(USE_UBUNTU_20 "Set to ON if you are using Ubuntu 20.04" OFF) find…

論文略讀:If Multi-Agent Debate is the Answer, What is the Question?

202502 arxiv 1 intro 多智能體辯論(Multi-Agent Debate, MAD):通過讓多個智能體在大模型推理時展開多輪辯論,可提升生成內容的事實準確性和推理質量 但論文認為,目前多智能體辯論在大多數情況下不敵簡單的單智能體方…