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

如何在Keil5中在没有硬件支持的情况下使用Keil的模拟器(Simulator) + 调试窗口输出进行调试

如何在Keil5中在没有硬件支持的情况下使用Keil的模拟器(Simulator) + 调试窗口输出进行调试

  • 一、核心配置步骤
    • 1. 启用仿真器并选择软件仿真
    • 2. 问题分析与解决方案
      • 2.1 问题原因
      • 2.2 解决方案
        • 2.2.1 创建初始化脚本文件
      • 2.3 验证仿真环境
      • 2.4 如果问题仍然存在
  • 二、善用仿真组件与调试窗口
    • 1. 配置逻辑分析仪
      • 1.1 进入调试模式:
      • 1.2 打开逻辑分析仪:
      • 1.3 添加GPIOD12信号:
    • 2. 可能的报错
    • 3. 解决办法:
      • 3.1 尝试直接地址访问法
      • 3.2 通过全局变量间接观察(万能方法,推荐用)
  • 三、软件仿真的局限性
  • 四、实用技巧与问题排查

在STM32F407项目开发中,使用Keil MDK的 Use Simulator 进行纯软件仿真,可以在没有硬件的情况下测试和调试代码的基本逻辑,我结合工程经验为你梳理了以下设置要点和技巧。

一、核心配置步骤

1. 启用仿真器并选择软件仿真

  • 在Keil MDK中,进入 Options for TargetDebug 选项卡。

  • 选择 Use Simulator。这表明你将使用MDK内置的仿真环境,而不是物理调试器。

  • Driver DLL 中,确保选择了适用于Cortex-M内核的仿真驱动,例如 SARMCM3.DLL。这一步对正确模拟Cortex-M4内核至关重要。

  • Parameter:此处需指定你的具体芯片型号,例如STM32F407ZG芯片则填写 -pSTM32F407ZG。请确保这与你在"Target"选项卡中选择的型号一致。

  • 正确设置外部晶振频率和系统时钟。即使是在仿真中,这些时钟设置也会影响延时函数等的执行。

Dialog DLL:DARMSTM.DLLParameter:-pXXXXXXXXXX(必须与 Device 选项卡中选定的芯片完全一致(如STM32F407ZG → -pSTM32F407ZG))。

在这里插入图片描述
在这里插入图片描述

2. 问题分析与解决方案

*** error 65: access violation at 0x40023830 : no 'read' permission

这个错误表示在线仿真时尝试读取一个没有读取权限的内存地址 0x40023830。在STM32F407中,这个地址对应的是 RCC (复位和时钟控制) 寄存器

2.1 问题原因

  • 地址分析: 0x40023830 是 RCC_APB2ENR 寄存器的地址
  • 权限问题: 仿真器没有正确配置对该外设地址空间的访问权限
  • 代码触发: 可能是代码中访问了RCC寄存器,但仿真环境没有正确映射

2.2 解决方案

2.2.1 创建初始化脚本文件

创建一个名为 simulation.ini 的文件,内容如下:

// STM32F407 完整仿真配置
FUNC void Setup(void) {// 清除现有的内存映射MAP 0x40000000, 0x400FFFFF UNMAPMAP 0x50000000, 0x50060BFF UNMAP// 重新映射所有必要的外设区域MAP 0x40000000, 0x400FFFFF READ WRITE EXEC  // AHB1/APB1/APB2 外设MAP 0x50000000, 0x50060BFF READ WRITE EXEC  // AHB2 外设 (GPIO)MAP 0x60000000, 0xA0000FFF READ WRITE EXEC  // AHB3 外设 (FSMC)// 特别映射关键外设区块MAP 0x40020000, 0x400203FF READ WRITE EXEC  // GPIOAMAP 0x40020400, 0x400207FF READ WRITE EXEC  // GPIOB  MAP 0x40020800, 0x40020BFF READ WRITE EXEC  // GPIOCMAP 0x40020C00, 0x40020FFF READ WRITE EXEC  // GPIODMAP 0x40021000, 0x400213FF READ WRITE EXEC  // GPIOEMAP 0x40021400, 0x400217FF READ WRITE EXEC  // GPIOFMAP 0x40021800, 0x40021BFF READ WRITE EXEC  // GPIOGMAP 0x40021C00, 0x40021FFF READ WRITE EXEC  // GPIOHMAP 0x40022000, 0x400223FF READ WRITE EXEC  // GPIOI// RCC 相关寄存器MAP 0x40023800, 0x40023BFF READ WRITE EXEC  // RCC// 系统配置MAP 0x40013000, 0x400133FF READ WRITE EXEC  // SYSCFGMAP 0x40013800, 0x40013BFF READ WRITE EXEC  // EXTI// 调试输出printf("=========================================\n");printf("STM32F407 软件仿真环境初始化完成\n");printf("外设内存映射已配置\n");printf("=========================================\n");
}// 执行初始化
Setup();

然后在MDK中配置使用此脚本:

  • Options for TargetDebugInitialization File
  • 选择你创建的 simulation.ini 文件

2.3 验证仿真环境

创建一个简单的测试程序来验证仿真环境:

// 在main函数或其他需要的地方更新状态
int main(void)
{// 初始化代码...while(1){// 翻转PD12之前或之后更新状态变量GPIO_ToggleBits(GPIOD, GPIO_Pin_12);                // 延时或其他代码Delay_ms(100);}
}

2.4 如果问题仍然存在

如果上述方法都不能解决问题,可以尝试:

  1. 重置仿真环境

    • 关闭MDK
    • 删除项目目录中的 *.uvoptx*.uvguix.* 文件
    • 重新打开项目
  2. 使用不同的仿真驱动

    • DebugSettings 中尝试不同的仿真驱动
  3. 检查MDK版本兼容性

    • 确保使用支持STM32F4系列的MDK版本

按照这些步骤操作,应该能解决 access violation 错误并成功进行STM32F407的在线仿真。

二、善用仿真组件与调试窗口

1. 配置逻辑分析仪

1.1 进入调试模式:

  • 点击 Start/Stop Debug Session 或按 Ctrl+F5

1.2 打开逻辑分析仪:

  • 菜单:View → Analysis Windows → Logic Analyzer

  • 或使用工具栏按钮

1.3 添加GPIOD12信号:

  • 在逻辑分析仪窗口中点击 Setup 按钮

  • 点击 Add New 按钮添加新信号

  • 在 Expression 栏中输入:(GPIOD->ODR & 0x1000) >> 12

在这里插入图片描述

2. 可能的报错

在添加引脚的时候就会出现报错:Unknown Signal !
在这里插入图片描述
Virtual Registers缺失:在软件仿真时,逻辑分析仪依赖Virtual Registers来识别外设寄存器。如果其中没有PORTF,输入PORTF.9等表达式就会报"Unknown Signal"。

芯片内核与仿真配置不匹配:您的工程可能使用的是Cortex-M3内核的配置(如SARMCM3.DLL),但如果实际芯片是其他内核(如M0或M4),或者仿真参数(Parameter)与芯片型号不精确匹配,就会导致外设寄存器无法访问。

Debug.ini文件未正确配置:如果没有正确配置初始化文件来映射外设寄存器的地址空间并设置读写权限,仿真时可能无法访问这些寄存器。

3. 解决办法:

直接测试下面的值尝试:

((((GPIO_TypeDef *) ((((uint32_t)0x40000000) + 0x00020000) + 0x0C00))->ODR & 0x1000) >> 12 & 0x1000) >> 12

3.1 尝试直接地址访问法

如果 PORTF 仍无法识别,直接操作对应的寄存器地址是更底层通用的方法。查找 GPIOF 的基地址:在芯片数据手册或参考手册的存储器映射中查找 GPIOF 的基地址(例如STM32F103系列中 GPIOF 的ODR寄存器地址可能为 0x4002140C)。在逻辑分析仪中添加信号:添加方法:直接输入地址表达式。逻辑分析仪中输入内容示例:*((unsigned long*)0x4002140C) & 0x0200) >> 9 (假设 0x4002140C 是 GPIOF_ODR 地址,0x0200 掩码针对Bit 9)。说明:此法直接访问内存地址,不依赖Virtual Registers,更可靠。添加后,同样需要设置该信号的 Display Type 为 Bit。

3.2 通过全局变量间接观察(万能方法,推荐用)

如果上述方法均无效,可以在代码中将GPIOF9的状态映射到一个全局变量,然后在逻辑分析仪中观察该变量。

在代码中定义并更新全局变量:

// 在全局区域定义变量
volatile uint8_t PD12_State = 0;// 在main函数或其他需要的地方更新状态
int main(void)
{// 初始化代码...while(1){// 翻转PD12之前或之后更新状态变量GPIO_ToggleBits(GPIOD, GPIO_Pin_12);// 读取PD12当前状态并更新全局变量PD12_State = (GPIOD->ODR & GPIO_Pin_12) ? 1 : 0;// 或者使用IDR读取实际引脚状态(如果是输入模式)// PD12_State = (GPIOD->IDR & GPIO_Pin_12) ? 1 : 0;// 延时或其他代码Delay_ms(100);}
}

在逻辑分析仪中直接添加全局变量 GPIOF9_State,并将其 Display Type 设置为 Bit。

三、软件仿真的局限性

非常重要的一点是,MDK的Use Simulator是一个软件仿真环境,它主要通过模拟ARM内核指令和部分核心外设来工作。

  • 外设模拟不完全:对于STM32F407复杂的片内外设(如USB、以太网、特定型号的ADC/DMA等),仿真可能无法完全或精确地模拟其行为。你可能无法像在真实硬件上那样依赖所有这些外设的仿真结果。
  • 时序差异:仿真执行速度与真实硬件速度不同,不能用于精确的性能测量。

四、实用技巧与问题排查

  • 添加软件仿真配置脚本:对于一些复杂的初始化(例如内存映射、时钟树),你可以编写或使用.INI格式的脚本文件,在仿真启动时通过 DebugInitialization File 指定并自动加载执行。
  • 检查初始化代码:确保你的 SystemInit() 和时钟配置(SetSysClock() 等)函数与软件仿真环境兼容。有时过于复杂的低功耗或时钟配置可能会在仿真中引发意外行为。
  • 理解仿真日志:关注MDK的 Command 窗口,仿真器可能会在那里输出重要的状态或错误信息。
http://www.dtcms.com/a/596585.html

相关文章:

  • YOLOv8改进实战:自研MSAM多尺度注意力机制,通道注意力全面升级,CBAM再进化!
  • 从一场年会看乐鑫科技的创新传承
  • 【系统架构设计师-2025下半年真题】综合知识-参考答案及详解(回忆版)
  • custed谁做的网站大连电商平台有哪些
  • 公司高端网站设计公司沈阳建设厅官方网站
  • 微信小程序必要要安装SSL证书吗?小程序SSL详解
  • PostgreSQL18新功能COPY命令变得更加用户友好
  • 医疗小程序05完善就诊人信息
  • idea AI编程 腾讯云代码助手 CodeBuddy插件安装和使用
  • 湖南益阳网站建设做地坪网站
  • 02-SQLite 为了防止多人同时乱写,把整个数据库文件“当一本账本加锁”
  • 盲盒抽赏小程序一番赏 + 无限赏拓展玩法分析:技术赋能与商业破局
  • 专业网站开发价格wordpress打开自定义很慢
  • 济南建站公司电话网页界面设计与制作邓文达
  • Mysql主从架构的搭建
  • MySQL数据库:表的增删改查 [CRUD](进阶)
  • AI+云计算互融共生,2025AI云产业发展大会即将举行
  • 基于YOLO的深度学习框架用于从胸部X射线图像检测肺炎
  • spring cloud微服务常用组件
  • 工业通信的“钢铁心脏”:耐达讯自动化Profibus光纤模块,为机械手臂提供持久动力
  • 【Kafka全攻略】Kafka从入门到实战:核心概念+实操配置+故障排查全攻略
  • 基于SpringBoot的新闻管理系统【协同过滤推荐算法+可视化统计】
  • 展示型网站方案C语言做网站需要创建窗口吗
  • 电脑硬盘数据恢复原理及核心技术解析
  • 潍坊网站建设制作几分钟弄清楚php做网站
  • Hadoop在AI时代如何实现生态协同? CMP 7.13(或类 Cloudera CDP7.3 的 CMP 7.13 平台,如华为鲲鹏 ARM 版)
  • 麒麟系统离线安装Rabbitmq
  • 【大模型训练】megatron分布式并行训练的调用流程,关键函数forward_backward_func
  • 基于 C++和 Python 实现计算机视觉
  • watch监视reactive对象类型数据