LDMIA 指令在皮质 M4 的外部 SRAM 上无法正常工作
LDMIA instruction not working correctly on external SRAM in cortex M4
我在拇指模式下使用 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
之外的所有寄存器都已恢复,奇怪的是它的值 "pop" 来自 0x60000000
而不是 0x600003F0
。
知道是什么导致了这个问题。我正在使用Jlink写入flash。
P.S。当寄存器保存到片上 SRAM 而不是外部 SRAM 时,不会发生此问题;
编辑
如果指令
ldmia r0!, {r1-r12}
分为两部分,如:
ldmia r0!, {r1-r6}
ldmia r0!, {r7-r12}
则所有寄存器恢复成功
您需要阅读 STM32L4xx6xx 芯片限制。 FMC 不支持第 2.2.4 节读取九个字或更多字的突发访问。 ( DocID026121 Rev 4 ) 可从 ST.
"CPU 对 FMC 的读取突发访问等于或超过 9 个寄存器 returns 损坏的数据
从读到的第 9 个字开始。这些突发只能由 Cortex®-M4 生成 CPU
而不是其他大师(即不是 DMA)。
当堆栈重新映射到 FMC 上的外部存储器并且
POP 操作使用 9 个或更多寄存器执行。
当 LDM/VLDM 操作与 9 个或更多寄存器一起使用时,也会发生这种情况。"
我在拇指模式下使用 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
之外的所有寄存器都已恢复,奇怪的是它的值 "pop" 来自 0x60000000
而不是 0x600003F0
。
知道是什么导致了这个问题。我正在使用Jlink写入flash。
P.S。当寄存器保存到片上 SRAM 而不是外部 SRAM 时,不会发生此问题;
编辑 如果指令
ldmia r0!, {r1-r12}
分为两部分,如:
ldmia r0!, {r1-r6}
ldmia r0!, {r7-r12}
则所有寄存器恢复成功
您需要阅读 STM32L4xx6xx 芯片限制。 FMC 不支持第 2.2.4 节读取九个字或更多字的突发访问。 ( DocID026121 Rev 4 ) 可从 ST.
"CPU 对 FMC 的读取突发访问等于或超过 9 个寄存器 returns 损坏的数据 从读到的第 9 个字开始。这些突发只能由 Cortex®-M4 生成 CPU 而不是其他大师(即不是 DMA)。 当堆栈重新映射到 FMC 上的外部存储器并且 POP 操作使用 9 个或更多寄存器执行。 当 LDM/VLDM 操作与 9 个或更多寄存器一起使用时,也会发生这种情况。"