← Back to list

IAR新手村-記憶體結構與堆疊還原技巧

這一年經歷了一個案子的中期與結束,目前處於另一個案子的開始,趁這個空檔把這一年從學長那邊學到的IAR知識,以及自學的成果紀錄一下,如果有任何錯誤或待修正的地方,也請不要吝嗇地盡情指點我(?)

Yunnie · 2025-05-31 02:24 · 0 claps · 3.9 min read
#iar #embedded #engineering
Open on Medium ↗

IAR新手村-記憶體結構與堆疊還原技巧

這一年經歷了一個案子的中期與結束,目前處於另一個案子的開始,趁這個空檔把這一年從學長那邊學到的IAR知識,以及自學的成果紀錄一下,如果有任何錯誤或待修正的地方,也請不要吝嗇地盡情指點我(?)

這篇文章主要說明 IAR 在 ARM 架構下的記憶體分布、.icf linker script 如何控制記憶體使用,以及當 Call Stack 錯亂時,如何手動透過 Memory 視窗進行還原。

ARM Cortex-M 的記憶體概念

ARM Cortex-M 系列會從 Flash 開始執行,並使用 SRAM 作為 stack 與變數區。

IAR .icf 記憶體配置檔範例

IAR 使用 .icf (IAR Configuration File) 定義記憶體範圍與各段區段位置:

define symbol __ICFEDIT_region_ROM_start__  = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__    = 0x0803FFFF;
define symbol __ICFEDIT_region_RAM_start__  = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__    = 0x2001FFFF;

搭配:

place in ROM_region   { readonly };    // Code + const 資料
place in RAM_region   { readwrite, section CSTACK };  // 變數 + stack

另外加入:

define block CSTACK with alignment = 8, size = 0x400 { section CSTACK };

這些定義會對應到啟動檔 startup.s 的 stack 初始化參數。

自定多段記憶體區域的範例

如果你的 MCU 有多段 SRAM,例如 SRAM1, SRAM2,或你需要將不同模組資料放入特定記憶體區段,可以這樣定義:

Step 1:定義多段記憶體區段

define region SRAM1_region = mem:[from 0x20000000 to 0x2000FFFF];
define region SRAM2_region = mem:[from 0x20010000 to 0x2001FFFF];

Step 2:自訂放置條件

place in SRAM1_region { section .fast_data };   // 放入較快 SRAM
place in SRAM2_region { readwrite };            // 一般變數

Step 3:程式碼中指定 section

#pragma default_variable_attributes = @ ".fast_data"
int fast_buffer[256];

或使用 GCC 標準寫法(若為裸機混編):

__attribute__((section(".fast_data"))) int fast_buffer[256];

這種方式常見於:

  • 將 audio buffer 放到高速 SRAM
  • 指令放 ITCM、資料放 DTCM
  • bootloader 和主程式共用 Flash 不同段

Stack 是怎麼運作的?

  • ARM Cortex-M 使用遞減堆疊(descending stack)
  • SP(Stack Pointer)從高地址往低地址推進
  • 呼叫函式時,return address、參數、暫存器會 push 到 stack
  • return 時會 pop 回來

當 Stack Overflow 發生時:

  • stack 超過分配空間 → 覆蓋鄰近變數 → 系統錯誤或 Crash
  • IAR 可啟用 Stack Usage 分析來偵測最大用量

當 IAR 的 Call Stack 視窗錯亂,常見原因包含 stack 被破壞、跳轉錯誤等。這時可手動透過 SP 與 Memory 檢查 return address:

步驟:

  1. 開啟 Registers 視窗 → 找到 SP(R13)值,例如 0x20001FF0
  2. 開啟 Memory 視窗,輸入該地址 → 查看內容
  3. 尋找類似 0x0800XXXX 的地址(Flash 中的函式)
  4. 將該值 copy → 在 DisassemblySymbolic 視窗貼上查看
  5. 可逐層上推,還原調用順序

(等我補圖片)


메타데이터
post_id
fe1793ab2e04
slug
iar新手村-記憶體結構與堆疊還原技巧-fe1793ab2e04
url
https://medium.com/@fearless1997s/iar%E6%96%B0%E6%89%8B%E6%9D%91-%E8%A8%98%E6%86%B6%E9%AB%94%E7%B5%90%E6%A7%8B%E8%88%87%E5%A0%86%E7%96%8A%E9%82%84%E5%8E%9F%E6%8A%80%E5%B7%A7-fe1793ab2e04
canonical_url
https://medium.com/@fearless1997s/iar%E6%96%B0%E6%89%8B%E6%9D%91-%E8%A8%98%E6%86%B6%E9%AB%94%E7%B5%90%E6%A7%8B%E8%88%87%E5%A0%86%E7%96%8A%E9%82%84%E5%8E%9F%E6%8A%80%E5%B7%A7-fe1793ab2e04
author_url
https://medium.com/@fearless1997s
status
ok
fetched_at
2026-07-19 16:10:01