Showing results for 
Search instead for 
Did you mean: 
Honored Contributor I

Registers in non-interrupt context switch.

I am hardly trying to understand what should be a basic concept of the uC/OS port when a non-interrupt context switch occurs. 


Now all is fine with interrupt context switches: 

-ra, r0-r16 are all saved onto current task stack (exception.entry in alt_exception_entry.S) 

-OSIntCtxSw (os_cpu_a.s) saves remaining ra (again?), fp, r16-r23. Called in alt_irq_handler. 

-OSIntCtxSw then restores same regs onto new ready-to-run task stack. 

-exception.exit pops back ra, r0-r16 also on new stack. 


Everyone is happy. 

Now I would have expected macro OS_TASK_SW() to be defined as a TRAP instruction so that non-interrupt context switch also occurs in the same fashion. Instead, it is only mapped to OSCtxSw() (same as OSIntCtxSw), which only saves ra, fp, r16-r23. 


Now I am trying to make sense of this but I can't. Jean Labrosse's book does not provide insight to this. It says the OS_TASK_SW() can be defined as TRAP or fct call but in the book, OSCtxSw saves/restores all regs which is not the case in the Altera port. 


Then it must boil down to what is pushed/popped by the compiler. Can anyone understand this and provide insight? 




0 Kudos
1 Reply
Honored Contributor I

Please discard the original post. 


I took a good stack of paper with a fresh mind in the morning to realized all of this make sense. 


For those interested, I guess one of the key point is the "ra" register saved in the OSIntCtxSw/OSCtxSw assembly function that performs a big part of the magic by returning to the point where the original task was suspended, which is either in: 


1. after OS_TASK_SW() in OS_Sched() (os_core.c) if the task was voluntarily yielded by the OS. 


2. after OSIntCtxSw in OSIntExit (os_core.c) if the task was suspended from interrupt. 


Yep, so what appears to be a redundant save/restore of "ra" while in interrupt context is in fact a neat way to jump back to the appropriate code. 


This effectively allows using a direct call in non-interrupt context switch instead of a TRAP, which avoid saving/restoring all the registers manages in the exception entry/exit. 


Hope this can help some others to understand.