mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Added the portALIGNMENT_ASSERT_pxCurrentTCB macro.
Updated the TriCore port layer so its compare match setup does not effect any other compare match bits.
This commit is contained in:
parent
f354d6599e
commit
188128f788
|
@ -192,6 +192,10 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
|
||||||
#define configASSERT( x )
|
#define configASSERT( x )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef portALIGNMENT_ASSERT_pxCurrentTCB
|
||||||
|
#define portALIGNMENT_ASSERT_pxCurrentTCB configASSERT
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The timers module relies on xTaskGetSchedulerState(). */
|
/* The timers module relies on xTaskGetSchedulerState(). */
|
||||||
#if configUSE_TIMERS == 1
|
#if configUSE_TIMERS == 1
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
/*
|
/*
|
||||||
* Perform any hardware configuration necessary to generate the tick interrupt.
|
* Perform any hardware configuration necessary to generate the tick interrupt.
|
||||||
*/
|
*/
|
||||||
void vPortSystemTickHandler( int ) __attribute__((longcall));
|
static void prvSystemTickHandler( int ) __attribute__((longcall));
|
||||||
static void prvSetupTimerInterrupt( void );
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -107,6 +107,9 @@ static void prvPortYield( int iTrapIdentification );
|
||||||
/* This reference is required by the save/restore context macros. */
|
/* This reference is required by the save/restore context macros. */
|
||||||
extern volatile unsigned long *pxCurrentTCB;
|
extern volatile unsigned long *pxCurrentTCB;
|
||||||
|
|
||||||
|
/* Precalculate the compare match value at compile time. */
|
||||||
|
static const unsigned long ulCompareMatchValue = ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
@ -253,20 +256,23 @@ static void prvSetupTimerInterrupt( void )
|
||||||
}
|
}
|
||||||
lock_wdtcon();
|
lock_wdtcon();
|
||||||
|
|
||||||
/* Set-up the Compare value. Determine how many bits are used. */
|
/* Determine how many bits are used without changing other bits in the CMCON register. */
|
||||||
STM_CMCON.reg = ( 0x1fUL - __CLZ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ) );
|
STM_CMCON.reg &= ~( 0x1fUL );
|
||||||
|
STM_CMCON.reg |= ( 0x1fUL - __CLZ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ) );
|
||||||
|
|
||||||
/* Take into account the current time so a tick doesn't happen immediately. */
|
/* Take into account the current time so a tick doesn't happen immediately. */
|
||||||
STM_CMP0.reg = ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ) + STM_TIM0.reg;
|
STM_CMP0.reg = ulCompareMatchValue + STM_TIM0.reg;
|
||||||
|
|
||||||
if( 0 != _install_int_handler( configKERNEL_INTERRUPT_PRIORITY, vPortSystemTickHandler, 0 ) )
|
if( 0 != _install_int_handler( configKERNEL_INTERRUPT_PRIORITY, prvSystemTickHandler, 0 ) )
|
||||||
{
|
{
|
||||||
/* Set-up the interrupt. */
|
/* Set-up the interrupt. */
|
||||||
STM_SRC0.reg = ( configKERNEL_INTERRUPT_PRIORITY | 0x00005000UL );
|
STM_SRC0.reg = ( configKERNEL_INTERRUPT_PRIORITY | 0x00005000UL );
|
||||||
|
|
||||||
/* Enable the Interrupt. */
|
/* Enable the Interrupt. */
|
||||||
STM_ISRR.reg = 0x1UL;
|
STM_ISRR.reg &= ~( 0x03UL );
|
||||||
STM_ICR.reg = 0x1UL;
|
STM_ISRR.reg |= 0x1UL;
|
||||||
|
STM_ISRR.reg &= ~( 0x07UL );
|
||||||
|
STM_ICR.reg |= 0x1UL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -276,7 +282,7 @@ static void prvSetupTimerInterrupt( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortSystemTickHandler( int iArg )
|
static void prvSystemTickHandler( int iArg )
|
||||||
{
|
{
|
||||||
unsigned long ulSavedInterruptMask;
|
unsigned long ulSavedInterruptMask;
|
||||||
|
|
||||||
|
@ -286,8 +292,24 @@ unsigned long ulSavedInterruptMask;
|
||||||
/* Clear the interrupt source. */
|
/* Clear the interrupt source. */
|
||||||
STM_ISRR.reg = 1UL;
|
STM_ISRR.reg = 1UL;
|
||||||
|
|
||||||
/* Reload the Compare Match register for X ticks into the future. */
|
/* Reload the Compare Match register for X ticks into the future.
|
||||||
STM_CMP0.reg += ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ );
|
|
||||||
|
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. */
|
||||||
|
STM_CMP0.reg += ulCompareMatchValue;
|
||||||
|
|
||||||
/* Kernel API calls require Critical Sections. */
|
/* Kernel API calls require Critical Sections. */
|
||||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
|
|
@ -146,6 +146,10 @@ extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE uxSavedStatus
|
||||||
/* Set ICR.CCPN to uxSavedInterruptStatus */
|
/* Set ICR.CCPN to uxSavedInterruptStatus */
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) vPortClearInterruptMaskFromISR( uxSavedStatusValue )
|
#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 )
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -173,6 +177,7 @@ extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE uxSavedStatus
|
||||||
{ \
|
{ \
|
||||||
unsigned portBASE_TYPE *pxUpperCSA = NULL; \
|
unsigned portBASE_TYPE *pxUpperCSA = NULL; \
|
||||||
unsigned portBASE_TYPE xUpperCSA = 0UL; \
|
unsigned portBASE_TYPE xUpperCSA = 0UL; \
|
||||||
|
extern volatile unsigned long *pxCurrentTCB; \
|
||||||
if ( pdTRUE == xHigherPriorityTaskWoken ) \
|
if ( pdTRUE == xHigherPriorityTaskWoken ) \
|
||||||
{ \
|
{ \
|
||||||
_disable(); \
|
_disable(); \
|
||||||
|
|
|
@ -504,7 +504,7 @@ tskTCB * pxNewTCB;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Check the alignment of the initialised stack. */
|
/* Check the alignment of the initialised stack. */
|
||||||
configASSERT( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
|
portALIGNMENT_ASSERT_pxCurrentTCB( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
|
||||||
|
|
||||||
if( ( void * ) pxCreatedTask != NULL )
|
if( ( void * ) pxCreatedTask != NULL )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue