]> git.sur5r.net Git - freertos/commitdiff
Added the portALIGNMENT_ASSERT_pxCurrentTCB macro.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Fri, 28 Oct 2011 11:50:00 +0000 (11:50 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Fri, 28 Oct 2011 11:50:00 +0000 (11:50 +0000)
Updated the TriCore port layer so its compare match setup does not effect any other compare match bits.

git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1629 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/include/FreeRTOS.h
Source/portable/GCC/TriCore_1782/port.c
Source/portable/GCC/TriCore_1782/portmacro.h
Source/tasks.c

index baa77afbc22e14010e9e31ab3b5494b2b3a5da71..4f24ac4edb3b12ab5425e89cf6577b33f8780deb 100644 (file)
@@ -192,6 +192,10 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
        #define configASSERT( x )\r
 #endif\r
 \r
+#ifndef portALIGNMENT_ASSERT_pxCurrentTCB\r
+       #define portALIGNMENT_ASSERT_pxCurrentTCB configASSERT\r
+#endif\r
+\r
 /* The timers module relies on xTaskGetSchedulerState(). */\r
 #if configUSE_TIMERS == 1\r
 \r
index cc33450445771fb6d5c8f6ad0c2ba5c639bf33bf..ab7f44a8db71dfac05f0c0166c3f4041b2205b4f 100644 (file)
@@ -95,7 +95,7 @@
 /*\r
  * Perform any hardware configuration necessary to generate the tick interrupt.\r
  */\r
-void vPortSystemTickHandler( int ) __attribute__((longcall));\r
+static void prvSystemTickHandler( int ) __attribute__((longcall));\r
 static void prvSetupTimerInterrupt( void );\r
 \r
 /*\r
@@ -107,6 +107,9 @@ static void prvPortYield( int iTrapIdentification );
 /* This reference is required by the save/restore context macros. */\r
 extern volatile unsigned long *pxCurrentTCB;\r
 \r
+/* Precalculate the compare match value at compile time. */\r
+static const unsigned long ulCompareMatchValue = ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ );\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
@@ -253,20 +256,23 @@ static void prvSetupTimerInterrupt( void )
        }\r
        lock_wdtcon();\r
 \r
-    /* Set-up the Compare value.  Determine how many bits are used. */\r
-       STM_CMCON.reg = ( 0x1fUL - __CLZ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ) );\r
+    /* Determine how many bits are used without changing other bits in the CMCON register. */\r
+       STM_CMCON.reg &= ~( 0x1fUL );\r
+       STM_CMCON.reg |= ( 0x1fUL - __CLZ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ) );\r
 \r
        /* Take into account the current time so a tick doesn't happen immediately. */\r
-       STM_CMP0.reg = ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ) + STM_TIM0.reg;\r
+       STM_CMP0.reg = ulCompareMatchValue + STM_TIM0.reg;\r
 \r
-       if( 0 != _install_int_handler( configKERNEL_INTERRUPT_PRIORITY, vPortSystemTickHandler, 0 ) )\r
+       if( 0 != _install_int_handler( configKERNEL_INTERRUPT_PRIORITY, prvSystemTickHandler, 0 ) )\r
        {\r
                /* Set-up the interrupt. */\r
                STM_SRC0.reg = ( configKERNEL_INTERRUPT_PRIORITY | 0x00005000UL );\r
 \r
                /* Enable the Interrupt. */\r
-               STM_ISRR.reg = 0x1UL;\r
-               STM_ICR.reg = 0x1UL;\r
+               STM_ISRR.reg &= ~( 0x03UL );\r
+               STM_ISRR.reg |= 0x1UL;\r
+               STM_ISRR.reg &= ~( 0x07UL );\r
+               STM_ICR.reg |= 0x1UL;\r
        }\r
        else\r
        {\r
@@ -276,7 +282,7 @@ static void prvSetupTimerInterrupt( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vPortSystemTickHandler( int iArg )\r
+static void prvSystemTickHandler( int iArg )\r
 {\r
 unsigned long ulSavedInterruptMask;\r
 \r
@@ -286,8 +292,24 @@ unsigned long ulSavedInterruptMask;
        /* Clear the interrupt source. */\r
        STM_ISRR.reg = 1UL;\r
 \r
-       /* Reload the Compare Match register for X ticks into the future. */\r
-       STM_CMP0.reg += ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ );\r
+       /* Reload the Compare Match register for X ticks into the future.\r
+\r
+       If critical section or interrupt nesting budgets are exceeded, then\r
+       it is possible that the calculated next compare match value is in the\r
+       past.  If this occurs (unlikely), it is possible that the resulting\r
+       time slippage will exceed a single tick period.  Any adverse effect of\r
+       this is time bounded by the fact that only the first n bits of the 56 bit\r
+       STM timer are being used for a compare match, so another compare match\r
+       will occur after an overflow in just those n bits (not the entire 56 bits).\r
+       As an example, if the peripheral clock is 75MHz, and the tick rate is 1KHz,\r
+       a missed tick could result in the next tick interrupt occurring within a\r
+       time that is 1.7 times the desired period.  The fact that this is greater\r
+       than a single tick period is an effect of using a timer that cannot be\r
+       automatically reset, in hardware, by the occurrence of a tick interrupt.\r
+       Changing the tick source to a timer that has an automatic reset on compare\r
+       match (such as a GPTA timer) will reduce the maximum possible additional\r
+       period to exactly 1 times the desired period. */\r
+       STM_CMP0.reg += ulCompareMatchValue;\r
 \r
        /* Kernel API calls require Critical Sections. */\r
        ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();\r
index 0f3a71e6a83ac713fffbd5342d460a3e7666281a..a71d0e3acf166ed0b696b515cb900cdc27214ed2 100644 (file)
@@ -146,6 +146,10 @@ extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE uxSavedStatus
 /* Set ICR.CCPN to uxSavedInterruptStatus */\r
 #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) vPortClearInterruptMaskFromISR( uxSavedStatusValue )\r
 \r
+/* As this port holds a CSA address in pxTopOfStack, the assert that checks the\r
+pxTopOfStack alignment is removed. */\r
+#define portALIGNMENT_ASSERT_pxCurrentTCB ( void )\r
+\r
 /*---------------------------------------------------------------------------*/\r
 \r
 /*\r
@@ -173,6 +177,7 @@ extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE uxSavedStatus
 {                                                                                                                              \\r
 unsigned portBASE_TYPE *pxUpperCSA = NULL;                                             \\r
 unsigned portBASE_TYPE xUpperCSA = 0UL;                                                        \\r
+extern volatile unsigned long *pxCurrentTCB;                                   \\r
        if ( pdTRUE == xHigherPriorityTaskWoken )                                       \\r
        {                                                                                                                       \\r
                _disable();                                                                                             \\r
index 3a4b21d75a53403df05280c6c01e133d75693d53..2d405c5868adc21e6c9f9190123771e751be973b 100644 (file)
@@ -504,7 +504,7 @@ tskTCB * pxNewTCB;
                #endif\r
 \r
                /* Check the alignment of the initialised stack. */\r
-               configASSERT( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
+               portALIGNMENT_ASSERT_pxCurrentTCB( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
 \r
                if( ( void * ) pxCreatedTask != NULL )\r
                {\r