We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have a Cortex M3-based MCU (and I also tried this on another MCU - stm32f103, which has the same memory alignment).
I tried Keil 4 and Keil 5 with armcc compiler. I tried 3 different boards and 2 different debuggers (uLink2 and st-link). Problem exists only if I compile with -O1.
The problem looks like this. I have a function, I try to step it line by line and I get a hard fault.
The function looks like this:
bool CanHandle::sendMsg(CanMsg & msg) { bool result = false; CAN_TxMsgTypeDef txMsg; if (format == FrameFormat::EXTENDED) <...>
If I try to step over line 'bool result = false;', I get a hard fault.
But here's the interesting part. If I step over assembly - I get no fault. If I set a breakpoint on the next line and press Run - even though it shouldn't be different from stepping over - I get no fault.
Compiler produces this assembly for that bit:
351: bool result = false; 352: 353: CAN_TxMsgTypeDef txMsg; 0x08000C4E 2700 MOVS r7,#0x00 0x08000C50 7A20 LDRB r0,[r4,#0x08] 0x08000C52 2600 MOVS r6,#0x00 0x08000C54 F04F0801 MOV r8,#0x01 354: if (format == FrameFormat::EXTENDED) 355: { 356: txMsg.ID = msg.id; 357: txMsg.IDE = CAN_ID_EXT; 358: } 359: else 360: { 0x08000C58 2801 CMP r0,#0x01 0x08000C5A D02E BEQ 0x08000CBA
Any minor change to this function - making result equal true, making result volatile, moving result definition lower - produces different assembly and doesn't cause hard fault.
When I don't use debugger I get no fault.
When the fault happens, I see UNDEFINSTR flag set on one MCU and IBUSERR on stm32. PC recovered from stack shows some address 0x0804FE4C - that's in empty memory region.
I removed almost everything from my program - no PLL, no peripheral initialization.
So my question is - how can that happen? Is it a real problem or just an artifact of debugger usage?