RL78 portYIELD_FROM_ISR bug in version 7.1.1

mikewilley wrote on Friday, August 10, 2012:

I discovered a bug in the RL78 port of version 7.1.1 when using portYIELD_FROM_ISR().  The symptom was that when portYIELD_FROM_ISR() was called and a context switch occurred, the stack frame that was active when the interrupt occurred was corrupted.

It turns out that vTaskSwitchContext() will corrupt the stack if it is not surrounded by a SAVE_CONTEXT/RESTORE_CONTEXT pair.  The fix is to change

#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if (xHigherPriorityTaskWoken)vTaskSwitchContext()[img]null[/img]

to

#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if (xHigherPriorityTaskWoken) vPortYield()

in the file portmacro.h
to

rtel wrote on Friday, August 10, 2012:

Thanks for your feedback.  I will have to try and replicate this to see why testing has not picked it up (and then add a new test).  Any additional information would be appreciated - for example, which byte on the stack gets clobbered.

Regards.

mikewilley wrote on Friday, August 10, 2012:

I haven’t spent enough time in the details of the OS to know what bytes specifically get clobbered.  The way I detected the error is that vApplicationStackOverflowHook() gets called and all the stack pointers in one or more TCBs are hosed.

rtel wrote on Friday, August 10, 2012:

Could it possibly be a genuine stack overflow?  If the stack has overflowed then it is likely that the stack will look corrupt.

Regards.

mikewilley wrote on Friday, August 10, 2012:

No, the hosed stack pointers are pointing to a completely different chunk of memory than where they were pointing before the “overflow” is detected. When I look at the areas where the stacks actually reside all of them have plenty of untouched space.

rtel wrote on Tuesday, August 14, 2012:

I’m just looking at this now:

It turns out that vTaskSwitchContext() will corrupt the stack if it is not surrounded by a SAVE_CONTEXT/RESTORE_CONTEXT pair. 

According to the documentation page for the port, if portYIELD_FROM_ISR() is to be used, then the ISR must have an assembly file wrapper that calls SAVE_CONTEXT/RESTORE_CONTEXT.  So far, from looking at this, I agree that attempting to call portYIELD_FROM_ISR() without the wrapper will corrupt the stack which is why it is not valid to do that.

#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if (xHigherPriorityTaskWoken) vPortYield()

That will cause a BRK instruction to be executed inside your ISR.  I’m not sure if that is dangerous, but I would definitely say it is undesirable for reasons of efficiency.

Please let me know if you are seeing an issue when portYIELD_FROM_ISR() is used as intended, and, if so, provide a test case to replicate the issue so I can investigate further.

Regards.