in GCC/TriCore_38xa/port.c [297:374]
static void prvSystemTickHandler( int iArg )
{
uint32_t ulSavedInterruptMask;
uint32_t *pxUpperCSA = NULL;
uint32_t xUpperCSA = 0UL;
extern volatile uint32_t *pxCurrentTCB;
int32_t lYieldRequired;
unsigned short cpuid = CPU_ID;
/* Just to avoid compiler warnings about unused parameters. */
( void ) iArg;
/* Clear the interrupt source. */
//STM_ISRR.reg = 1UL; //ATEN
/* Reload the Compare Match register for X ticks into the future.
If critical section or interrupt nesting budgets are exceeded, then
it is possible that the calculated next compare match value is in the
past. If this occurs (unlikely), it is possible that the resulting
time slippage will exceed a single tick period. Any adverse effect of
this is time bounded by the fact that only the first n bits of the 56 bit
STM timer are being used for a compare match, so another compare match
will occur after an overflow in just those n bits (not the entire 56 bits).
As an example, if the peripheral clock is 75MHz, and the tick rate is 1KHz,
a missed tick could result in the next tick interrupt occurring within a
time that is 1.7 times the desired period. The fact that this is greater
than a single tick period is an effect of using a timer that cannot be
automatically reset, in hardware, by the occurrence of a tick interrupt.
Changing the tick source to a timer that has an automatic reset on compare
match (such as a GPTA timer) will reduce the maximum possible additional
period to exactly 1 times the desired period. */
STMs[cpuid]->CMP[0].U = STMs[cpuid]->TIM0.U + ulCompareMatchValue; //ATEN
STMs[cpuid]->ISCR.B.CMP0IRR = 1;
//STM_CMP0.reg += ulCompareMatchValue;
/* Kernel API calls require Critical Sections. */
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
{
/* Increment the Tick. */
lYieldRequired = xTaskIncrementTick();
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
if( lYieldRequired != pdFALSE )
{
/* 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;
SRBs[cpuid]->B.TRIG0 = 0; //ATEN
//CPU_SRC0.bits.SETR = 0;
_isync();
}
}