gcc - LDMIA 指令在皮质 M4 的外部 SRAM 上无法正常工作

标签 gcc memory arm ram cortex-m

我在拇指模式下使用 STM32L486ZG 开发板。我正在运行一个没有任何 RTOS 的简单裸机应用程序。我使用 FSM 将外部 SRAM 连接到电路板。外部 SRAM 位于地址 0x60000000。系统已初始化并以 72MHz 的频率运行(我已经在 18-80 MHz 的频率上尝试过这个问题)现在在我的主要功能中我有以下代码:

int main(){
    asm volatile (
            "push {r0}\n"
            "mov r0, #0x60000000\n"
            "add r0, #0x400\n"
            "stmdb r0!, {r1-r12}\n"
            "ldmia r0!, {r1-r12}\n"
            "pop {r0}\n"
            );
}

根据此代码,在执行此主函数后不应更改任何寄存器,但在执行以下指令后情况并非如此

ldmia r0!, {r1-r12}

r9执行后不正确。 stmdb指令工作正常,但 ldmia没有正确加载数据。我已经通过查看内存中的内容验证了这一点。

此问题对于 ldmia 中的任何参数都存在说明:始终影响第9个寄存器。

解释: 假设我正在调试这段代码,下一条要执行的指令是:

stmdb r0!, {r1-r12}

在加紧之后所有这些寄存器都被保存在内存中并且值r00x600003d0

内存内容:

0x600003D0  00000000 40021008 0000000C  .......@....
0x600003DC  40000000 00000000 00000000  ...@........
0x600003E8  20017FEC 00000000 00000000  ì.. ........
0x600003F4  00000000 00000000 00000000  ............

寄存器内容:

r0  0x600003d0
r1  0x00000000
r2  0x40021008
r3  0x0000000c
r4  0x40000000
r5  0x00000000
r6  0x00000000
r7  0x20017fec
r8  0x00000000
r9  0x00000000
r10 0x00000000
r11 0x00000000  
r12 0x00000000

这说明所有的寄存器都成功保存到内存中了。现在我执行下一条指令

ldmia r0!, {r1-r12}

之后 这些是寄存器的内容:

r0  0x60000400
r1  0x00000000
r2  0x40021008
r3  0x0000000c
r4  0x40000000
r5  0x00000000
r6  0x00000000
r7  0x20017fec
r8  0x00000000
r9  0x555555d5
r10 0x00000000
r11 0x00000000
r12 0x00000000

如您所见,除r9 外,所有寄存器都已恢复奇怪的是它的值从 0x60000000 中“弹出”而不是 0x600003F0 .

知道是什么导致了这个问题。我正在使用 Jlink 写入闪存。

附言当寄存器保存到片上 SRAM 而不是外部 SRAM 时,不会发生此问题;

编辑 如果指令

ldmia r0!, {r1-r12}

分为两部分:

ldmia r0!, {r1-r6}
ldmia r0!, {r7-r12}

那么所有的寄存器都恢复成功

最佳答案

您需要阅读 STM32L4xx6xx 芯片限制。 FMC 不支持第 2.2.4 节读取九个字或更多字的突发访问。 ( DocID026121 Rev 4 ) 可从 ST 获得。

“对 FMC 的 CPU 读取突发访问等于或超过 9 个寄存器返回损坏的数据 从读到的第 9 个字开始。这些突发只能由 Cortex®-M4 CPU 生成 而不是其他大师(即不是 DMA)。 当堆栈重新映射到 FMC 上的外部存储器并且 POP 操作使用 9 个或更多寄存器执行。 当 LDM/VLDM 操作与 9 个或更多寄存器一起使用时,也会发生这种情况。”

关于gcc - LDMIA 指令在皮质 M4 的外部 SRAM 上无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41265112/

相关文章:

c - 什么在 ARM 上更快? MUL 或 (SHIFT + SUB)?

linux - 针对 ARM9 与 ssl 交叉编译 cURL 时出现问题

c++ - 快速读取文件

C++:为什么访问类数据成员比访问全局变量慢?

ios - 如何减小 iOS 中滤镜图像的大小

java - 您更喜欢哪种堆大小?

windows-8 - 如何模拟 Windows RT

c++ - int64_t 的整数类型歧义

c - sqlite3库 undefined reference 错误

c++ - OpenGL 内存泄漏