mardi 21 juin 2016

Cortex M0+ returns to wrong position in thread mode after interrupting sleep

I'm not sure if I'm missing something obvious here but has anyone else experienced any issues with the Cortex M0+ (or any of the Cortex M range) returning from an ISR to a somewhat random position in thread mode after being woken up from sleep mode (eg not returning to the line below the WFI instruction). It seems to wake up in the middle of the code, like in the middle of a for loop or the middle of a function. I'm using the ATSAMD218A microcontroller and have been using the debugger in Atmel Studio 7. I've attempted to isolate the problem and have noticed the following:

  • It only occurs when the device is put to sleep, when the device is interrupted while it is awake the ISR always returns to the right place.
  • The ISR always returns to the same (incorrect) position in the code, if I comment out that function or piece of code then it begins returning to another incorrect position
  • I've unsuccessfully inserted delays and NOPs to try determine if it is timing related or clock cycle related but it still always returns to the same (incorrect) position
  • I have tried implementing interrupts using both direct register access as well as using the Arduino Interrupts library.
  • It occurs in both idle and standby mode (sleep and deep sleep)
  • While looking at the assembly instructions during debugging, right before the ISR is exited, the 'bx lr' instruction is called which is supposed to branch to the link register. The link register contains a value called EXC_RETURN which indicates the return behavior, which in my case is 0xFFFFFFF9 (return to thread mode). I can't however find the actual memory address that it returns to anywhere. The memory address isn't in any of the core registers R0-R15.

I have been reading the ARMv6 Architecture Reference Manual as well as the Cortex M0+ Generic User Guide. Not quite sure what's going on and any debugging suggestions would be much appreciated. Does anyone have a better understanding of the exception handling of the Cortex M series and could point me in the right direction to find the memory address that thread mode returns to after an ISR. I could supply code if you'd like but even a simple piece of code that does nothing but count in a loop, sleep and then wake up causes trouble.

Aucun commentaire:

Enregistrer un commentaire