define portRESTORE_CONTEXT()
{ extern volatile void * volatile pxCurrentTCB; extern volatile unsigned portLONG ulCriticalNesting;
asm volatile (
/* Set the LR to the task stack. */
"LDR R0, 1f /* =pxCurrentTCB */ nt"
"LDR R0, [R0] nt"
"LDR LR, [R0] nt"
/* The critical nesting depth is the first item on the stack. */
/* Load it into the ulCriticalNesting variable. */
"LDR R0, 2f /* =ulCriticalNesting */ nt"
"LDMFD LR!, {R1} nt"
"STR R1, [R0] nt"
/* Get the SPSR from the stack. */
"LDMFD LR!, {R0} nt"
"MSR SPSR, R0 nt"
/* Restore all system mode registers for the task. */
"LDMFD LR, {R0-R14}^ nt"
"NOP nt"
/* Restore the return address. */
"LDR LR, [LR, #+60] nt"
/* And return - correcting the offset in the LR to obtain the */
/* correct address. */
"SUBS PC, LR, #4 nt"
/* Place the pool behind the code. This is never reached. */
"1: .word pxCurrentTCB nt"
"2: .word ulCriticalNesting nt"
);
( void ) ulCriticalNesting;
( void ) pxCurrentTCB;
}
/———————————————————–/
define portSAVE_CONTEXT()
{ extern volatile void * volatile pxCurrentTCB; extern volatile unsigned portLONG ulCriticalNesting;
asm volatile (
"b 3f /* skip data */ nt"
"1: .word pxCurrentTCB nt"
"2: .word ulCriticalNesting nt"
"3: nt"
/* Push R0 as we are going to use the register. */
"STMDB SP!, {R0} nt"
/* Set R0 to point to the task stack pointer. */
"STMDB SP,{SP}^ nt"
"NOP nt"
"SUB SP, SP, #4 nt"
"LDMIA SP!,{R0} nt"
/* Push the return address onto the stack. */
"STMDB R0!, {LR} nt"
/* Now we have saved LR we can use it instead of R0. */
"MOV LR, R0 nt"
/* Pop R0 so we can save it onto the system mode stack. */
"LDMIA SP!, {R0} nt"
/* Push all the system mode registers onto the task stack. */
"STMDB LR,{R0-LR}^ nt"
"NOP nt"
"SUB LR, LR, #60 nt"
/* Push the SPSR onto the task stack. */
"MRS R0, SPSR nt"
"STMDB LR!, {R0} nt"
"LDR R0, 2b /* =ulCriticalNesting */ nt"
"LDR R0, [R0] nt"
"STMDB LR!, {R0} nt"
/* Store the new top of stack for the task. */
"LDR R0, 1b /* =pxCurrentTCB */ nt"
"LDR R0, [R0] nt"
"STR LR, [R0] nt"
);
( void ) ulCriticalNesting;
( void ) pxCurrentTCB;
}
~~~~~~
Instead of:
~~~~~~
define portRESTORE_CONTEXT()
{ extern volatile void * volatile pxCurrentTCB; extern volatile uint32_t ulCriticalNesting;
/* Set the LR to the task stack. */
__asm volatile (
"LDR R0, =pxCurrentTCB nt"
"LDR R0, [R0] nt"
"LDR LR, [R0] nt"
/* The critical nesting depth is the first item on the stack. */
/* Load it into the ulCriticalNesting variable. */
"LDR R0, =ulCriticalNesting nt"
"LDMFD LR!, {R1} nt"
"STR R1, [R0] nt"
/* Get the SPSR from the stack. */
"LDMFD LR!, {R0} nt"
"MSR SPSR, R0 nt"
/* Restore all system mode registers for the task. */
"LDMFD LR, {R0-R14}^ nt"
"NOP nt"
/* Restore the return address. */
"LDR LR, [LR, #+60] nt"
/* And return - correcting the offset in the LR to obtain the */
/* correct address. */
"SUBS PC, LR, #4 nt"
);
( void ) ulCriticalNesting;
( void ) pxCurrentTCB;
}
/———————————————————–/
define portSAVE_CONTEXT()
{ extern volatile void * volatile pxCurrentTCB; extern volatile uint32_t ulCriticalNesting;
/* Push R0 as we are going to use the register. */
__asm volatile (
"STMDB SP!, {R0} nt"
/* Set R0 to point to the task stack pointer. */
"STMDB SP,{SP}^ nt"
"NOP nt"
"SUB SP, SP, #4 nt"
"LDMIA SP!,{R0} nt"
/* Push the return address onto the stack. */
"STMDB R0!, {LR} nt"
/* Now we have saved LR we can use it instead of R0. */
"MOV LR, R0 nt"
/* Pop R0 so we can save it onto the system mode stack. */
"LDMIA SP!, {R0} nt"
/* Push all the system mode registers onto the task stack. */
"STMDB LR,{R0-LR}^ nt"
"NOP nt"
"SUB LR, LR, #60 nt"
/* Push the SPSR onto the task stack. */
"MRS R0, SPSR nt"
"STMDB LR!, {R0} nt"
"LDR R0, =ulCriticalNesting nt"
"LDR R0, [R0] nt"
"STMDB LR!, {R0} nt"
/* Store the new top of stack for the task. */
"LDR R0, =pxCurrentTCB nt"
"LDR R0, [R0] nt"
"STR LR, [R0] nt"
);
( void ) ulCriticalNesting;
( void ) pxCurrentTCB;
}
~~~~~~