在 Keil 中將 STM32 工程下載到 RAM 進行調試運行

在 Keil 中將 STM32 工程下載到 RAM 進行調試運行

在使用 STM32 進行調試時,默認情況下代碼會被燒寫到 Flash 中運行。然而,Flash 寫入速度較慢,擦寫次數有限,且調試過程中頻繁燒寫可能影響開發效率。在某些場景下(如快速驗證代碼或避免 Flash 擦寫),我們可以將代碼直接下載到 STM32 的內部 RAM 中運行并進行調試。

本文以 STM32H750 為例,詳細介紹如何在 Keil 中配置工程,使代碼下載到 RAM 并進行調試。其他 STM32 系列芯片的配置方法類似,只需根據芯片的 RAM 地址和大小進行調整。


1. 關閉默認的 Memory Layout 配置

在 Keil 中,打開工程配置窗口:

  1. 點擊菜單欄 Project -> Options for Target
  2. 切換到 Linker 選項卡。
  3. 取消勾選 Use Memory Layout from Target Dialog

說明
取消該選項后,Keil 將不再使用 Target 選項卡中配置的 ROM 和 RAM 地址,而是完全依賴用戶自定義的 Scatter File (.sct) 來定義代碼和數據的內存布局。這一步是實現 RAM 調試的關鍵。
在這里插入圖片描述


2. 配置 Scatter File (.sct)

由于取消了默認內存布局,需要創建一個分散加載文件(.sct 文件)來指定代碼和數據的存儲位置。
Options for Target -> Linker 中,啟用 Use Scatter File 選項,并創建一個 .sct 文件,用于定義代碼和數據的內存分配。
在這里插入圖片描述

以下是以 STM32H750 為例的 .sct 文件內容:

; *************************************************************
; *** Scatter-Loading Description File for STM32H750 RAM Debug ***
; *************************************************************LR_IROM1 0x24000000 0x00080000  {    ; Load region: AXI SRAM (512KB)ER_IROM1 0x24000000 0x00080000  {  ; Execution region: Code and constants*.o (RESET, +First)              ; Reset vector and Reset_Handler*(InRoot$$Sections)              ; Linker-specific root sections.ANY (+RO)                       ; Read-only sections (code and constants).ANY (+XO)                       ; Execute-only sections (if any)}RW_IRAM1 0x20000000 0x00020000  {  ; Execution region: DTCM RAM (128KB).ANY (+RW +ZI)                   ; Read-write and zero-initialized data}
}

說明

  • LR_IROM1:定義加載區域,起始地址為 0x24000000(STM32H750 的 AXI SRAM 起始地址),大小為 512KB
  • ER_IROM1:定義代碼和常量數據的執行區域,放置在 AXI SRAM 中。
    • *.o (RESET, +First):將復位向量表和 Reset_Handler 放在執行區域的開頭。
    • *(InRoot$$Sections):包含鏈接器需要的根區段(如初始化代碼)。
    • .ANY (+RO):將所有只讀數據(代碼和常量)分配到該區域。
    • .ANY (+XO):將僅執行代碼(若有)分配到該區域。
  • RW_IRAM1:定義讀寫數據和零初始化數據的執行區域,起始地址為 0x20000000(DTCM RAM 起始地址),大小為 128KB
    • .ANY (+RW +ZI):將讀寫數據和零初始化數據分配到 DTCM RAM。

注意

  • 不同 STM32 芯片的 RAM 地址和大小不同,請參考芯片的參考手冊或數據手冊(如 STM32H750 的 AXI SRAM 和 DTCM RAM 地址)。
  • 確保程序的代碼和數據總大小不超過目標 RAM 的容量。

3. 禁用 Flash 編程算法

由于我們希望代碼運行在 RAM 中,而不是 Flash 中,因此需要禁用 Keil 的 Flash 編程功能:

  1. 打開 Options for Target -> Utilities
  2. 取消勾選 Use Target Driver for Flash Programming
  3. 選擇 Use External Tool for Flash Programming

說明
禁用 Flash 編程算法后,Keil 不會嘗試將代碼寫入 Flash,而是直接將程序加載到指定的 RAM 地址。
在這里插入圖片描述


4. 配置調試初始化文件 (.ini)

為了確保程序從 RAM 正確啟動,需要配置一個調試初始化文件(.ini),用于設置棧指針(SP)、程序計數器(PC)以及向量表偏移寄存器(VTOR)。在 Options for Target -> Debug 中,啟用 Initialization File 選項,并創建一個 .ini 文件,
在這里插入圖片描述

內容如下:

/***********************************************************/
/* Debug_RAM.ini: Initialization File for Debugging from RAM */
/***********************************************************/FUNC void Setup (void) {SP = _RDWORD(0x24000000);        // Set Stack Pointer (SP) from RAM vector tablePC = _RDWORD(0x24000004);        // Set Program Counter (PC) from RAM reset vector_WDWORD(0xE000ED08, 0x24000000); // Set Vector Table Offset Register (VTOR) to RAM
}FUNC void OnResetExec (void) {      // Executes upon software resetSetup();                          // Reinitialize runtime environment
}LOAD %L INCREMENTAL                // Load the .axf file to RAM
Setup();                           // Call Setup function to initialize runtime
g, main                            // Jump to main function

說明

  • _RDWORD(addr):從指定地址讀取一個 4 字節的字。
  • _WDWORD(addr, val):向指定地址寫入一個 4 字節的字。
  • SP = _RDWORD(0x24000000):從 RAM 的起始地址(AXI SRAM)讀取棧指針初值。
  • PC = _RDWORD(0x24000004):從 RAM 的復位向量地址讀取程序計數器初值。
  • _WDWORD(0xE000ED08, 0x24000000):將向量表偏移寄存器(VTOR)設置為 RAM 起始地址,確保中斷向量表正確指向 RAM。
  • LOAD %L INCREMENTAL:將編譯生成的 .axf 文件加載到 RAM。
  • g, main:跳轉到 main 函數開始執行。

注意

  • 確保 .ini 文件中的地址與 .sct 文件中的 RAM 地址一致。
  • 如果芯片的 RAM 地址不同,需要相應修改 .ini 文件中的地址。

5. 配置調試和下載選項

為了確保程序只加載到 RAM 而不影響 Flash,需要調整調試和下載設置:

  1. 打開 Options for Target -> Debug -> Settings -> Flash Download
  2. Programming Algorithm 中,刪除所有與 Flash 相關的算法。
  3. Download Function 中:
    • 選擇 Do not Erase
    • 取消勾選 Program

說明
這些設置確保 Keil 不會擦除或寫入 Flash,而是直接將程序加載到 RAM 中運行。
在這里插入圖片描述


6. 編譯并進入調試模式

完成以上配置后:

  1. 點擊 Build 編譯工程,確保無錯誤。
  2. 點擊 Debug -> Start/Stop Debug Session 進入調試模式。
  3. 程序將自動下載到 RAM 并從 RAM 啟動運行。

驗證

  • 在調試模式下,檢查程序計數器(PC)是否指向 RAM 地址(如 0x24000000 開頭的地址)。
  • 確保中斷和函數調用正常工作。
    在這里插入圖片描述

常見問題與注意事項

  1. RAM 大小限制
    確保程序的代碼和數據總大小不超過目標 RAM 的容量。例如,STM32H750 的 AXI SRAM 為 512KB,DTCM RAM 為 128KB。如果程序過大,可能需要優化代碼或選擇其他 RAM 區域。

  2. 復位向量地址
    .sct 文件中,RESET 段必須位于 RAM 的起始地址(如 0x24000000),否則程序無法正確啟動。

  3. 中斷向量表
    確保 .ini 文件中正確設置了 VTOR 寄存器(如 _WDWORD(0xE000ED08, 0x24000000)),以將中斷向量表重定位到 RAM,否則中斷可能無法正常工作。

  4. 硬件斷點限制
    在 RAM 調試時,調試器支持的硬件斷點數量可能有限(通常為 6-8 個,具體取決于調試器和芯片)。如果需要設置更多斷點,可以考慮使用軟件斷點(需確保代碼支持)。

  5. 調試器兼容性
    確保使用的調試器(如 ST-Link、J-Link)支持 RAM 調試。某些低端調試器可能對 RAM 調試支持有限。

  6. 初始化代碼
    如果程序依賴特定的硬件初始化(如時鐘或外設),確保這些代碼在 RAM 運行時仍然有效。某些外設可能需要額外的配置以支持 RAM 執行。


總結

通過以上步驟,您可以在 Keil 中將 STM32 工程配置為從 RAM 運行并進行調試,從而避免頻繁擦寫 Flash,提高調試效率。關鍵步驟包括:

  1. 使用 .sct 文件手動定義內存布局。
  2. 配置 .ini 文件以設置 RAM 啟動環境。
  3. 禁用 Flash 編程算法,僅將程序加載到 RAM。

此方法適用于快速調試、驗證代碼邏輯或需要保護 Flash 的場景。希望這篇教程能幫助您順利實現 STM32 的 RAM 調試!🚀

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

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

相關文章

【51單片機】【protues仿真】基于51單片機寵物投食系統

目錄 一、主要功能 二、使用步驟 三、硬件資源 四、軟件設計 五、實驗現象 一、主要功能 1、LCD1602液晶顯示時間、溫度、食物重量 2、按鍵手動投喂食物? 3、稱重模塊檢測當前食物重量 4、食物重量小于閾值會聲光警報并自動投喂 二、使用步驟 基于51單片機的寵物投食…

騰訊云負載均衡增加訪問策略后訪問失敗

為了測試,在負載均衡的安全組添加2條安全策略,限制辦公室內IP可訪問,其他IP地址拒絕所有訪問。結果,訪問失敗。經過反復測試,主要是js問價加載失敗,動態接口訪問代碼返回正常。再進行測試,發現去…

CSS的文本樣式

1.文本樣式的分類注意&#xff1a;必須先建立標簽&#xff0c;再在head中修改1.1字體樣式1.1.1字體顏色代碼演示<head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title&g…

R語言讀取excel文件數據-解決na問題

文章目錄安裝R語言運行環境實現代碼遇到的問題總結安裝R語言運行環境 安裝教程連接, 包含國內鏡像快速下載 實現代碼 實現思路&#xff1a;使用python將文件的空字符的位置變成0&#xff0c;生成csv文件后交給R語言處理python實現代碼如下&#xff1a; import pandas as pd…

【Nginx 運維實戰】版本替換:強制 vs 平滑升級全解析

【Nginx 運維實戰】版本替換&#xff1a;強制 vs 平滑升級全解析一&#xff1a;版本替換的兩種思路二&#xff1a;使用場景對比三&#xff1a;實戰1&#xff09;強制替換1.備份舊版本2.替換為新版本3.**賦予執行權限**4.**重啟 Nginx**2&#xff09;平滑替換1.確認進程文件2.備…

MQ-消息隊列

定義 Mssage Queue&#xff1a;消息隊列。它是一種“先進先出”&#xff08;FIFO&#xff09;的數據結構&#xff0c;用于在分布式系統或應用程序之間進行異步通信。組成1. 生產者&#xff08;Producer&#xff09;定義&#xff1a;消息的發送方&#xff0c;負責將業務系…

NVIDIA驅動程序核心的“即時編譯器”(Just-in-Time, JIT Compiler)詳細介紹

我們來詳細、深入地剖析這個位于NVIDIA驅動程序核心的“即時編譯器”&#xff08;Just-in-Time, JIT Compiler&#xff09;。它堪稱CUDA生態系統成功的“幕后英雄”&#xff0c;是連接軟件穩定性和硬件飛速發展的關鍵橋梁。 第一部分&#xff1a;JIT編譯器的本質 首先&#xff…

【PS2025全網最新版】穩定版PS2025保姆級下載安裝詳細圖文教程(附安裝包)(Adobe Photoshop)

今天&#xff0c;給大家帶來PS2025的保姆級下載安裝圖文教程。 前言&#xff1a; Adobe Photoshop 作為業界領先的圖像處理與設計軟件&#xff0c;持續推動著數字創意領域的發展。其應用涵蓋平面設計、攝影后期、UI/UX 設計、影視特效等多個專業方向&#xff0c;為用戶提供強…

分享TWS充電倉方案開發設計

TWS耳機市場“卷”到最后&#xff0c;拼的早已不只是音質&#xff0c;而是續航、交互、體積、成本四位一體。傳統充電倉用多顆IC堆砌&#xff1a;升壓、電量計、霍爾、LED驅動、保護IC……BOM高、貼片復雜、調試周期長。8位MCU把上述功能“一鍋端”&#xff1a;單芯片即完成電源…

【Java實戰?】深入Java單元測試:JUnit 5實戰指南

目錄一、單元測試概述1.1 單元測試概念1.2 單元測試優勢1.3 JUnit 5 框架組成1.4 JUnit 5 環境搭建二、JUnit 5 核心功能實戰2.1 測試類與測試方法2.2 測試生命周期2.3 斷言方法2.4 異常測試三、單元測試進階實戰3.1 參數化測試3.2 測試套件3.3 Mockito 框架3.4 單元測試實戰案…

分布式微服務--ZooKeeper作為分布式鎖

看這篇博客之前可以先去了解博主的另一篇講解ZooKeeper的博客&#xff1a;分布式微服務--ZooKeeper的客戶端常用命令 & Java API 操作-CSDN博客 1. 為什么需要分布式鎖&#xff1f; 在分布式系統中&#xff0c;多個服務節點可能同時訪問或修改同一份共享資源&#xff08;例…

基于容器化云原生的 MySQL 及中間件高可用自動化集群項目

1 項目概述 本項目旨在構建一個高可用、高性能的 MySQL 集群,能夠處理大規模并發業務。通過容器化部署、多級緩存、完善的監控和備份策略,確保數據庫服務的連續性和數據安全性。 架構總覽 預期目標 數據庫服務可用性達到 99.99% 支持每秒 thousands 級別的并發訪問 實現秒…

如何將 iPhone 備份到電腦/PC 的前 5 種方法

定期備份你的 iPhone&#xff08;最好每兩周一次&#xff09;對于保護你的數據至關重要。它確保了如果設備損壞、丟失或被盜&#xff0c;或者你換了新手機&#xff0c;你不會丟失重要信息&#xff0c;并且可以輕松地從備份中恢復應用程序、照片、設置等。如果你不確定如何備份 …

國產AI芯片編程模型深度對比:寒武紀MLU vs 壁仞BR100異構計算設計

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;H卡級別算力&#xff0c;80G大顯存&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生更享專屬優惠。 引言&#xff1a;國產AI芯片的崛起與挑戰 隨著人工智能技術的飛速…

【項目】基于One Thread One Loop模型的高性能網絡庫實現 - 項目介紹與前置知識

目錄 項目介紹 HTTP服務器基本認識 Reactor模式基本認識 單Reactor單線程模式認識 單Reactor多線程模式認識 多Reactor多線程模式認識 模塊劃分 Server模塊 Buffer模塊 Socket模塊 Channel模塊 Connection模塊 Acceptor模塊 TimerQueue模塊 Poller模塊 EventLo…

lua中table鍵類型及lua中table的初始化有幾種方式

在 Lua 中&#xff0c;table 的鍵幾乎可以是任何類型&#xff0c;但有幾個重要的規則和最佳實踐需要了解。1. 主要鍵類型(1) 字符串 (string)這是最常見、最推薦的鍵類型。local person {name "Alice", -- 等同于 ["name"] "Alice"["age…

matlab實現利用雙MZI產生RZ33-QPSK信號

利用MATLAB實現雙MZI產生RZ33-QPSK信號的代碼&#xff1a; 參數設置 % 信號參數 fs 1e6; % 采樣頻率 fc 10e6; % 載波頻率 T 1e-6; % 符號周期 N 1000; % 采樣點數 t 0:1/fs:(N-1)/fs; % 時間向量生成QPSK信號 % 生成隨機二進制序列 data randi([0,1],1,N);% 將二進制序列…

Vue響應式更新 vs React狀態更新:兩種范式的底層邏輯與實踐差異

在現代前端框架中&#xff0c;Vue和React作為兩大主流選擇&#xff0c;分別采用了截然不同的狀態管理與更新機制。Vue的“響應式更新”通過自動追蹤依賴實現數據與視圖的聯動&#xff0c;而React的“狀態更新”則依賴顯式setState觸發重新渲染。本文將從底層原理、更新流程、優…

Spring MVC 的常用注解

一、控制器相關注解ControllerController注解用于標記一個類為 Spring MVC 的控制器。在 Spring MVC 框架里&#xff0c;控制器扮演著關鍵角色&#xff0c;負責接收 HTTP 請求并返回響應。當一個類被Controller注解標記后&#xff0c;Spring 容器會自動識別并將其納入管理。例如…

Oracle APEX 利用卡片實現翻轉(方法一)

目錄 0. 以 Oracle 的標準示例表 EMP 為例&#xff0c;實現卡片翻轉 1. 創建PL/SQL動態內容區域 2. 添加 CSS 實現翻轉效果 3. 添加動態操作 (Dynamic Action) 4. 看效果 0. 以 Oracle 的標準示例表 EMP 為例&#xff0c;實現卡片翻轉 正面&#xff1a; 顯示員工姓名 (EN…