mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-20 18:18:32 -04:00
RL78 GCC: Save and restore all register banks.
This commit is contained in:
parent
3b9d0819c9
commit
3b1ff85222
13 changed files with 696 additions and 422 deletions
|
@ -72,8 +72,6 @@
|
|||
mission critical applications that require provable dependability.
|
||||
*/
|
||||
|
||||
/*_RB_ #include "FreeRTOSConfig.h" */
|
||||
|
||||
/* Variables used by scheduler */
|
||||
.extern _pxCurrentTCB
|
||||
.extern _usCriticalNesting
|
||||
|
@ -86,32 +84,47 @@
|
|||
*/
|
||||
.macro portSAVE_CONTEXT
|
||||
|
||||
SEL RB0
|
||||
|
||||
/* Save AX Register to stack. */
|
||||
PUSH AX
|
||||
PUSH HL
|
||||
#if __DATA_MODEL__ == __DATA_MODEL_FAR__
|
||||
PUSH AX
|
||||
PUSH HL
|
||||
/* Save CS register. */
|
||||
MOV A, CS
|
||||
XCH A, X
|
||||
MOV A, CS
|
||||
XCH A, X
|
||||
/* Save ES register. */
|
||||
MOV A, ES
|
||||
PUSH AX
|
||||
#else
|
||||
/* Save CS register. */
|
||||
MOV A, CS
|
||||
PUSH AX
|
||||
#endif
|
||||
/* Save the remaining general purpose registers. */
|
||||
PUSH DE
|
||||
PUSH BC
|
||||
MOV A, ES
|
||||
PUSH AX
|
||||
/* Save the remaining general purpose registers from bank 0. */
|
||||
PUSH DE
|
||||
PUSH BC
|
||||
/* Save the other register banks - only necessary in the GCC port. */
|
||||
SEL RB1
|
||||
PUSH AX
|
||||
PUSH BC
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
SEL RB2
|
||||
PUSH AX
|
||||
PUSH BC
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
SEL RB3
|
||||
PUSH AX
|
||||
PUSH BC
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
SEL RB0
|
||||
/* Save the usCriticalNesting value. */
|
||||
MOVW AX, !_usCriticalNesting
|
||||
PUSH AX
|
||||
MOVW AX, !_usCriticalNesting
|
||||
PUSH AX
|
||||
/* Save the Stack pointer. */
|
||||
MOVW AX, !_pxCurrentTCB
|
||||
MOVW HL, AX
|
||||
MOVW AX, SP
|
||||
MOVW [HL], AX
|
||||
MOVW AX, !_pxCurrentTCB
|
||||
MOVW HL, AX
|
||||
MOVW AX, SP
|
||||
MOVW [HL], AX
|
||||
/* Switch stack pointers. */
|
||||
movw sp,#_stack /* Set stack pointer */
|
||||
|
||||
.endm
|
||||
|
||||
|
@ -123,33 +136,46 @@
|
|||
* of the selected task from the task stack
|
||||
*/
|
||||
.macro portRESTORE_CONTEXT MACRO
|
||||
SEL RB0
|
||||
/* Restore the Stack pointer. */
|
||||
MOVW AX, !_pxCurrentTCB
|
||||
MOVW HL, AX
|
||||
MOVW AX, [HL]
|
||||
MOVW SP, AX
|
||||
MOVW AX, !_pxCurrentTCB
|
||||
MOVW HL, AX
|
||||
MOVW AX, [HL]
|
||||
MOVW SP, AX
|
||||
/* Restore usCriticalNesting value. */
|
||||
POP AX
|
||||
MOVW !_usCriticalNesting, AX
|
||||
POP AX
|
||||
MOVW !_usCriticalNesting, AX
|
||||
/* Restore the alternative register banks - only necessary in the GCC
|
||||
port. */
|
||||
SEL RB3
|
||||
POP HL
|
||||
POP DE
|
||||
POP BC
|
||||
POP AX
|
||||
SEL RB2
|
||||
POP HL
|
||||
POP DE
|
||||
POP BC
|
||||
POP AX
|
||||
SEL RB1
|
||||
POP HL
|
||||
POP DE
|
||||
POP BC
|
||||
POP AX
|
||||
SEL RB0
|
||||
/* Restore the necessary general purpose registers. */
|
||||
POP BC
|
||||
POP DE
|
||||
#if __DATA_MODEL__ == __DATA_MODEL_FAR__
|
||||
POP BC
|
||||
POP DE
|
||||
/* Restore the ES register. */
|
||||
POP AX
|
||||
MOV ES, A
|
||||
POP AX
|
||||
MOV ES, A
|
||||
/* Restore the CS register. */
|
||||
XCH A, X
|
||||
MOV CS, A
|
||||
#else
|
||||
POP AX
|
||||
/* Restore the CS register. */
|
||||
MOV CS, A
|
||||
#endif
|
||||
XCH A, X
|
||||
MOV CS, A
|
||||
/* Restore general purpose register HL. */
|
||||
POP HL
|
||||
POP HL
|
||||
/* Restore AX. */
|
||||
POP AX
|
||||
POP AX
|
||||
|
||||
.endm
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ interrupts don't accidentally become enabled before the scheduler is started. */
|
|||
#define portINITIAL_CRITICAL_NESTING ( ( unsigned short ) 10 )
|
||||
|
||||
/* Initial PSW value allocated to a newly created task.
|
||||
* 1100011000000000
|
||||
* 11000110
|
||||
* ||||||||-------------- Fill byte
|
||||
* |||||||--------------- Carry Flag cleared
|
||||
* |||||----------------- In-service priority Flags set to low level
|
||||
|
@ -95,7 +95,8 @@ interrupts don't accidentally become enabled before the scheduler is started. */
|
|||
* |--------------------- Zero Flag set
|
||||
* ---------------------- Global Interrupt Flag set (enabled)
|
||||
*/
|
||||
#define portPSW ( 0xc6UL )
|
||||
//#define portPSW ( 0xc6UL )
|
||||
#define portPSW ( 0x86UL )
|
||||
|
||||
/* The address of the pxCurrentTCB variable, but don't know or need to know its
|
||||
type. */
|
||||
|
@ -137,67 +138,24 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
|
|||
{
|
||||
unsigned long *pulLocal;
|
||||
|
||||
#if __DATA_MODEL__ == __DATA_MODEL_FAR__
|
||||
{
|
||||
/* Parameters are passed in on the stack, and written using a 32bit value
|
||||
hence a space is left for the second two bytes. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Write in the parameter value. */
|
||||
pulLocal = ( unsigned long * ) pxTopOfStack;
|
||||
*pulLocal = ( unsigned long ) pvParameters;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* These values are just spacers. The return address of the function
|
||||
would normally be written here. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x00;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x00;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The start address / PSW value is also written in as a 32bit value,
|
||||
so leave a space for the second two bytes. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Task function start address combined with the PSW. */
|
||||
pulLocal = ( unsigned long * ) pxTopOfStack;
|
||||
*pulLocal = ( ( ( unsigned long ) pxCode ) | ( portPSW << 24UL ) );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* An initial value for the AX register. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x1111;
|
||||
pxTopOfStack--;
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* Task function address is written to the stack first. As it is
|
||||
written as a 32bit value a space is left on the stack for the second
|
||||
two bytes. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Task function start address combined with the PSW. */
|
||||
pulLocal = ( unsigned long * ) pxTopOfStack;
|
||||
*pulLocal = ( ( ( unsigned long ) pxCode ) | ( portPSW << 24UL ) );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The parameter is passed in AX. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
|
||||
pxTopOfStack--;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef This_was_an_alternative_to_the_two_above
|
||||
/* Parameters are passed in on the stack. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
|
||||
/* Parameters are passed in on the stack, and written using a 32bit value
|
||||
hence a space is left for the second two bytes. */
|
||||
pxTopOfStack--;
|
||||
|
||||
#warning Why is the offset necessary? Presumably because the parameter could be 20 bits.
|
||||
pxTopOfStack--;
|
||||
/* Write in the parameter value. */
|
||||
pulLocal = ( unsigned long * ) pxTopOfStack;
|
||||
*pulLocal = ( unsigned long ) pvParameters;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Task function address is written to the stack first. As it is
|
||||
written as a 32bit value a space is left on the stack for the second
|
||||
two bytes. */
|
||||
/* These values are just spacers. The return address of the function
|
||||
would normally be written here. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x00;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x00;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The start address / PSW value is also written in as a 32bit value,
|
||||
so leave a space for the second two bytes. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Task function start address combined with the PSW. */
|
||||
|
@ -206,9 +164,9 @@ unsigned long *pulLocal;
|
|||
pxTopOfStack--;
|
||||
|
||||
/* An initial value for the AX register. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaa;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x1111;
|
||||
pxTopOfStack--;
|
||||
#endif
|
||||
|
||||
/* An initial value for the HL register. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x2222;
|
||||
pxTopOfStack--;
|
||||
|
@ -217,11 +175,9 @@ unsigned long *pulLocal;
|
|||
*pxTopOfStack = ( portSTACK_TYPE ) 0x0F00;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Finally the remaining general purpose registers DE and BC */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0xDEDE;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0xBCBC;
|
||||
pxTopOfStack--;
|
||||
/* The remaining general purpose registers bank 0 (DE and BC) and the other
|
||||
three register banks.. */
|
||||
pxTopOfStack -= 14;
|
||||
|
||||
/* Finally the critical section nesting count is set to zero when the task
|
||||
first starts. */
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
.extern _vTaskIncrementTick
|
||||
|
||||
.text
|
||||
.align 2
|
||||
|
||||
/* FreeRTOS yield handler. This is installed as the BRK software interrupt
|
||||
handler. */
|
||||
|
@ -101,6 +102,7 @@ _vPortYield:
|
|||
|
||||
/* Starts the scheduler by restoring the context of the task that will execute
|
||||
first. */
|
||||
.align 2
|
||||
_vPortStartFirstTask:
|
||||
/* Restore the context of whichever task will execute first. */
|
||||
portRESTORE_CONTEXT
|
||||
|
@ -109,6 +111,7 @@ _vPortStartFirstTask:
|
|||
|
||||
/* FreeRTOS tick handler. This is installed as the interval timer interrupt
|
||||
handler. */
|
||||
.align 2
|
||||
_vPortTickISR:
|
||||
|
||||
/* Save the context of the currently executing task. */
|
||||
|
|
|
@ -156,7 +156,7 @@ extern volatile unsigned short usCriticalNesting; \
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
#define portYIELD() __asm volatile ( "BRK" )
|
||||
#define portYIELD() __asm volatile ( "BRK" )
|
||||
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken ) vTaskSwitchContext()
|
||||
#define portNOP() __asm volatile ( "NOP" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue