这是和一位网友探讨交流的问题,初步做的分析。
【问题由来】
程序在MDK AC6的O0优化等级下运行是正常的,而在O2优化下,运行就不正常了,锁定到是下面这个代码造成。
注:O0和O2调用的汇编指令不同。
[C] 纯文本查看 复制代码 __asm("ldr r5,=0x20010402");
__asm("ldr r7,=0x55f4");
__asm("strbt r7,[r5,#6]");
硬件异常错误类型:
【原因分析】
问题分析采用了优先各种情况测试,然后缩写范围的方式。
问题起初的检查方向差点搞错,起初我并不认为是MPU的配置问题,因为操作出问题的这个空间是DTCM,这个空间和CPU的主频一样,基本不需要配置MPU的,实际应用中,也从来没有配置过,但问题恰恰就出在这里了。
1、测试H7芯片所有4GB空间开启MPU可以正常运行了。
2、进一步缩小范围,测试DTCM的0x2000 0000地址开始128KB空间配置MPU S,B,C各种设置也没有触发这个问题了。
3、再进一步测试发现,只要关闭DTCM的MPU配置,就会触发硬件异常:
[C] 纯文本查看 复制代码 MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.BaseAddress = 0x20000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_128KB; // MPU_REGION_SIZE_512MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER5;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
这个测试,想起来早期一个帖子:
非特权级模式下,并且开启了MPU了,只有MPU使能的区域才可以访问
https://www.armbbs.cn/forum.php?mod=viewthread&tid=112372

【问题解决】
这个发现太重要了,然后进一步搜索指令STRBT的介绍,初步认为是这个问题造成的。
https://developer.arm.com/documentation/dui0646/c/The-Cortex-M7-Instruction-Set/Memory-access-instructions/LDR-and-STR--unprivileged?lang=en
再进一步查找指令介绍,使用这个指令在特权模式下,这个指令只有非特权权限,按照这个要求的话,配置了MPU即可解决。
|