I am trying to implement a scheduler for Arduino Mega 2560. I think I lack understanding of how to set the PC register to another instruction. Here is my simple approach so far:

void dummy(){
    digitalWrite(LED_BUILTIN, HIGH);

in a naked ISR method:

SP = (uint16_t)(&dummy)
__asm volatile(
"reti     \n\t"

However it is not working. How should the PC register be set to a certain function or to where it was in a previous process for a scheduler approach?



SP = (uint16_t)(&dummy)

is changing the stack pointer. Not what you want. You want to instead push the destination address to the stack. However, rather than simulating a function return, it should be simpler to perform an indirect jump:

asm volatile("ijmp" :: "z"(dummy));

Don't forget that your naked ISR has to save all the call-used registers, as well as SREG, r0 and r1, in its custom prologue. And restore them in its epilogue. Check the AVR calling conventions.

| improve this answer | |
  • Thanks for you fast answer, I am saving all registsers r0, ..,r31 and SREG to the stack, however I am not sure how I can save the PC into the stack and reload it. – Mustafa Otbah Sep 1 '19 at 2:34
  • @MustafaOtbah: The PC was already saved by the interrupt. You normally restore it with reti. Maybe you should expand your question and explain in more detail how you intend to manage saving and restoring task context, what you have done so far, and what is not working. – Edgar Bonet Sep 1 '19 at 9:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.