I am using STM32L486ZG board in thumb mode. I am running a simple bare-metal application without any RTOS. I have external SRAM connected to the board using FSM. The external SRAM is located at address 0x60000000. The system is initialized and running at 72MHz (i have tried this issue with frequency from 18-80 MHz) now in my main function i have following code:
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"
);
}
According to this code no register should be changed after this main function has executed, but that's not the case after the following instruction
ldmia r0!, {r1-r12}
i.e. r9
is not correct after execution. stmdb
instruction is working correctly but ldmia
is not loading the data correctly. I have verified this by viewing the contents from memory.
This issue is persistent with any arguments in the ldmia
instruction: the 9th register is always affected.
Explanation: Lets say I am debugging this code and the next instruction to execute is this:
stmdb r0!, {r1-r12}
after stepping up all these registers have been saved in the memory and value of r0
is 0x600003d0
the contents of memory:
0x600003D0 00000000 40021008 0000000C .......@....
0x600003DC 40000000 00000000 00000000 ...@........
0x600003E8 20017FEC 00000000 00000000 ì.. ........
0x600003F4 00000000 00000000 00000000 ............
content of the registers:
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
this shows that all the registers are successfully saved in the memory. Now i step the next instruction
ldmia r0!, {r1-r12}
after this these are the contents of registers:
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
as you can see all the registers are restored except r9
which oddly has its value "pop"ed from 0x60000000
instead of 0x600003F0
.
Any idea what could be causing this issue. I am using Jlink to write into flash.
P.S. This issue doesn't occur when the registers are saved to onchip SRAM as opposed to external SRAM;
edit if the instruction
ldmia r0!, {r1-r12}
is split into two parts like:
ldmia r0!, {r1-r6}
ldmia r0!, {r7-r12}
then all the registers are restored successfully
You need to read the STM32L4xx6xx Silicon Limitations. Section 2.2.4 Read burst access of nine words or more is not supported by FMC. ( DocID026121 Rev 4 ) available from ST.
"CPU read burst access equal to or more than 9 registers to FMC returns corrupted data starting from the 9th read word. These bursts can only be generated by Cortex®-M4 CPU and not by the other masters (i.e not by DMA). This issue occurs when the stack is remapped on the external memory on the FMC and POP operations are performed with 9 or more registers. This also occurs when LDM/VLDM operations are used with 9 or more registers."
User contributions licensed under CC BY-SA 3.0