嵌入式系統內存分段核心內容詳解

一、嵌入式內存分段整體規則(按地址從低到高)

????????嵌入式系統內存按 “功能 + 屬性” 劃分為 6 個核心段,地址從低到高依次分布,各段職責與存儲對象明確,具體規則如下表:

地址范圍段類型(Segment)對應段標識 / 關鍵字核心存儲內容
低地址代碼段(Code Segment).text編譯后的機器指令、程序執行邏輯、#define定義的常量
常量段(Const Segment).rodata字符串常量(如"hello")、數字常量(如const int a=10)、const修飾的全局變量
全局 / 靜態段(Global/Static Segment).bss.data-?.bss:未初始化的全局 / 靜態變量、初始化為 0 的全局 / 靜態變量
-?.data:已初始化(非 0)的全局 / 靜態變量
堆段(Heap Segment)無固定標識開發者通過malloc手動分配的動態內存、需手動free釋放的內存
高地址棧段(Stack Segment)無固定標識局部變量(如函數內int x=5)、const修飾的局部變量、函數形參、函數返回值

關鍵地址增長特性

  • 堆段:從低地址向高地址增長,由隱式指針跟蹤分配邊界;
  • 棧段:從高地址向低地址增長,遵循 “先進后出(FILO)” 規則,與數據結構中的 “棧” 邏輯一致。

二、各段核心屬性與物理存儲

不同段的讀寫權限、初始化方式、物理位置差異顯著,直接影響嵌入式系統的資源占用與運行效率,具體細節如下:

1. 代碼段(.text)

  • 核心屬性
    • 權限:只讀 + 可執行(不可修改,防止程序指令被意外篡改);
    • 初始化:由編譯器將 C/C++ 代碼編譯為機器指令后生成,無需手動干預;
    • 物理存儲:固定存于Flash(?,因代碼無需運行中修改,且 Flash 非易失性可長期保存程序。
  • 典型場景:函數體邏輯(如void init(void)的指令)、程序主流程(main函數指令)。

2. 常量段(.rodata)

  • 核心屬性
    • 權限:只讀(運行中不可修改,若強行修改會觸發硬件 / 軟件保護);
    • 初始化:編譯時由編譯器將常量數據(如字符串、const全局變量)打包生成;
    • 物理存儲:僅存于Flash,嵌入式系統中所有 “只讀(RO)” 數據均不占用 SRAM(靜態存儲器),避免寶貴的 SRAM 資源浪費。
  • 易混淆點:函數內的字符串常量(如char* s="test")也存于.rodata,而非棧段;const局部變量則存于棧段(僅編譯期限制修改,物理位置在 SRAM)。

3. 全局 / 靜態段(.bss + .data)

(1).bss 段
  • 核心屬性
    • 權限:可讀可寫(運行中可修改變量值,如int g_val; g_val=10;);
    • 初始化:不占用 BIN/ELF 文件空間,程序啟動時由啟動代碼自動清零(無需開發者手動初始化);
    • 物理存儲:僅存于SRAM,因全局 / 靜態變量需運行中快速訪問,SRAM 無需刷新、讀寫速度遠快于 Flash。
  • 包含對象:未初始化的全局變量(如int g_uninit;)、初始化為 0 的靜態變量(如static int s_zero=0;)。
(2).data 段
  • 核心屬性
    • 權限:可讀可寫(運行中可修改,如int g_init=5; g_init=8;);
    • 初始化:占用 BIN/ELF 文件空間,編譯時將初始值寫入文件,程序啟動后從 Flash 加載到 SRAM;
    • 物理存儲:運行時存于SRAM(保證訪問速度),初始數據備份于 Flash(非易失性保存)。
  • 關鍵影響:若全局 / 靜態變量初始值非 0(如uint8_t buf[256*1024]={1};),會直接導致 BIN 文件增大 —— 因.data段需存儲完整的初始化數據。

4. 堆段(Heap)

  • 核心屬性
    • 權限:可讀可寫(動態分配的內存可自由修改,如char* p=malloc(10); p[0]='a';);
    • 初始化:開發者通過malloc/calloc手動初始化(如int* arr=malloc(4*5);),需通過free手動釋放;
    • 物理存儲:僅存于SRAM,因動態內存需快速讀寫,且運行中需靈活調整大小。
  • 風險點:未及時free會導致內存泄漏,長期運行會耗盡 SRAM;頻繁分配 / 釋放可能產生內存碎片,導致后續malloc失敗(即使總剩余內存足夠)。

5. 棧段(Stack)

  • 核心屬性
    • 權限:可讀可寫(局部變量可修改,如void func(){int x=3; x=5;});
    • 初始化:由編譯器自動管理,變量進入作用域時自動分配棧空間,離開作用域時自動釋放(無需手動操作);
    • 物理存儲:僅存于SRAM,棧訪問依賴 CPU 寄存器(如棧指針 SP),速度極快。
  • 關鍵限制
    • 棧空間大小固定(由鏈接腳本配置,如STACK_SIZE = 0x1000),若局部變量過大(如char buf[1024*1024];)或遞歸調用過深,會導致棧溢出(程序崩潰);
    • 作用域限制:棧變量離開定義范圍后即失效(如函數返回后,其內部局部變量地址變為 “無效地址”)。

三、段相關開發實踐要點

結合嵌入式系統 “資源受限(SRAM/Flash 容量小)” 的特點,段的合理使用直接決定系統穩定性與資源利用率,核心實踐要點如下:

1. 避免 BIN 文件膨脹:優先用.bss 段存大緩沖區

若需定義大緩沖區(如 256K/512K),避免使用.data段(如uint8_t buf[512*1024]={0};)—— 會導致 BIN 文件增大 512K;應定義為未初始化變量(uint8_t buf[512*1024];),使其進入.bss段,不占用 BIN 空間,僅運行時占用 SRAM。

2. 減少 SRAM 占用:只讀數據放入.rodata

  • 全局常量(如配置參數const int MAX_LEN=1024)、固定字符串(如日志格式const char* LOG_FMT="[%s] %s")需加const修飾,確保進入.rodata段(存于 Flash),不消耗 SRAM;
  • 避免將 “無需修改的數據” 定義為全局變量(如int g_fixed=10),應改為const int g_fixed=10,節省 SRAM。

3. 棧段使用禁忌:不定義過大局部變量

  • 函數內避免定義大數組(如void func(){char big_buf[64*1024];}),若需大緩沖區,優先用malloc(堆)或全局.bss變量;
  • 遞歸函數需控制深度(如遞歸層級不超過 100),防止棧溢出,可改用迭代實現。

4. 堆段使用原則:減少動態分配,優先靜態內存池

  • 嵌入式系統中,堆的malloc/free易導致內存碎片,關鍵場景(如實時控制)建議用 “靜態內存池” 替代(預先分配一塊連續 SRAM,手動管理分配 / 釋放);
  • 若使用堆,需確保malloc返回值非NULL(判斷內存分配是否成功),且配對使用free(避免泄漏)。

5. 鏈接腳本配置:明確段的內存分配

通過鏈接腳本(.ld 文件)指定各段的物理地址與大小,避免段重疊(如堆與棧重疊導致內存 corruption),示例配置:

/* 定義Flash和SRAM地址范圍 */
MEMORY {FLASH (rx)  : ORIGIN = 0x08000000, LENGTH = 1024K  /* 代碼段、常量段存于此 */SRAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 128K   /* .bss、.data、堆、棧存于此 */
}/* 分配各段到指定內存 */
SECTIONS {.text : { *(.text) *(.rodata) } > FLASH  /* 代碼段+常量段放入Flash */.data : { *(.data) } > SRAM AT > FLASH   /* .data初始值存Flash,運行時加載到SRAM */.bss  : { *(.bss) } > SRAM               /* .bss直接放入SRAM */heap_start = .;                          /* 堆起始地址(.bss結束后) */stack_start = ORIGIN(SRAM) + LENGTH(SRAM);/* 棧起始地址(SRAM最高地址) */
}

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

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

相關文章

開發避坑指南(45):Java Stream 求兩個List的元素交集

需求 java 中如何用stream求兩個List元素的交集&#xff1f; 代碼實現 直接上代碼 public class ListTest {public static void main(String[] args) {List<Integer> list1 new ArrayList<>();list1.add(1);list1.add(2);list1.add(3);List<Integer> list2 …

gitlab流水線與k8s集群的聯通

gitlab流水線與k8s集群的連接&#xff0c;首先是通過gitlab-ci.yml文件中的命令&#xff0c;通過runner執行器實例運行對應的kubectl命令實現的。 那么runner執行器實例執行器如何執行kubectl命令&#xff0c;執行環境的配置&#xff0c;kubectl命令如何與k8s集群互認&#xff…

【Linux】常用命令速查表

Linux 常用命令速查表查看進程內存映射pmap -x <pid> # 查看進程的內存映射信息查看系統架構uname -m # 查看操作系統架構&#xff08;x86_64 / arm64 等&#xff09;磁盤與文件du -sh /home/* # 查看 /home 下每個用戶目錄的大小&#x…

Windows下編譯SLEPc

本文記錄在Windows下編譯SLEPc的流程。 零、環境 操作系統Windows 11VS Code1.92.1MSYS2msys2-x86_64-20250830 一、安裝依賴 1.1、依賴 首先&#xff0c;下載并安裝MSYS2&#xff0c; 打開MSYS2 MINGW64控制臺&#xff0c;運行以下命令安裝依賴包&#xff0c; pacman -S …

運動生理實驗室解決方案 人體生理實驗整體解決方案

&#xff08;一&#xff09;、硬件參數 集成化折疊式無創型生理實驗平臺&#xff1a;1.1、 集成化設計:至少包含設備操作臺、可收納式交互實驗桌、可收納式檢查床、生物信號 采集處理系統、計算機工作站集成于一體的高度集成設計&#xff1b;&#xff08;o561-6o623…

Axure RP 9 最新版安裝包+安裝步驟Win系統適用(附安裝包)

Axure RP 9? 是一款專業的 ?原型設計工具&#xff0c;主要用于 ?網站、APP、軟件等產品的界面設計和交互原型制作。 一、準備工作 ?下載好安裝包? Axure RP 9安裝包下載&#xff1a;https://pan.quark.cn/s/bc2b35011106 二、開始安裝 第一步&#xff1a;雙擊運行安裝包…

AutoMQ 亮相首爾:KafkaKRU 分享日志流處理新思路

全球 Kafka 社區都在關注 AutoMQ&#xff01;憑借在 Kafka 生態的獨特創新&#xff0c;AutoMQ 深受 Kafka 用戶喜愛&#xff0c;已成為眾多企業和開發者的首選實時數據解決方案。昨天&#xff0c;我們非常高興看到來自韓國的 KafkaKRU 核心社區在首爾舉辦第2屆官方線下交流會。…

從零開始使用 axum-server 構建 HTTP/HTTPS 服務

axum-server 是 Rust 生態中為 axum 框架設計的高性能服務器實現&#xff0c;基于 hyper&#xff08;底層 HTTP 引擎&#xff09;和 tower&#xff08;服務抽象&#xff09;構建&#xff0c;支持 HTTP/1、HTTP/2 及 HTTPS。本教程將從環境準備到實戰功能&#xff0c;一步步帶你…

電路運行的核心-RTC

1. 時鐘芯片是什么&#xff1f;時鐘芯片&#xff0c;更準確的名稱是實時時鐘芯片&#xff0c;英文是 Real-Time Clock&#xff0c;簡稱 RTC。它是一個專用的集成電路&#xff0c;其核心功能是追蹤時間和日歷。你可以把它想象成電子設備里的一個“電子表”或“日歷鐘”。關鍵特性…

AR消防頭盔:火場救援的智能“透視眼”

在濃煙彌漫、能見度幾乎為零的火場中&#xff0c;消防員們依靠什么來精準掌握隊友的位置和狀態&#xff1f;答案是AR智能消防頭盔&#xff08; www.teamhelper.cn &#xff09;。這種頭盔通過多種定位技術的融合&#xff0c;為消防員提供了強大的團隊協作和指揮協同能力&#x…

基于大模型的個性化推薦系統實現探索與應用

前言 如果你一直在跟著Fanstuck博主的腳步探索AI大模型的相關內容&#xff0c;從最初的大模型Prompt工程解析&#xff0c;DeepSeek全面解析&#xff0c;到實際的私有化大模型開發部署&#xff0c;再到深入NL2SQL、知識圖譜大模型和ChatBI等更高階應用.我是Fanstuck&#xff0c…

【已解決】Echarts 力學布局圖譜切換圖例的時候線條殘留在了畫布上

在用Vue3封裝 ECharts 的力導向圖&#xff08;graph force&#xff09;時&#xff0c;我遇到一個問題&#xff1a;點擊圖例切換節點顯隱后&#xff0c;線條殘留在原位置&#xff0c;畫布出現“臟線條”。&#xff08;問題如下&#xff1a;&#xff09;這個問題本質上是因為…&…

Vue動態實時字數限制

文章目錄&#x1f680; Vue.js 動態實時字數限制指南1. 核心實現方法1.1 使用計算屬性 (Computed Property)1.2 結合計算屬性的 Setter/Getter1.3 使用監聽器 (Watcher)1.4 使用自定義指令 (Custom Directive)1.5 原生 maxlength 屬性結合 Vue2. 特殊場景處理2.1 處理粘貼操作2…

榮耀手機無法連接win11電腦,錯誤消息:“無法在此設備上加載驅動程序 (hn_usbccgpfilter.sys)。”解決方案

錯誤發生背景&#xff1a; 本人于2024年月底買了一部榮耀Magic7 RSR手機&#xff0c;當時在win10的rog電腦上可以正常連接&#xff0c;但是后面換了一個acer的win11電腦后&#xff0c;一開始可以正常連接&#xff0c;但是要我下載榮耀Hisuite&#xff08;榮耀手機助理&#xff…

springboot env 多環境配置入門與實戰

Spring Boot3 Env 項目地址 https://gitee.com/supervol/loong-springboot-study &#xff08;記得給個start&#xff0c;感謝&#xff09; Env 概述 在 Spring Boot 3 開發中&#xff0c;多環境配置是核心能力之一&#xff0c;其目的是為不同場景&#xff08;如開發、測試、…

利用conda打包/復刻生信環境

01、寫在前面 大家拿到自己的服務器(趁開學| 入手足夠完成碩博生涯的生信環境)后可能需要安裝很多的軟件與包&#xff0c;Linux中許多包的安裝依賴過多、安裝復雜。而conda作為一個能夠直接安裝超過90%軟件的"管家"&#xff0c;能夠像Windows和手機中的應用商店那樣…

數據分析:合并

&#x1f537; DA37&#xff1a;統計運動會項目報名人數&#xff08;僅輸出有人報名的項目&#xff09;? 題目描述給定兩個 CSV 文件&#xff1a;items.csv&#xff1a;包含項目信息&#xff08;item_id, item_name, location&#xff09;signup.csv&#xff1a;包含員工報名信…

高并發內存池(一):項目介紹和ThreadCache(線程緩存)實現

前言&#xff1a;本文將要介紹的高并發內存池&#xff0c;它的原型是Google的?個開源項?tcmalloc&#xff0c;全稱Thread-Caching Malloc&#xff0c;近一個月我將以學習為目的來模擬實現一個精簡版的高并發內存池&#xff0c;并對核心技術分塊進行精細剖析&#xff0c;分享在…

RK3399平臺ffmpeg-VPU硬編碼錄制USB攝像頭視頻、H264或MJPEG編碼

文章目錄 1 前言2 項目內容詳細說明2.0 功能2.1 工程文件夾說明 3 代碼3.1 CameraThread類3.1 CameraThreadImpl類 4 資源下載 1 前言 在某項目中需要在RK3399平臺實現USB攝像頭畫面的實時預覽、視頻錄制、拍照存儲等功能。 ??先來看需要實現的最終效果。 ?? ffmpeg USB攝…

解決藍牙耳機連win11電腦畫質依托答辯問題

以wh910n藍牙耳機為例 設置-系統-聲音-輸出&#xff08;耳機&#xff09;-常規&#xff08;輸出點不允許&#xff09;然后刪除wh910n藍牙設備 重新配對藍牙耳機