STM32的內存分配與堆棧

使用過cortex-M4內核單片機的朋友對下面這張圖一定不會感到陌生,它是ST原廠手冊里面的memory map,里面的信息量其實非常多,今天簡單說明一部分。

我們在編寫stm32代碼的時候最長使用的地址有兩塊,第一塊是0x0000 0000~0x3FFF FFFF,

第二塊是0x4000 0000~0x5003 FFFF。注意,第二塊地址是我們APB與AHB總線上面掛載著的各種外設的物理地址,我們想要操作外設就是配置這些寄存器地址。我們今天討論的內存是第一塊兒,可供我們進行數據存儲的內存。

首先0x000 000~0x0007 FFFF并不可以用來進行用戶數據存儲,這一段固化的代碼作用是根據BOOT引腳輸入的電平高低來決定將Flash memory、System memory還是SRAM的首地址映射到起始位置。

那么在真正可供我們操作的內存空間中,首先我們來討論SRAM,SRAM只要芯片沒有下電就可以一直存儲數據(除非軟失效等情形發生)。

Option bytes主要可以設置對 Flash 存儲器的讀寫保護級別,防止未經授權的程序對 Flash 中的代碼和數據進行讀取或修改,保障程序和數據的安全性。

System memory里面存儲著ST原廠編寫的bootloader,當我們無法通過工具鏈下載代碼時,可以通過改變boot引腳高低電平的方式選擇使用該段內存中的bootloader。我們經常使用的串口升級代碼也存儲在這一段內存中。

我們平時下載的代碼主要就存儲在0x0800 0000~0x0807 FFFF中,這512K的內存又可以分為兩部分,代碼.text段和數據.rodata段。這段內存的第一個字節(0x08000 0000~0x0800 0003)存儲著至關重要的MSP指針(棧底指針);第二個字節裝著PC指針,PC指針指向了我們的復位函數。

下面介紹SRAM的作用,首先最底部的.data段的數據來源自上圖用戶代碼的.rodatda。那么我們在編程中如何定義變量會導致數據被存儲在.data段內部呢?下面介紹了兩種特定值可修改的變量定義方式。

int cnt3=1;
fun1(void)
{static int cnt=1;
}

其次.bss段存儲兩類內容,一類是FreeRTOS中的heap size,另外一類是其他未初始化或者初始化為0的可修改變量;第二類又可以分為3小類,第一類是如同下文中cnt那樣的未初始化全局變量,第二類是初始化為0的全局變量,第三類是靜態的局部變量。

int cnt;
int cnt1=0;
int fun1(char *argv)
{static int cnt2;}

.s文件中映射單片機堆棧中的數據,msp指針向下壓入數據,當msp向下生長影響到隊時就會在造成棧溢出。堆中的數據則是用malloc手動分配。

那么在移植freertos的過程中,動態創建的任務與靜態創建的任務分別都被存儲在了哪里?都在.bss段中的freertos_heap_size中。

下面討論上下文堆棧:

cortex-M內核擁有雙堆棧機制,除了MSP指針外還有一個PSP指針。在 Cortex-M 內核中,PSP(Process Stack Pointer,進程棧指針)是專門用于應用任務(用戶任務)的棧指針,與 MSP(Main Stack Pointer,主棧指針)配合實現了內核與用戶任務的棧空間分離,是支持實時操作系統(如 FreeRTOS)多任務管理的核心機制之一。

機制原理

  1. 棧指針的分離設計
    Cortex-M 內核有兩個棧指針:

    • MSP(主棧指針):默認用于內核模式(如中斷服務程序、異常處理、內核代碼),復位后默認使用 MSP。
    • PSP(進程棧指針):僅用于用戶模式(應用任務),由用戶任務代碼使用。

    內核通過CONTROL 寄存器的 bit [1] 控制當前使用的棧指針:

    • CONTROL[1] = 0:使用 MSP(內核模式默認)。
    • CONTROL[1] = 1:使用 PSP(用戶任務運行時)。
  2. 任務切換時的 PSP 作用
    當發生任務切換(如由調度器觸發)時:

    • 內核先將當前任務的寄存器狀態(R0-R15 等)壓入該任務的 PSP 所指向的棧空間(保存上下文)。
    • 然后加載下一個任務的 PSP 值(從該任務的 TCB 中獲取),并從其棧中恢復寄存器狀態(恢復上下文)。
    • 最后通過修改 CONTROL 寄存器,使 CPU 切換到 PSP,運行新任務。

核心作用

  1. 實現任務棧隔離
    每個用戶任務擁有獨立的棧空間(由 PSP 指向),任務間的棧數據互不干擾,避免了多任務運行時的棧沖突,提高了系統穩定性。

  2. 支持實時操作系統的多任務調度
    操作系統(如 FreeRTOS)通過管理每個任務的 PSP 值(存儲在 TCB 中),實現快速的任務上下文切換,是多任務并發執行的基礎。

  3. 區分內核與用戶權限
    MSP 用于內核和異常處理,PSP 用于用戶任務,配合內核的特權模式機制,實現了系統資源的權限隔離(如某些寄存器僅能在特權模式下訪問)。

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

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

相關文章

OpenStack 03:創建實例

修改默認安全組 管理規則 添加規則 添加端口22規則 添加ping 規則 下載鏡像文件 Get images — Virtual Machine Image Guide documentation https://mirrors.tuna.tsinghua.edu.cn/fedora/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2 …

企業級架構師綜合能力項目案例一(各種組件集群搭建+SpringBoot整合)

架構圖 用戶請求 → Nginx → Spring Cloud Gateway → 微服務集群↓MySQL集群主從復制(ShardingSphere) Redis集群主從復制(Sentinel)ES集群 MongoDB集群(分片)RocketMQ集群 Seata分布式事務搭建集群 Nginx集群和配置┌─────────…

學習stm32 窗口看門狗

窗口看門狗1.WWDG簡介窗口看門狗用于監測單片機程序運行時效是否精準,主要檢測軟件異常,一般用于需要精準檢測程序運行時間的場合。不僅防止程序 “卡死不喂狗”,還能避免程序 “異常早喂狗”(如死循環中誤執行喂狗指令&#xff0…

Selenium 等待機制:編寫穩定可靠的自動化腳本

一、為什么需要等待機制?網頁是動態加載的,元素出現的時間不確定。如果腳本在元素還沒加載完成時就嘗試操作它,就會拋出 NoSuchElementException 異常。三種等待方式:強制等待:time.sleep() - 簡單但低效隱式等待&…

蓓韻安禧活性葉酸獨立包裝防漏貼心設計

蓓韻安禧葉酸新升級 近期,蓓韻安禧在葉酸產品上進行了重要的優化升級。這次升級的核心在于產品形態和使用體驗的顯著提升,尤其體現在其包裝設計上。新版本采用了獨立密封的小包裝形式,每一份都精準包含每日所需的葉酸量。這種設計不僅有效避免…

8針腳的1.8寸IIC接口的TFT彩屏的八個引腳都需要使用嗎?

核心結論 不需要全部使用8個引腳。實際僅需連接 4根核心線(GND, VCC, SCL, SDA) 即可基本工作,其余引腳為功能增強或備用設計。具體需根據屏幕型號確認,但通用規則如下:8針腳功能分解引腳標號典型名稱是否必需作用不連…

刷題日記0831

今日計劃5道早上起來不困,吃好早飯開始困了,感覺刷不動題,就先做別的事,不困。現在別的事做好了,感覺能刷動題了。開始開始。7/5134. 加油站 中等超時了。看下題解。不是,怎么上數學了?假設從 x…

【2025.8.31】自學Java三個月,談談心路歷程順便給自己灌點雞湯

自學Java三個月,談談心得順便給自己灌點雞湯 6月1開始上班,到今天剛好三個月。從上班第一天決定開始自學java,到今天也是正好3個月整,想借這個機會簡單記錄一下學習java的契機和進度,α一些碎碎念。(括號恐…

linux內核trace_begin和trace_end使用分析

1,strace/ftrace的實現和使用 echo 1 > /sys/kernel/debug/tracing/tracing_on echo function > /sys/kernel/debug/tracing/current_tracer 2, 手動插入追蹤點 在內核代碼中,可以使用trace_printk函數手動插入追蹤點,標記代碼段的開始和結束: trace_printk(&…

Linux-驅動積累

Linux 設備驅動概述?Linux 設備驅動是內核與硬件交互的核心橋梁,負責屏蔽硬件細節、提供統一操作接口。其以內核模塊為主要存在形式,支持動態加載 / 卸載,核心功能涵蓋硬件初始化、中斷處理、電源管理及數據傳輸,是嵌入式 Linux …

軟考-系統架構設計師 決策支持系統(DSS)詳細講解

個人博客:blogs.wurp.top 一、DSS的核心概念與定位 1. 什么是DSS? DSS是一個交互式的、計算機化的系統,旨在幫助決策者利用數據和模型來解決半結構化(Semi-structured) 或非結構化(Non-structured&#…

《Python 實戰:構建一個可擴展的訂單管理系統,從基礎操作到架構思維》

《Python 實戰:構建一個可擴展的訂單管理系統,從基礎操作到架構思維》 一、引言:用代碼管理商業的脈搏 在數字化浪潮席卷各行各業的今天,訂單管理系統已成為電商、物流、零售等領域的核心支撐。它不僅承載著交易數據,更是企業運營效率的體現。而 Python,以其簡潔優雅的…

【計算機網絡】生產問題排查:如何使用Wireshark抓包/讀取抓包文件進行網絡分析

1 緣起 有一次,公司同事A讓同事B看一次請求日志, 同事B說先抓一次包看看請求是否進入服務器-某個服務, 我知道這個事情后,也“參觀”了抓包過程, 上面的事件只是一個小插曲,緊接著的第二件事才是寫本篇文章的真正動機: 同一天,同事C讓同事D配置個服務代理(某種上網方…

網格dp|

lc3665class Solution {public:int uniquePaths(vector<vector<int>>& grid) {const int MOD 1000000007;int m grid.size(), n grid[0].size();vector memo(m, vector(n, array<int, 2>{-1, -1})); // -1 表示沒有計算過auto dfs [&](this auto…

煩人的Nano 編輯器,如何退出呢?

對于不熟悉 nano 編輯器的人來說&#xff0c;它的退出方式確實有點反直覺。別擔心&#xff0c;這是幾乎所有新手都會遇到的困惑。 退出 Nano 編輯器的正確方法 記住這個黃金法則&#xff1a;ctrl鍵是你的朋友&#xff01; 1. 正常保存并退出&#xff08;最常用&#xff09; 按 …

IDM(Internet Download Managerv 6.38)破除解版下載!IDM 下載器永久免費版!提升下載速度達5倍!安裝及使用

軟件介紹 IDM&#xff08;Internet Download Manager&#xff09;是一款功能強大的 Windows 平臺專業下載加速工具&#xff0c;可加速下載速度、調度任務、續傳下載、管理文件。可使下載速度提升至普通瀏覽器的 5 倍以上&#xff0c;最高可加速 8 倍。IDM 支持 HTTP、FTP、HTTP…

學習Java29天(tcp多發多收)但是無解決客戶端啟動多個問題

180/189今天看了一些ip的東西WLAN的ip是路由器隨機分配的&#xff08;DHCP&#xff09;

Photoshop - Ps Camera Raw 濾鏡

使用Adobe Photoshop Camera Raw濾鏡對圖像進行快速和可逆的編輯。Camera Raw濾鏡將圖像拖入Photoshop工作區&#xff0c;或者點擊菜單欄-文件-打開來打開圖像。選中圖像的對應的圖層&#xff0c;點擊菜單欄-濾鏡-Camera Raw濾鏡&#xff0c;彈出Camera Raw濾鏡面板。使用Camer…

Node.js(4)—— http模塊基礎

下面我們來學nodejs中的http模塊。在此之前&#xff0c;你需要有一定的網絡知識儲備&#xff0c;能知道http&#xff0c;IP&#xff0c;端口是什么并且它們之間的關系。如果還不清楚或比較模糊&#xff0c;可以查看下面的文章&#xff1a; HTTP協議與IP 下面我們開始學習。 目…

后端去拿數據怎么拿?

簡單來說&#xff0c;Entity 和 DTO 代表了數據在不同層次和場景下的不同形態和目的。它們最根本的區別在于&#xff1a;職責和目的不同。一句話概括Entity&#xff1a;代表數據庫中的表&#xff0c;是業務邏輯的核心&#xff0c;與持久化&#xff08;數據庫&#xff09;緊密相…