mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Latest TriCore port files - these still contain some debug code, and are not yet fully documented.
This commit is contained in:
parent
93c4c48f78
commit
b89f1a729a
|
@ -75,11 +75,11 @@
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* System register Definitions. */
|
||||
#define portSYSTEM_PROGRAM_STATUS_WORD ( (unsigned portBASE_TYPE) 0x000008FF ) /* Supervisor Mode, MPU Register Set 0 and Call Depth Counting disabled. */
|
||||
#define portINITIAL_PRIVILEGED_PROGRAM_STATUS_WORD ( (unsigned portBASE_TYPE) 0x000014FF ) /* IO Level 1, MPU Register Set 1 and Call Depth Counting disabled. */
|
||||
#define portINITIAL_UNPRIVILEGED_PROGRAM_STATUS_WORD ( (unsigned portBASE_TYPE) 0x000010FF ) /* IO Level 0, MPU Register Set 1 and Call Depth Counting disabled. */
|
||||
#define portINITIAL_PCXI_UPPER_CONTEXT_WORD ( (unsigned portBASE_TYPE) 0x00C00000 ) /* The lower 20 bits identify the CSA address. */
|
||||
#define portINITIAL_SYSCON ( (unsigned portBASE_TYPE) 0x00000000 ) /* MPU Disable. */
|
||||
#define portSYSTEM_PROGRAM_STATUS_WORD ( 0x000008FFUL ) /* Supervisor Mode, MPU Register Set 0 and Call Depth Counting disabled. */
|
||||
#define portINITIAL_PRIVILEGED_PROGRAM_STATUS_WORD ( 0x000014FFUL ) /* IO Level 1, MPU Register Set 1 and Call Depth Counting disabled. */
|
||||
#define portINITIAL_UNPRIVILEGED_PROGRAM_STATUS_WORD ( 0x000010FFUL ) /* IO Level 0, MPU Register Set 1 and Call Depth Counting disabled. */
|
||||
#define portINITIAL_PCXI_UPPER_CONTEXT_WORD ( 0x00C00000UL ) /* The lower 20 bits identify the CSA address. */
|
||||
#define portINITIAL_SYSCON ( 0x00000000UL ) /* MPU Disable. */
|
||||
|
||||
/* CSA manipulation macros. */
|
||||
#define portCSA_FCX_MASK ( 0x000FFFFFUL )
|
||||
|
@ -90,6 +90,9 @@
|
|||
|
||||
/* Each CSA contains 16 words of data. */
|
||||
#define portNUM_WORDS_IN_CSA ( 16 )
|
||||
|
||||
/* The interrupt enable bit in the PCP_SRC register. */
|
||||
#define portENABLE_CPU_INTERRUPT ( 1U << 12U )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
@ -101,7 +104,13 @@ static void prvSetupTimerInterrupt( void );
|
|||
/*
|
||||
* Trap handler for yields.
|
||||
*/
|
||||
static void prvPortYield( int iTrapIdentification );
|
||||
static void prvTrapYield( int iTrapIdentification );
|
||||
|
||||
/*
|
||||
* Priority 1 interrupt handler for yields pended from an interrupt.
|
||||
*/
|
||||
static void prvInterruptYield( int iTrapIdentification );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* This reference is required by the save/restore context macros. */
|
||||
|
@ -153,10 +162,11 @@ unsigned long *pulLowerCSA = NULL;
|
|||
if( ( NULL != pulLowerCSA ) && ( NULL != pulUpperCSA ) )
|
||||
{
|
||||
/* Remove the two consumed CSAs from the free CSA list. */
|
||||
_disable();
|
||||
_dsync();
|
||||
_mtcr( $FCX, pulUpperCSA[ 0 ] );
|
||||
|
||||
/* ISync to commit the change to the FCX. */
|
||||
_isync();
|
||||
_enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -167,14 +177,14 @@ unsigned long *pulLowerCSA = NULL;
|
|||
portEXIT_CRITICAL();
|
||||
|
||||
/* Clear the upper CSA. */
|
||||
memset( pulUpperCSA, 0, portNUM_WORDS_IN_CSA * sizeof( unsigned portBASE_TYPE ) );
|
||||
memset( pulUpperCSA, 0, portNUM_WORDS_IN_CSA * sizeof( unsigned long ) );
|
||||
|
||||
/* Upper Context. */
|
||||
pulUpperCSA[ 2 ] = ( unsigned long )pxTopOfStack; /* A10; Stack Return aka Stack Pointer */
|
||||
pulUpperCSA[ 1 ] = portSYSTEM_PROGRAM_STATUS_WORD; /* PSW */
|
||||
|
||||
/* Clear the lower CSA. */
|
||||
memset( pulLowerCSA, 0, portNUM_WORDS_IN_CSA * sizeof( unsigned portBASE_TYPE ) );
|
||||
memset( pulLowerCSA, 0, portNUM_WORDS_IN_CSA * sizeof( unsigned long ) );
|
||||
|
||||
/* Lower Context. */
|
||||
pulLowerCSA[ 8 ] = ( unsigned long ) pvParameters; /* A4; Address Type Parameter Register */
|
||||
|
@ -193,29 +203,43 @@ unsigned long *pulLowerCSA = NULL;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portBASE_TYPE xPortStartScheduler( void )
|
||||
long xPortStartScheduler( void )
|
||||
{
|
||||
extern void vTrapInstallHandlers( void );
|
||||
unsigned long ulMFCR = 0UL;
|
||||
unsigned long *pulUpperCSA = NULL;
|
||||
unsigned long *pulLowerCSA = NULL;
|
||||
|
||||
/* Interrupts at or below configMAX_SYSCALL_INTERRUPT_PRIORITY are disable
|
||||
when this function is called. */
|
||||
|
||||
/* Set-up the timer interrupt. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Install the Trap Handlers. */
|
||||
vTrapInstallHandlers();
|
||||
|
||||
/* Install the Syscall Handler. */
|
||||
if( 0 == _install_trap_handler( portSYSCALL_TRAP, prvPortYield ) )
|
||||
/* Install the Syscall Handler for yield calls. */
|
||||
if( 0 == _install_trap_handler( portSYSCALL_TRAP, prvTrapYield ) )
|
||||
{
|
||||
/* Failed to install the yield handler, force an assert. */
|
||||
configASSERT( ( ( volatile void * ) NULL ) );
|
||||
}
|
||||
|
||||
/* Enable then install the priority 1 interrupt for pending context
|
||||
switches from an ISR. See mod_SRC in the TriCore manual. */
|
||||
CPU_SRC0.reg = ( portENABLE_CPU_INTERRUPT ) | ( configKERNEL_YIELD_PRIORITY );
|
||||
if( 0 == _install_int_handler( configKERNEL_YIELD_PRIORITY, prvInterruptYield, 0 ) )
|
||||
{
|
||||
/* Failed to install the yield handler, force an assert. */
|
||||
configASSERT( ( ( volatile void * ) NULL ) );
|
||||
}
|
||||
|
||||
_disable();
|
||||
|
||||
/* Load the initial SYSCON. */
|
||||
_dsync();
|
||||
_mtcr( $SYSCON, portINITIAL_SYSCON );
|
||||
_isync();
|
||||
|
||||
/* ENDINIT has already been applied in the 'cstart.c' code. */
|
||||
|
||||
|
@ -223,14 +247,16 @@ unsigned long *pulLowerCSA = NULL;
|
|||
exception because this code is not genuinely in an exception. */
|
||||
ulMFCR = _mfcr( $PSW );
|
||||
ulMFCR &= portRESTORE_PSW_MASK;
|
||||
_dsync();
|
||||
_mtcr( $PSW, ulMFCR );
|
||||
_isync();
|
||||
|
||||
/* Finally, perform the equivalent of a portRESTORE_CONTEXT() */
|
||||
pulLowerCSA = portCSA_TO_ADDRESS( ( *pxCurrentTCB ) );
|
||||
pulUpperCSA = portCSA_TO_ADDRESS( pulLowerCSA[0] );
|
||||
_mtcr( $PCXI, *pxCurrentTCB );
|
||||
|
||||
_dsync();
|
||||
_mtcr( $PCXI, *pxCurrentTCB );
|
||||
_isync();
|
||||
_nop();
|
||||
_rslcx();
|
||||
_nop();
|
||||
|
@ -285,6 +311,11 @@ static void prvSetupTimerInterrupt( void )
|
|||
static void prvSystemTickHandler( int iArg )
|
||||
{
|
||||
unsigned long ulSavedInterruptMask;
|
||||
unsigned long *pxUpperCSA = NULL;
|
||||
unsigned long xUpperCSA = 0UL;
|
||||
extern volatile unsigned long *pxCurrentTCB;
|
||||
|
||||
COUNT_NEST();
|
||||
|
||||
/* Just to avoid compiler warnings about unused parameters. */
|
||||
( void ) iArg;
|
||||
|
@ -321,8 +352,36 @@ unsigned long ulSavedInterruptMask;
|
|||
|
||||
#if configUSE_PREEMPTION == 1
|
||||
{
|
||||
portYIELD_FROM_ISR( pdTRUE );
|
||||
/* Save the context of a task.
|
||||
The upper context is automatically saved when entering a trap or interrupt.
|
||||
Need to save the lower context as well and copy the PCXI CSA ID into
|
||||
pxCurrentTCB->pxTopOfStack. Only Lower Context CSA IDs may be saved to the
|
||||
TCB of a task.
|
||||
|
||||
Call vTaskSwitchContext to select the next task, note that this changes the
|
||||
value of pxCurrentTCB so that it needs to be reloaded.
|
||||
|
||||
Call vPortSetMPURegisterSetOne to change the MPU mapping for the task
|
||||
that has just been switched in.
|
||||
|
||||
Load the context of the task.
|
||||
Need to restore the lower context by loading the CSA from
|
||||
pxCurrentTCB->pxTopOfStack into PCXI (effectively changing the call stack).
|
||||
In the Interrupt handler post-amble, RSLCX will restore the lower context
|
||||
of the task. RFE will restore the upper context of the task, jump to the
|
||||
return address and restore the previous state of interrupts being
|
||||
enabled/disabled. */
|
||||
_disable();
|
||||
_dsync();
|
||||
xUpperCSA = _mfcr( $PCXI );
|
||||
pxUpperCSA = portCSA_TO_ADDRESS( xUpperCSA );
|
||||
*pxCurrentTCB = pxUpperCSA[ 0 ];
|
||||
vTaskSwitchContext();
|
||||
pxUpperCSA[ 0 ] = *pxCurrentTCB;
|
||||
CPU_SRC0.bits.SETR = 0;
|
||||
_isync();
|
||||
}
|
||||
ulNest--;
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -345,10 +404,10 @@ unsigned long ulSavedInterruptMask;
|
|||
* than they can be freed assuming that tasks are being spawned and
|
||||
* deleted frequently.
|
||||
*/
|
||||
void vPortReclaimCSA( unsigned portBASE_TYPE *pxTCB )
|
||||
void vPortReclaimCSA( unsigned long *pxTCB )
|
||||
{
|
||||
unsigned portBASE_TYPE pxHeadCSA, pxTailCSA, pxFreeCSA;
|
||||
unsigned portBASE_TYPE *pulNextCSA;
|
||||
unsigned long pxHeadCSA, pxTailCSA, pxFreeCSA;
|
||||
unsigned long *pulNextCSA;
|
||||
|
||||
/* A pointer to the first CSA in the list of CSAs consumed by the task is
|
||||
stored in the first element of the tasks TCB structure (where the stack
|
||||
|
@ -382,7 +441,7 @@ unsigned portBASE_TYPE *pulNextCSA;
|
|||
pulNextCSA = portCSA_TO_ADDRESS( pxTailCSA );
|
||||
}
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
_disable();
|
||||
{
|
||||
/* Look up the current free CSA head. */
|
||||
_dsync();
|
||||
|
@ -394,11 +453,9 @@ unsigned portBASE_TYPE *pulNextCSA;
|
|||
/* Move the head of the reclaimed into the Free. */
|
||||
_dsync();
|
||||
_mtcr( $FCX, pxHeadCSA );
|
||||
|
||||
/* ISync to commit the change to the FCX. */
|
||||
_isync();
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
_enable();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -408,13 +465,43 @@ void vPortEndScheduler( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvPortYield( int iTrapIdentification )
|
||||
static void prvTrapYield( int iTrapIdentification )
|
||||
{
|
||||
unsigned long *pxUpperCSA = NULL;
|
||||
unsigned long xUpperCSA = 0UL;
|
||||
extern volatile unsigned long *pxCurrentTCB;
|
||||
|
||||
switch( iTrapIdentification )
|
||||
{
|
||||
case portSYSCALL_TASK_YIELD:
|
||||
/* Select another task to run. */
|
||||
portYIELD_FROM_ISR( pdTRUE );
|
||||
/* Save the context of a task.
|
||||
The upper context is automatically saved when entering a trap or interrupt.
|
||||
Need to save the lower context as well and copy the PCXI CSA ID into
|
||||
pxCurrentTCB->pxTopOfStack. Only Lower Context CSA IDs may be saved to the
|
||||
TCB of a task.
|
||||
|
||||
Call vTaskSwitchContext to select the next task, note that this changes the
|
||||
value of pxCurrentTCB so that it needs to be reloaded.
|
||||
|
||||
Call vPortSetMPURegisterSetOne to change the MPU mapping for the task
|
||||
that has just been switched in.
|
||||
|
||||
Load the context of the task.
|
||||
Need to restore the lower context by loading the CSA from
|
||||
pxCurrentTCB->pxTopOfStack into PCXI (effectively changing the call stack).
|
||||
In the Interrupt handler post-amble, RSLCX will restore the lower context
|
||||
of the task. RFE will restore the upper context of the task, jump to the
|
||||
return address and restore the previous state of interrupts being
|
||||
enabled/disabled. */
|
||||
_disable();
|
||||
_dsync();
|
||||
xUpperCSA = _mfcr( $PCXI );
|
||||
pxUpperCSA = portCSA_TO_ADDRESS( xUpperCSA );
|
||||
*pxCurrentTCB = pxUpperCSA[ 0 ];
|
||||
vTaskSwitchContext();
|
||||
pxUpperCSA[ 0 ] = *pxCurrentTCB;
|
||||
CPU_SRC0.bits.SETR = 0;
|
||||
_isync();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -425,20 +512,60 @@ static void prvPortYield( int iTrapIdentification )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR( void )
|
||||
static void prvInterruptYield( int iId )
|
||||
{
|
||||
unsigned portBASE_TYPE uxReturn = 0UL;
|
||||
unsigned long *pxUpperCSA = NULL;
|
||||
unsigned long xUpperCSA = 0UL;
|
||||
extern volatile unsigned long *pxCurrentTCB;
|
||||
COUNT_NEST();
|
||||
/* Just to remove compiler warnings. */
|
||||
( void ) iId;
|
||||
|
||||
/* Save the context of a task.
|
||||
The upper context is automatically saved when entering a trap or interrupt.
|
||||
Need to save the lower context as well and copy the PCXI CSA ID into
|
||||
pxCurrentTCB->pxTopOfStack. Only Lower Context CSA IDs may be saved to the
|
||||
TCB of a task.
|
||||
|
||||
Call vTaskSwitchContext to select the next task, note that this changes the
|
||||
value of pxCurrentTCB so that it needs to be reloaded.
|
||||
|
||||
Call vPortSetMPURegisterSetOne to change the MPU mapping for the task
|
||||
that has just been switched in.
|
||||
|
||||
Load the context of the task.
|
||||
Need to restore the lower context by loading the CSA from
|
||||
pxCurrentTCB->pxTopOfStack into PCXI (effectively changing the call stack).
|
||||
In the Interrupt handler post-amble, RSLCX will restore the lower context
|
||||
of the task. RFE will restore the upper context of the task, jump to the
|
||||
return address and restore the previous state of interrupts being
|
||||
enabled/disabled. */
|
||||
_disable();
|
||||
_dsync();
|
||||
xUpperCSA = _mfcr( $PCXI );
|
||||
pxUpperCSA = portCSA_TO_ADDRESS( xUpperCSA );
|
||||
*pxCurrentTCB = pxUpperCSA[ 0 ];
|
||||
vTaskSwitchContext();
|
||||
pxUpperCSA[ 0 ] = *pxCurrentTCB;
|
||||
CPU_SRC0.bits.SETR = 0;
|
||||
_isync();
|
||||
ulNest--;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
unsigned long uxPortSetInterruptMaskFromISR( void )
|
||||
{
|
||||
unsigned long uxReturn = 0UL;
|
||||
|
||||
_disable();
|
||||
uxReturn = _mfcr( $ICR );
|
||||
_mtcr( $ICR, ( ( uxReturn & ~portCCPN_MASK ) | configMAX_SYSCALL_INTERRUPT_PRIORITY ) );
|
||||
_isync();
|
||||
_enable();
|
||||
|
||||
/* Return just the interrupt mask bits. */
|
||||
return ( uxReturn & portCCPN_MASK );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE uxSavedStatusValue )
|
||||
{
|
||||
_mtcr( $ICR, ( uxSavedStatusValue & portCCPN_MASK ) );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -114,16 +114,12 @@ extern void vTaskExitCritical( void );
|
|||
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
|
||||
extern void vPortReclaimCSA( unsigned portBASE_TYPE *pxTCB );
|
||||
|
||||
/* CSA Manipulation. */
|
||||
#define portCSA_TO_ADDRESS( pCSA ) ( ( unsigned portBASE_TYPE * )( ( ( ( pCSA ) & 0x000F0000 ) << 12 ) | ( ( ( pCSA ) & 0x0000FFFF ) << 6 ) ) )
|
||||
#define portADDRESS_TO_CSA( pAddress ) ( ( unsigned portBASE_TYPE )( ( ( ( (unsigned portBASE_TYPE)( pAddress ) ) & 0xF0000000 ) >> 12 ) | ( ( (unsigned portBASE_TYPE)( pAddress ) & 0x003FFFC0 ) >> 6 ) ) )
|
||||
#define portCSA_TO_ADDRESS( pCSA ) ( ( unsigned long * )( ( ( ( pCSA ) & 0x000F0000 ) << 12 ) | ( ( ( pCSA ) & 0x0000FFFF ) << 6 ) ) )
|
||||
#define portADDRESS_TO_CSA( pAddress ) ( ( unsigned long )( ( ( ( (unsigned long)( pAddress ) ) & 0xF0000000 ) >> 12 ) | ( ( ( unsigned long )( pAddress ) & 0x003FFFC0 ) >> 6 ) ) )
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#define portYIELD() _syscall(0)
|
||||
#define portYIELD() _syscall( 0 )
|
||||
/* Port Restore is implicit in the platform when the function is returned from the original PSW is automatically replaced. */
|
||||
#define portSYSCALL_TASK_YIELD 0
|
||||
#define portSYSCALL_RAISE_PRIORITY 1
|
||||
|
@ -131,68 +127,53 @@ extern void vPortReclaimCSA( unsigned portBASE_TYPE *pxTCB );
|
|||
|
||||
/* Critical section management. */
|
||||
|
||||
/* Clear the ICR.IE bit. */
|
||||
#define portDISABLE_INTERRUPTS() _mtcr( $ICR, ( ( _mfcr( $ICR ) & ~portCCPN_MASK ) | configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
|
||||
/* Set ICR.CCPN to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
#define portDISABLE_INTERRUPTS() { \
|
||||
unsigned long ulICR; \
|
||||
_disable(); \
|
||||
ulICR = _mfcr( $ICR ); /* Get current ICR value. */ \
|
||||
ulICR &= ~portCCPN_MASK; /* Clear down mask bits. */ \
|
||||
ulICR |= configMAX_SYSCALL_INTERRUPT_PRIORITY; /* Set mask bits to required priority mask. */ \
|
||||
_mtcr( $ICR, ulICR ); /* Write back updated ICR. */ \
|
||||
_isync(); \
|
||||
_enable(); \
|
||||
}
|
||||
|
||||
/* Set the ICR.IE bit. */
|
||||
#define portENABLE_INTERRUPTS() { unsigned long ulCurrentICR = _mfcr( $ICR ); _mtcr( $ICR, ( ulCurrentICR & ~portCCPN_MASK ) ) }
|
||||
/* Clear ICR.CCPN to allow all interrupt priorities. */
|
||||
#define portENABLE_INTERRUPTS() { \
|
||||
unsigned long ulICR; \
|
||||
_disable(); \
|
||||
ulICR = _mfcr( $ICR ); /* Get current ICR value. */ \
|
||||
ulICR &= ~portCCPN_MASK; /* Clear down mask bits. */ \
|
||||
_mtcr( $ICR, ulICR ); /* Write back updated ICR. */ \
|
||||
_isync(); \
|
||||
_enable(); \
|
||||
}
|
||||
|
||||
/* Set ICR.CCPN to uxSavedMaskValue. */
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedMaskValue ) { \
|
||||
unsigned long ulICR; \
|
||||
_disable(); \
|
||||
ulICR = _mfcr( $ICR ); /* Get current ICR value. */ \
|
||||
ulICR &= ~portCCPN_MASK; /* Clear down mask bits. */ \
|
||||
ulICR |= uxSavedMaskValue; /* Set mask bits to previously saved mask value. */ \
|
||||
_mtcr( $ICR, ulICR ); /* Write back updated ICR. */ \
|
||||
_isync(); \
|
||||
_enable(); \
|
||||
}
|
||||
|
||||
extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR( void );
|
||||
extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE uxSavedStatusValue );
|
||||
|
||||
/* Set ICR.CCPN to configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||
extern unsigned long uxPortSetInterruptMaskFromISR( void );
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMaskFromISR()
|
||||
|
||||
/* Set ICR.CCPN to uxSavedInterruptStatus */
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) vPortClearInterruptMaskFromISR( uxSavedStatusValue )
|
||||
|
||||
/* As this port holds a CSA address in pxTopOfStack, the assert that checks the
|
||||
pxTopOfStack alignment is removed. */
|
||||
#define portALIGNMENT_ASSERT_pxCurrentTCB ( void )
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Pend a priority 1 interrupt, which will take care of the context switch. */
|
||||
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken != pdFALSE ) { CPU_SRC0.bits.SETR = 1; _isync(); }
|
||||
|
||||
/*
|
||||
* Save the context of a task.
|
||||
* The upper context is automatically saved when entering a trap or interrupt.
|
||||
* Need to save the lower context as well and copy the PCXI CSA ID into
|
||||
* pxCurrentTCB->pxTopOfStack. Only Lower Context CSA IDs may be saved to the
|
||||
* TCB of a task.
|
||||
*
|
||||
* Call vTaskSwitchContext to select the next task, note that this changes the
|
||||
* value of pxCurrentTCB so that it needs to be reloaded.
|
||||
*
|
||||
* Call vPortSetMPURegisterSetOne to change the MPU mapping for the task
|
||||
* that has just been switched in.
|
||||
*
|
||||
* Load the context of the task.
|
||||
* Need to restore the lower context by loading the CSA from
|
||||
* pxCurrentTCB->pxTopOfStack into PCXI (effectively changing the call stack).
|
||||
* In the Interrupt handler post-amble, RSLCX will restore the lower context
|
||||
* of the task. RFE will restore the upper context of the task, jump to the
|
||||
* return address and restore the previous state of interrupts being
|
||||
* enabled/disabled.
|
||||
*/
|
||||
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) \
|
||||
{ \
|
||||
unsigned portBASE_TYPE *pxUpperCSA = NULL; \
|
||||
unsigned portBASE_TYPE xUpperCSA = 0UL; \
|
||||
extern volatile unsigned long *pxCurrentTCB; \
|
||||
if ( pdTRUE == xHigherPriorityTaskWoken ) \
|
||||
{ \
|
||||
_disable(); \
|
||||
_isync(); \
|
||||
xUpperCSA = _mfcr( $PCXI ); \
|
||||
pxUpperCSA = portCSA_TO_ADDRESS( xUpperCSA ); \
|
||||
*pxCurrentTCB = pxUpperCSA[0]; \
|
||||
vTaskSwitchContext(); \
|
||||
pxUpperCSA[0] = *pxCurrentTCB; \
|
||||
_dsync(); \
|
||||
_isync(); \
|
||||
_nop(); \
|
||||
_nop(); \
|
||||
} \
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
|
@ -204,8 +185,8 @@ extern volatile unsigned long *pxCurrentTCB; \
|
|||
* Port specific clean up macro required to free the CSAs that were consumed by
|
||||
* a task that has since been deleted.
|
||||
*/
|
||||
void vPortReclaimCSA( unsigned portBASE_TYPE *pxTCB );
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortReclaimCSA( ( unsigned portBASE_TYPE *) ( pxTCB ) )
|
||||
void vPortReclaimCSA( unsigned long *pxTCB );
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortReclaimCSA( ( unsigned long * ) ( pxTCB ) )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue