AnsweredAssumed Answered

LPC11U68 HardFault on pc-relative ldr

Question asked by David Fenger on Mar 14, 2018
Latest reply on Mar 16, 2018 by David Fenger

I'm using MCUXpresso IDE to develop for the LPC11U68, currently using a OM13058 LPCXpresso Board, Rev C2 as the development target.


I keep running into HardFaults when the compiler generates a "ldr r3, [pc, #20]" instruction at an address that's not a power of 4.  It seems to assume that the CPU will round down to the nearest power of 4, but that's not what I'm seeing in the debugger.


A representative dissasembly from USB_IRQHandler (taken directly from the usbd_rom_hid_generic project in LPCOpen for the LPC116x):


71 if ( LPC_USB->DEVCMDSTAT & USB_SETUP_RCVD ) { /* if setup packet is received */
00000452: ldr r3, [r3, #0]
00000454: lsls r3, r3, #23
00000456: bpl.n 0x460 <USB_IRQHandler+20>
72 addr[2] &= ~BUF_ACTIVE; /* clear EP0_IN ACTIVE bit*/
00000458: ldr r3, [r2, #8]
0000045a: lsls r3, r3, #1
0000045c: lsrs r3, r3, #1
0000045e: str r3, [r2, #8]

74 USBD_API->hw->ISR(g_hUsb);
00000460: ldr r3, [pc, #16] ; (0x474 <USB_IRQHandler+40>)
00000462: ldr r2, [pc, #20] ; (0x478 <USB_IRQHandler+44>)
00000464: ldr r3, [r3, #0]
00000466: ldr r0, [r2, #0]
00000468: ldr r3, [r3, #0]


0x474 contains 0x10000320.  0x478 contains 0x1000130.  So it all looks okay...


But the instruction at 462 loads garbage into r2 (0x68db681b), which causes the instruction in 0x466 to HardFault.


Hunting around for the 'random' data, I see it's living at 0x468.


I've tried compiling the code with -mno-unaligned-access, but it doesn't seem to help.


Obviously, I'm doing something terribly wrong, because if this issue was common nobody would be able to run anything on the LPC11U68 at all.  Worse, some of the time, I can get some builds to run, but I have no idea why.


Other cases I've seen make seems to be related to a branch instruction or other jump happening shortly before the ldr.  I've included some context to show where that would be the case, here.