I’ve just fixed a bug very hard to find.
IAR 78K0R port uses configMEMORY_MODE to detect if ES register should be saved/restored on a context switch.
The problem occurs when a project has near data model and far code model with a code placed in several 64K pages. As data model is near, configMEMORY_MODE should be set to 0. But a function exit code generated by IAR uses far data pointers. These pointers are used to retrieve how much function arguments should be removed from a stack.
When some task goes to a background inside a function exit code and another task or interrupt handler changes ES register, stack pointer of the first task becomes invalid.
To fix this issue portSAVE_CONTEXT and portRESTORE_CONTEXT in addition to configMEMORY_MODE should check the code model. But I’d rather always save ES register even when both code and data models are near.
Thanks for taking the time to report this. I would be grateful if you could attach the updated port layer file so we can ensure we understand the fix correctly.
#if configMEMORY_MODE == 1
MOV A, CS ; Save CS register.
XCH A, X
MOV A, ES ; Save ES register.
PUSH AX
#else
MOV A, CS ; Save CS register.
PUSH AX
#endif
For those who count each instruction cycle:
#if defined(__FAR_MODEL__) || (configMEMORY_MODE == 1)
MOV A, CS ; Save CS register.
XCH A, X
MOV A, ES ; Save ES register.
PUSH AX
#else
MOV A, CS ; Save CS register.
PUSH AX
#endif
__FAR_MODEL__ is a macro defined in assembler preprocessor options (just like __NEAR_MODEL__ in original demo project FreeRTOS\Demo\NEC_78K0R_IAR).
Also the condition (configMEMORY_MODE == 1) may be replaced by defined(__FAR_DATA_MODEL__).
The code I use at this moment:
MOV A, CS ; Save CS register.
XCH A, X
MOV A, ES ; Save ES register.
PUSH AX
I don’t care about 2 extra instructions for each save/restore context. Also some of my projects, which use NEAR code and data models, use far pointers (to access flash memory for example) so conditional compilation may also cause a bug.
portRESTORE_CONTEXT macro should be changed by the same way.