Unable to read link register using __ASM("lr");

Additional details:

  • IDE: Keil uVision 5.17.00
    • C Compiler: V5.06 update 1 (build 61)
    • Assembler: V5.06 update 1 (build 61)
  • Custom board (This shouldn't make a difference)
  • SoftDevice: s140_nrf52_6.1.0
  • SDK: 15.2

Hello.

I am attempting to read the link register LR the same way that the PSP and MSP are read in all Nordic example projects. See __get_PSP() and __get_MSP() for reference. I have implemented the following to mimic __get_MSP():

__STATIC_INLINE uint32_t __get_LR(void)
{
  register uint32_t __regLR  __ASM("lr");
  return(__regLR);
}

void MemoryManagement_Handler(void)
{
   static volatile uint32_t lr;
   lr = __get_LR();
   
   if(lr & 0x4)
   {
      // Do something useful
   }
   else
   {
      // Do something useful
   }
}

// Trigger a MemManage fault from main;

main(void)
{
   typedef void (*fn_t)();
   fn_t func = (fn_t)((char*) 0xFFFFFFFF);
   func();
}

However, the link register value returned does not match what is shown in the Keil uVision registers window as seen below.

Note that I have no trouble reading the PSP or MSP. But for some reason I cannot read the link register,. Replacing __ASM("lr") with __ASM("r14") resulted in the same behavior. Oddly enough, when I hover my mouse over __ASM("lr"), it shows the correct value as seen in the register window. Lastly, looking at the HardFault_Handler() implementation in the Nordic examples as found in hardfault_handler_keil.c, it looks like the link register LR is checked using "tst lr, #4".

Any idea as to why I cannot read the link register using ASM("lr")? The same code works on a STM MCU in Keil uVision, but Nordic does not work.

Thanks!

Derek

Parents Reply Children
No Data
Related