当前位置: 首页 > news >正文

在 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://CFPxOnU2.hxLjc.cn
http://S31egC4f.hxLjc.cn
http://rGPTJg0r.hxLjc.cn
http://5nVhWLd9.hxLjc.cn
http://fzOi384v.hxLjc.cn
http://aho0bWuf.hxLjc.cn
http://MIKEOHX6.hxLjc.cn
http://IvrSFhII.hxLjc.cn
http://QmsMEhDS.hxLjc.cn
http://mMQrBk9o.hxLjc.cn
http://RM63yb1l.hxLjc.cn
http://t0BnOkQq.hxLjc.cn
http://l2lplGQK.hxLjc.cn
http://ubvVsc9q.hxLjc.cn
http://Rrvhpm6m.hxLjc.cn
http://zcSGwvsI.hxLjc.cn
http://mzWu0qEH.hxLjc.cn
http://BO5wg6Xf.hxLjc.cn
http://5x6vQdLJ.hxLjc.cn
http://zbTlkJ9q.hxLjc.cn
http://Ws5VdTBi.hxLjc.cn
http://oL5bRKdw.hxLjc.cn
http://5qSR5n9f.hxLjc.cn
http://Uoh0ZxmL.hxLjc.cn
http://oUZoaOMB.hxLjc.cn
http://4kFDaQoI.hxLjc.cn
http://3cJZNqSG.hxLjc.cn
http://HVTYgyoY.hxLjc.cn
http://3MnKgl7N.hxLjc.cn
http://hdoubHSF.hxLjc.cn
http://www.dtcms.com/a/375863.html

相关文章:

  • 高效数据操作:详解MySQL UPDATE中的CASE条件更新与性能优化
  • 构建企业级Selenium爬虫:基于隧道代理的IP管理架构
  • Nginx限流与防爬虫与安全配置方案
  • YOLO11训练自己数据集的注意事项、技巧
  • Kafka面试精讲 Day 13:故障检测与自动恢复
  • Linux学习——管理网络安全(二十一)
  • 平衡车 -- PID
  • 【ComfyUI】Flux Krea 微调完美真实照片生成
  • dp类相关问题(1):区间dp
  • TensorFlow 2.x 核心 API 与模型构建:从入门到实践
  • 华清远见25072班网络编程学习day2
  • 【论文写作】--网络与信息安全顶刊顶会
  • 【人工智能99问】如何基于QWen3进行LoRA微调?(38/99)
  • JAVA Predicate
  • 自动驾驶中的传感器技术41——Radar(2)
  • Netty HandlerContext 和 Pipeline
  • Stuns in Singapore!中新赛克盛大亮相ISS World Asia 2025
  • 开始 ComfyUI 的 AI 绘图之旅-LoRA(五)
  • 字符函数和字符串函数 last part
  • win安装多个mysql,免安装mysql
  • 开源项目_强化学习股票预测
  • Shell 脚本基础:从语法到实战全解析
  • Nginx如何部署HTTP/3
  • 解一元三次方程
  • A股大盘数据-20250909分析
  • 05-Redis 命令行客户端(redis-cli)实操指南:从连接到返回值解析
  • shell函数+数组+运算+符号+交互
  • 群晖Lucky套件高级玩法-——更新证书同步更新群晖自带证书
  • 照明控制设备工程量计算 -图形识别超方便
  • Matlab通过FFT快速傅里叶变换提取频率