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

时间:2016-12-21 14:28:02

标签: 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}

升级后,所有这些寄存器都保存在内存中,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奇怪地具有其值{&#34;弹出&#34;来自0x60000000而不是0x600003F0。< /强>

知道可能导致此问题的原因。我正在使用Jlink写入flash。

P.S。当寄存器保存到片上SRAM而不是外部SRAM时,不会发生此问题;

修改 如果说明

ldmia r0!, {r1-r12}

分为两部分,如:

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

然后所有寄存器都成功恢复

1 个答案:

答案 0 :(得分:6)

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

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