FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [March 2015 Threads]
I've just fixed a bug very hard to find.
IAR 78K0R port uses configMEMORYMODE 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, configMEMORYMODE 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 portSAVECONTEXT and portRESTORECONTEXT 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.
Regards.
FreeRTOSSourceportableIAR78K0RISR_Support.h
portSAVE_CONTEXT macro
Original code:
~~~~~~
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
~~~~~
__FARMODEL_ is a macro defined in assembler preprocessor options (just like __NEARMODEL_ in original demo project FreeRTOSDemoNEC78K0RIAR).
Also the condition (configMEMORYMODE == 1) may be replaced by defined(_FARDATAMODEL__).
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.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.