I am investigating what looks to be a memory corruption issue. I am stepping through the assembler and I cannot explain what I see. It's as if the microcontroller is not correctly interpreting the assembler code that was generated by the compiler.
Brief context (more detail later): - IDE-Version: µVision V5.18.0.0 - Toolchain: MDK-ARM Standard Version: 5.18 - C Compiler: Armcc.exe V5.06 update 1 (build 61) - Assembler: Armasm.exe V5.06 update 1 (build 61) - Target hardware: STM3240G-EVAL with STM32F457IGH6
Issue details: I have trapped execution at a breakpoint in my code at which things seem to be fine ("*"=breakpoint, "-"=execution point).
0x080073EC 4629 MOV r1,r5 * - 0x080073EE F104000C ADD r0,r4,#0x0C 0x080073F2 F7FEFD71 BL.W FilterList::Add (0x08005ED8)
Registers and "Call Stack and Locals" are as I might expect.
I then hit F11 to step one instruction of the assembler and instead of the program counter moving to 0x080073F2, the Program Counter goes to 0x080073F0 and the disassembled code displayed is changed.
0x080073EC 4629 MOV r1,r5 * 0x080073EE F104000C ADD r0,r4,#0x0C - 0x080073F0 000C MOVS r4,r1 0x080073F2 F7FEFD71 BL.W FilterList::Add (0x08005ED8)
It's as though the MCU has executed a 2 byte instruction instead of the 4 byte instruction that was displayed.
The subsequent "unexpected" 2 byte instruction (MOVS r4,r1) then tramples all over a pointer which later gives rise to a Hard Fault error.
For all the world, it looks like the microcontroller is not doing what the compiler had intended it to do.
Other stuff that might or might not be relevant: - The code uses ITM to display debug messages in the Serial "Debug (printf) viewer" - Much of the code is written in C++ but also links to the ST "Cube" HAL. - Microlib is enabled - The microcontroller on the STM3240G-EVAL board is clearly marked "STM32F457IGH6". I can find no mention of this as a valid ST part. I have set the Device in uVision as STM32F407IGHx since that is what I had expected the STM3240G-EVAL board to contain.
Can anyone shed any light on what is going on?
Thanks, Richard
What if you breakpoint the call, and don't single step this specific piece of code?
The F457 is the part sampled on the board in 2011Q4, the production parts may well have different numbers.
You might want to review the core stepping, I'd perhaps look at the CPUID at 0xE000ED00, and review that in the light of any ARM Errata. And look at the DBGMCU->IDCODE
You could also double check the flash and prefetch settings.
Clive,
Many thanks for responding.
>What if you breakpoint the call, and don't single step this specific piece of code? I tried inserting a breakpoint in the assembler at the call, but the code does not stop. That is curious in itself. But execution looks to have continued in exactly the way that it did when I stepped across it, i.e. the Hard Fault error is hit and the pointer appears to have been corrupted.
>look at the CPUID at 0xE000ED00 I took a look at this and I am seeing 0x410FC241. According to the PM0214 Programming manual, this corresponds to Cortex-M4, revision 0, patch 1.
So I took a look at DBGMCU_IDCODE at 0xE0042000, which believe contains the "MCU device ID code". I see 0x20006411. I checked section 38.6 of RM0090 Reference Manual for the STM32F4 and, whilst the values for revision and device identifier seeem reasonable i.e. dev=0x411, rev=0x2000, they are not described in that document.
It would seem that the startup code that I am using should be suitable for all STM32F4 variants (with allowance for crystal frequency). In the code, I see that Devices that report "rev=0x1001" (STM32F405x/407x/415x/417x Revision Z) will have Flash Prefetch Buffer enabled, but this would not be the case here.
It's odd. The problem seems to be repeatable with the code build that I currently have. However, if I make a small change to the code in an completely unrelated area, the problem does not seem to occur. That is an obstacle to stripping down the code to a bare failing minimum. I've found a case that seems to fail repeatedly and I have used it to obtain as much information as possible. I don't seem to have the luxury of changing the code in order to aid my investigation.
Your suggestions were excellent. Do you have any more? Thanks, Richard
More info:
>dev=0x411, rev=0x2000 According to RM0033 section 32.6.1, this is the code for the STM32F2xx rev B. According to STM32F40x and STM32F41x Errata sheet section 2.1.2 the "MCU device ID is incorrect" on STM32F40x and STM32F41x rev A parts. The STM32F457 package on the board appears to be marked as Rev A.
Combined with the previously obtained info about the Cortex-M4 core, I suspect the STM32F457 on this STM3240G-EVAL board is a STM32F4xxx rev A.
The one here is a Rev A, and an Engineering Sample (ES) cache.amobbs.com/.../ourdev_714153X481IF.JPG
Might want to disable the ART, the original STM32F2 had a critical path on the prefetch where certain code sequences from GCC would break the execution.
This is something you might have better results discussing with ST FAE's, or testing on a board with 2016/2017 silicon.
Yep those are exactly the markings that I see on this STM3240G-EVAL board. I think we have concluded that its a STM32F407 Rev A, with the known pre-fetch issue.
Yesterday, it was my view that the code was not enabling the prefetch buffer, since SystemClock_Config contains
/* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */ if (HAL_GetREVID() == 0x1001) { /* Enable the Flash prefetch */ __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); }
and we know that this STM32F457 reports RevId = 0x2000.
But further investigation reveals that HAL_Init contains
#if (PREFETCH_ENABLE != 0U) __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); #endif /* PREFETCH_ENABLE */
After setting PREFETCH_ENABLE to 0 and recompiling, I am not observing the "unexpected behaviour" at that execution point. Whilst I have previously seen changes in behaviour due to apparently unrelated code changes, I have a good feeling that the problem was due to the known issues with the pre-fetch buffer on STM32F4 Rev A parts. I'll want to find a cleaner solution that deals with this properly at runtime. But at least I can move forward.
Clive, you were right that it was a MCU issue (i.e. ST) rather than a compiler issue (i.e. Keil) and that my original post should have been to the ST forums. That said, I remain immensely grateful for your help in overcoming this problem.
Many thanks, Richard