artlip wrote on Wednesday, September 12, 2007:
Hi,
The main idea is to allocate space for task context in the TCB e.g.
typedef struct tskTaskControlBlock
{
#if ( configUSE_STATIC_CONTEXT_FRAME == 1 )
portSTACK_TYPE pxCpuContextFrame[ portCPU_CONTEXT_SIZE ];
#else
volatile portSTACK_TYPE *pxTopOfStack;
#endif
…
Basing on my previous experience with another RTOS and ARM platform I found that such solution has real advantages. It simplify and speeds up context save and restore (at least for the ARM7 platform).
The end results seems quite nice. For my benchmarks I got speedup up to 5% (five tasks with the same priority doing only taskYIELD).
I’ve also observed speedup of interrupt processing. The time between interrupt generation to the first line of C code in the ISR is shorter over 8% (even 9.5% with compiler optimized code) and time from last line of C code in the ISR to the first instrucion in task is shorter nearly 4%.
Tests was performed on LPC2114 using FreeRTOS 4.4 and GCC 4.2 compiler.
Example code for context save for ARM7:
/* push R0 as we are going to use the register */
STMDB SP!, {R0}
LDR R0, =pxCurrentTCB
LDR R0, [R0]
/* seek to R1 location */
ADD R0, R0, #16
STMIA R0, {R1-R14}^
LDR R1, =ulCriticalNesting
LDR R1, [R1]
MRS R2, SPSR
MOV R3, LR
/* pop R0 */
LDMIA SP!, {R4}
/* seek to SPSR location (begin of the context frame) */
SUB R0, R0, #16
/* R1 = ulCriticalNesting, R2 = SPSR, R3 = LR, R4 = R0 */
STMIA R0, {R1-R4}
Example code for context restore for ARM7:
LDR R0, =pxCurrentTCB
LDR R0, [R0]
/* R1 = ulCriticalNesting, R2 = SPSR */
LDMIA R0!, {R1-R2, LR}
LDR R3, =ulCriticalNesting
STR R1, [R3]
MSR SPSR_fsxc, R2
LDMIA R0, {R0-R14}^
NOP
SUBS PC, LR, #4
I welcome any questions and critique.
BTW> Full patchset is available at request.
Regards,
–
Artur Lipowski