error 65: access violation at 0x40021000 : no 'read' permission

本文详细介绍了使用Keil MDK V5.10在Windows 7环境下,遇到的STM32固件库与仿真调试不匹配导致的错误。主要问题在于工程配置选项中的debug对话框配置不正确,导致无法正常进行仿真调试。通过对比ST官方提供的模板,发现正确的dialogdll和parameter配置为DARMSTM.dll和STM32F103C8。解释了MCU型号命名规则及为何使用特定配置的原因,并提供了解决步骤。
AI助手已提取文章相关产品:

开发环境:keil MDK V5.10

操作系统:windows 7(32位)


问题描述:使用MDK进行软件设计时没有使用ST官方的模板而是手动建立的工程,使用ST官方提供的3.5版本固件库。编译完全通过,在使用软件仿真时出现问题,表现为程序无法跳转到main入口,直接在SystemInit()函数就无法执行,调试窗口出现如标题所示的错误信息:

error 65: access violation at 0x40021000 : no 'read' permission

如下图所示,途中红圈分别表示了代码执行到的位置及相应的错误信息


网络上查找解决方案同时对比ST提供的3.5版本固件库中的工程模板,发现是工程配置选项中的debug选项卡的dialog dll和对应的parameter配置出了问题。选中MCU后默认的配置如下图:


可以看到dialog dll默认配置为DCM.DLL,而parameter默认配置为-pCM3,该种配置无法进行正常的仿真调试。

正确配置应该为dialog dll:DARMSTM.dll parameter:-pSTM32F103C8

这两个参数是根据你使用的MCU不同而不同的,例如本工程使用的MCU为STM系列,那么在dialog DLL选项中就应该使用DARMSTM.dll,名字中的STM就是指厂商,参数则是具体的MCU芯片型号,本项目使用STM32F103C8T6,因此选择为STM32F103C8,如下图所示:


为何使用的是STM32F103C8T6,参数却只能是STM32F103C8,这个原因是因为根据ST公司的MCU命名规则,到C8这个位置就已经完全规定了仿真所需要的所有参数,包括cpu频率,ram容量,flash容量,外设资源等内容。型号中后边的部分都已经和仿真无关了,例如后边的名字主要代表了MCU的封装,工作温度等。官方命名规则如下图:


当然还有一个更加直接的原因是DARMSTM.DLL这个动态链接库文件中没有详细的MCU型号,我们可以通过使用工具打开动态链接库文件查看证明,如下图所示,图中可以清楚的看到一个MCU的型号只有11个字符,不包括后边的其他参数字符。

总结:该问题的产生,归根到底还是keil IDE的问题,正常的情况,应该是通过工程向导建立工程的时候,配置参数就自动使用该MCU应该使用的dialogdll及相关参数。不得不感叹,KEIL有的时候也很傻啊!!

您可能感兴趣的与本文相关内容

访问冲突错误(Access Violation)是程序运行时试图访问一个不允许访问的内存地址时触发的异常。在具体场景中,`error 65: access violation at 0x40007000 no read permission` 表示程序尝试从地址 `0x40007000` 读取数据,但该内存区域没有授予读取权限。 ### 错误原因分析 1. **无效指针访问** 程序可能使用了一个未正确初始化或已释放的指针,导致访问了非法内存地址。这种情况常见于动态内存管理不当、指针悬空(dangling pointer)等问题。 2. **内存映射配置错误** 在嵌入式系统或底层编程中,如果内存映射配置不正确,可能导致某些地址范围不可访问。例如,MMU(Memory Management Unit)未正确设置页表项,或者外设寄存器映射错误。 3. **权限设置问题** 某些操作系统或运行时环境会对内存区域设置访问权限(如只写、不可执行等)。如果程序试图以错误的权限访问某块内存,就会触发此类错误。例如,在 Windows 中,可以通过 `VirtualProtect` 设置内存保护属性[^1]。 4. **驱动或硬件接口问题** 如果访问的是与硬件交互的内存地址(如通过 RDMA 或 InfiniBand 接口),可能是由于设备驱动未正确初始化或内存区域未注册导致的访问失败。例如,InfiniBand 设备需要通过 `ib_verbs.h` 提供的接口注册内存区域(MR)后才能进行 RDMA 操作[^2]。 --- ### 解决方法 1. **检查指针有效性** 确保所有使用的指针都已正确初始化,并且在访问前未被释放。可以使用调试工具(如 GDB、Valgrind)检测内存访问问题。 2. **验证内存映射和权限** 如果涉及低层内存访问,确保 MMU 配置正确,并为相应地址空间设置合适的访问权限。例如,在 Linux 中可通过 `/proc/<pid>/maps` 查看进程的内存映射情况。 3. **使用内存保护机制** 在 Windows 上,可使用 `VirtualAlloc` 和 `VirtualProtect` 显式分配和保护内存区域;在 Linux 上,可使用 `mmap` 和 `mprotect` 控制内存访问权限。 4. **检查 RDMA/InfiniBand 内存注册** 若涉及 RDMA 操作,需确保目标内存区域已通过 `ib_reg_mr` 等函数注册,并设置了正确的访问标志(如 `IB_ACCESS_LOCAL_WRITE`、`IB_ACCESS_REMOTE_READ`)[^2]。 --- ### 示例代码:Linux 下内存访问权限控制 ```c #include <sys/mman.h> #include <stdio.h> #include <string.h> int main() { size_t page_size = 4096; char *buffer = mmap(NULL, page_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (buffer == MAP_FAILED) { perror("mmap"); return 1; } // 设置可读写权限 if (mprotect(buffer, page_size, PROT_READ | PROT_WRITE) == -1) { perror("mprotect"); return 1; } strcpy(buffer, "Hello, protected memory!"); printf("%s\n", buffer); munmap(buffer, page_size); return 0; } ``` ---
评论 12
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值