LDMIA 指令在 cortex M4 中的外部 SRAM 上无法正常工作

Posted

技术标签:

【中文标题】LDMIA 指令在 cortex M4 中的外部 SRAM 上无法正常工作【英文标题】:LDMIA instruction not working correctly on external SRAM in cortex M4 【发布时间】:2017-05-07 00:21:19 【问题描述】:

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

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

升压后所有这些寄存器都保存在内存中,r0的值为0x600003d0

内存内容:

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 写入 flash。

附:当寄存器保存到片上 SRAM 而不是外部 SRAM 时,不会出现此问题;

编辑 如果指令

ldmia r0!, r1-r12

分为两部分,如:

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

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

【问题讨论】:

" 正在运行一个没有任何 RTOS 的简单裸机应用程序。我使用 FSM 将外部 SRAM 连接到电路板"...什么是 FSM 第 9 位以后的寄存器总是正确的吗?事实上,它显然在 32 字节边界上出错,这听起来有点像地址线未正确连接或内存控制器配置不正确(特别是关于 AHB 突发拆分和/或时序) . @Notlikethat 是的,他们总是正确的,只有第 9 个是错误的。 如果他们不是,那么它可能会提示一些地址包装问题 - 事实上,这听起来像是“在引脚上拍打逻辑分析仪并检查时间”类型的问题,再加上对 FSMC 配置与 SRAM 数据表的仔细交叉检查(当然,假设您的电路板布局是合理的)。可能更多的是electronics,而不是编程。 您可以尝试将已知值放入 R8 到 R12 并存储它们然后加载它们。从您的代码中无法确定问题仅出在 R9 上,因为寄存器可能已经为 0。 【参考方案1】:

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

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

【讨论】:

它还提供了解决方法。我这里只放了一个sn-p。 谢谢 这真的很有帮助

以上是关于LDMIA 指令在 cortex M4 中的外部 SRAM 上无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

stm32mp1 Cortex M4开发篇7:窗口看门狗

学习笔记~

学习笔记~

FPU 浮点运算单元和DSP指令

Arm Cortex-M4 LDRD 指令导致硬故障

stm32mp1 Cortex M4开发篇1:stm32CubeIDE开发环境搭建