]> git.sur5r.net Git - freertos/blobdiff - Source/tasks.c
Add two Cortex-M4F port layers.
[freertos] / Source / tasks.c
index 01d7565ec6fb10b6a1ad11e404d2074dca672f92..91b749bf1502421a21d5e82de97563aaea5d517e 100644 (file)
@@ -1,11 +1,5 @@
 /*\r
-    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-       \r
-\r
-       FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:\r
-       Atollic AB - Atollic provides professional embedded systems development \r
-       tools for C/C++ development, code analysis and test automation.  \r
-       See http://www.atollic.com\r
+    FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
        \r
 \r
     ***************************************************************************\r
@@ -106,7 +100,8 @@ typedef struct tskTaskControlBlock
        #endif\r
 \r
        #if ( configUSE_TRACE_FACILITY == 1 )\r
-               unsigned portBASE_TYPE  uxTCBNumber;    /*< This is used for tracing the scheduler and making debugging easier only. */\r
+               unsigned portBASE_TYPE  uxTCBNumber;    /*< This stores a number that increments each time a TCB is created.  It allows debuggers to determine when a task has been deleted and then recreated. */\r
+               unsigned portBASE_TYPE  uxTaskNumber;   /*< This stores a number specifically for use by third party trace code. */\r
        #endif\r
 \r
        #if ( configUSE_MUTEXES == 1 )\r
@@ -157,7 +152,7 @@ PRIVILEGED_DATA static xList xPendingReadyList;                                                     /*< Tasks that have been r
 \r
 #endif\r
 \r
-#if ( INCLUDE_xTaskIdleTaskHandleGet == 1 )\r
+#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )\r
        \r
        PRIVILEGED_DATA static xTaskHandle xIdleTaskHandle = NULL;\r
        \r
@@ -173,7 +168,7 @@ PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended         =
 PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks                   = ( unsigned portBASE_TYPE ) 0U;\r
 PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield                                             = ( portBASE_TYPE ) pdFALSE;\r
 PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows                                  = ( portBASE_TYPE ) 0;\r
-PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber                                             = ( unsigned portBASE_TYPE ) 0U;\r
+PRIVILEGED_DATA static unsigned portBASE_TYPE uxTCBNumber                                              = ( unsigned portBASE_TYPE ) 0U;\r
 PRIVILEGED_DATA static portTickType xNextTaskUnblockTime                                               = ( portTickType ) portMAX_DELAY;\r
 \r
 #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
@@ -200,58 +195,6 @@ PRIVILEGED_DATA static portTickType xNextTaskUnblockTime                                           = ( portTickType )
 #define tskDELETED_CHAR                ( ( signed char ) 'D' )\r
 #define tskSUSPENDED_CHAR      ( ( signed char ) 'S' )\r
 \r
-/*\r
- * Macros and private variables used by the trace facility.\r
- */\r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
-\r
-       #define tskSIZE_OF_EACH_TRACE_LINE                      ( ( unsigned long ) ( sizeof( unsigned long ) + sizeof( unsigned long ) ) )\r
-       PRIVILEGED_DATA static volatile signed char * volatile pcTraceBuffer;\r
-       PRIVILEGED_DATA static signed char *pcTraceBufferStart;\r
-       PRIVILEGED_DATA static signed char *pcTraceBufferEnd;\r
-       PRIVILEGED_DATA static signed portBASE_TYPE xTracing = pdFALSE;\r
-       static unsigned portBASE_TYPE uxPreviousTask = 255U;\r
-       PRIVILEGED_DATA static char pcStatusString[ 50 ];\r
-\r
-#endif\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Macro that writes a trace of scheduler activity to a buffer.  This trace\r
- * shows which task is running when and is very useful as a debugging tool.\r
- * As this macro is called each context switch it is a good idea to undefine\r
- * it if not using the facility.\r
- */\r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
-\r
-       #define vWriteTraceToBuffer()                                                                                                                                   \\r
-       {                                                                                                                                                                                               \\r
-               if( xTracing != pdFALSE )                                                                                                                                       \\r
-               {                                                                                                                                                                                       \\r
-                       if( uxPreviousTask != pxCurrentTCB->uxTCBNumber )                                                                               \\r
-                       {                                                                                                                                                                               \\r
-                               if( ( pcTraceBuffer + tskSIZE_OF_EACH_TRACE_LINE ) < pcTraceBufferEnd )                         \\r
-                               {                                                                                                                                                                       \\r
-                                       uxPreviousTask = pxCurrentTCB->uxTCBNumber;                                                                             \\r
-                                       *( unsigned long * ) pcTraceBuffer = ( unsigned long ) xTickCount;                              \\r
-                                       pcTraceBuffer += sizeof( unsigned long );                                                                               \\r
-                                       *( unsigned long * ) pcTraceBuffer = ( unsigned long ) uxPreviousTask;                  \\r
-                                       pcTraceBuffer += sizeof( unsigned long );                                                                               \\r
-                               }                                                                                                                                                                       \\r
-                               else                                                                                                                                                            \\r
-                               {                                                                                                                                                                       \\r
-                                       xTracing = pdFALSE;                                                                                                                             \\r
-                               }                                                                                                                                                                       \\r
-                       }                                                                                                                                                                               \\r
-               }                                                                                                                                                                                       \\r
-       }\r
-\r
-#else\r
-\r
-       #define vWriteTraceToBuffer()\r
-\r
-#endif\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
@@ -473,7 +416,7 @@ tskTCB * pxNewTCB;
                #if( portSTACK_GROWTH < 0 )\r
                {\r
                        pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( unsigned short ) 1 );\r
-                       pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( unsigned long ) pxTopOfStack ) & ( ( unsigned long ) ~portBYTE_ALIGNMENT_MASK  ) );\r
+                       pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK  ) );\r
 \r
                        /* Check the alignment of the calculated top of stack is correct. */\r
                        configASSERT( ( ( ( unsigned long ) pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
@@ -510,7 +453,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
@@ -563,10 +506,10 @@ tskTCB * pxNewTCB;
                        #if ( configUSE_TRACE_FACILITY == 1 )\r
                        {\r
                                /* Add a counter into the TCB for tracing only. */\r
-                               pxNewTCB->uxTCBNumber = uxTaskNumber;\r
+                               pxNewTCB->uxTCBNumber = uxTCBNumber;\r
                        }\r
                        #endif\r
-                       uxTaskNumber++;\r
+                       uxTCBNumber++;\r
 \r
                        prvAddTaskToReadyQueue( pxNewTCB );\r
 \r
@@ -637,7 +580,7 @@ tskTCB * pxNewTCB;
 \r
                        /* Increment the uxTaskNumberVariable also so kernel aware debuggers\r
                        can detect that the task lists need re-generating. */\r
-                       uxTaskNumber++;\r
+                       uxTCBNumber++;\r
 \r
                        traceTASK_DELETE( pxTCB );\r
                }\r
@@ -824,7 +767,7 @@ tskTCB * pxNewTCB;
                        priority of the calling function. */\r
                        pxTCB = prvGetTCBFromHandle( pxTask );\r
 \r
-                       traceTASK_PRIORITY_SET( pxTask, uxNewPriority );\r
+                       traceTASK_PRIORITY_SET( pxTCB, uxNewPriority );\r
 \r
                        #if ( configUSE_MUTEXES == 1 )\r
                        {\r
@@ -950,7 +893,7 @@ tskTCB * pxNewTCB;
                                /* The scheduler is not running, but the task that was pointed\r
                                to by pxCurrentTCB has just been suspended and pxCurrentTCB\r
                                must be adjusted to point to a different task. */\r
-                               if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) \r
+                               if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks )\r
                                {\r
                                        /* No other tasks are ready, so set pxCurrentTCB back to\r
                                        NULL so when the next task is created pxCurrentTCB will\r
@@ -1054,29 +997,34 @@ tskTCB * pxNewTCB;
        {\r
        portBASE_TYPE xYieldRequired = pdFALSE;\r
        tskTCB *pxTCB;\r
+       unsigned portBASE_TYPE uxSavedInterruptStatus;\r
 \r
                configASSERT( pxTaskToResume );\r
 \r
                pxTCB = ( tskTCB * ) pxTaskToResume;\r
 \r
-               if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )\r
+               uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
                {\r
-                       traceTASK_RESUME_FROM_ISR( pxTCB );\r
-\r
-                       if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
-                       {\r
-                               xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
-                               vListRemove(  &( pxTCB->xGenericListItem ) );\r
-                               prvAddTaskToReadyQueue( pxTCB );\r
-                       }\r
-                       else\r
+                       if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )\r
                        {\r
-                               /* We cannot access the delayed or ready lists, so will hold this\r
-                               task pending until the scheduler is resumed, at which point a\r
-                               yield will be performed if necessary. */\r
-                               vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );\r
+                               traceTASK_RESUME_FROM_ISR( pxTCB );\r
+\r
+                               if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
+                               {\r
+                                       xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
+                                       vListRemove(  &( pxTCB->xGenericListItem ) );\r
+                                       prvAddTaskToReadyQueue( pxTCB );\r
+                               }\r
+                               else\r
+                               {\r
+                                       /* We cannot access the delayed or ready lists, so will hold this\r
+                                       task pending until the scheduler is resumed, at which point a\r
+                                       yield will be performed if necessary. */\r
+                                       vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );\r
+                               }\r
                        }\r
                }\r
+               portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
 \r
                return xYieldRequired;\r
        }\r
@@ -1096,10 +1044,10 @@ void vTaskStartScheduler( void )
 portBASE_TYPE xReturn;\r
 \r
        /* Add the idle task at the lowest priority. */\r
-       #if ( INCLUDE_xTaskIdleTaskHandleGet == 1 )\r
+       #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )\r
        {\r
                /* Create the idle task, storing its handle in xIdleTaskHandle so it can\r
-               be returned by the xTaskIdleTaskHandleGet() function. */\r
+               be returned by the xTaskGetIdleTaskHandle() function. */\r
                xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle );\r
        }\r
        #else\r
@@ -1298,9 +1246,9 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-#if ( INCLUDE_pcTaskNameGet == 1 )\r
+#if ( INCLUDE_pcTaskGetTaskName == 1 )\r
 \r
-       signed char *pcTaskNameGet( xTaskHandle xTaskToQuery )\r
+       signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery )\r
        {\r
        tskTCB *pxTCB;\r
 \r
@@ -1451,49 +1399,11 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
 #endif\r
 /*----------------------------------------------------------*/\r
 \r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
-\r
-       void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize )\r
-       {\r
-               configASSERT( pcBuffer );\r
-               configASSERT( ulBufferSize );\r
-\r
-               taskENTER_CRITICAL();\r
-               {\r
-                       pcTraceBuffer = ( signed char * )pcBuffer;\r
-                       pcTraceBufferStart = pcBuffer;\r
-                       pcTraceBufferEnd = pcBuffer + ( ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE );\r
-                       xTracing = pdTRUE;\r
-               }\r
-               taskEXIT_CRITICAL();\r
-       }\r
-\r
-#endif\r
-/*----------------------------------------------------------*/\r
-\r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
-\r
-       unsigned long ulTaskEndTrace( void )\r
-       {\r
-       unsigned long ulBufferLength;\r
-\r
-               taskENTER_CRITICAL();\r
-                       xTracing = pdFALSE;\r
-               taskEXIT_CRITICAL();\r
-\r
-               ulBufferLength = ( unsigned long ) ( pcTraceBuffer - pcTraceBufferStart );\r
-\r
-               return ulBufferLength;\r
-       }\r
-\r
-#endif\r
-/*----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_xTaskIdleTaskHandleGet == 1 )\r
+#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )\r
 \r
-       xTaskHandle xTaskIdleTaskHandleGet( void )\r
+       xTaskHandle xTaskGetIdleTaskHandle( void )\r
        {\r
-               /* If xTaskIdleTaskHandleGet() is called before the scheduler has been\r
+               /* If xTaskGetIdleTaskHandle() is called before the scheduler has been\r
                started, then xIdleTaskHandle will be NULL. */\r
                configASSERT( ( xIdleTaskHandle != NULL ) );\r
                return xIdleTaskHandle;\r
@@ -1532,18 +1442,18 @@ tskTCB * pxTCB;
        \r
                        if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )\r
                        {\r
-                               /* The new current delayed list is empty.  Set \r
-                               xNextTaskUnblockTime to the maximum possible value so it is \r
+                               /* The new current delayed list is empty.  Set\r
+                               xNextTaskUnblockTime to the maximum possible value so it is\r
                                extremely unlikely that the     \r
-                               if( xTickCount >= xNextTaskUnblockTime ) test will pass until \r
+                               if( xTickCount >= xNextTaskUnblockTime ) test will pass until\r
                                there is an item in the delayed list. */\r
                                xNextTaskUnblockTime = portMAX_DELAY;\r
                        }\r
                        else\r
                        {\r
-                               /* The new current delayed list is not empty, get the value of \r
-                               the item at the head of the delayed list.  This is the time at \r
-                               which the task at the head of the delayed list should be removed \r
+                               /* The new current delayed list is not empty, get the value of\r
+                               the item at the head of the delayed list.  This is the time at\r
+                               which the task at the head of the delayed list should be removed\r
                                from the Blocked state. */\r
                                pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );\r
                                xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );\r
@@ -1715,7 +1625,6 @@ void vTaskSwitchContext( void )
                listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );\r
        \r
                traceTASK_SWITCHED_IN();\r
-               vWriteTraceToBuffer();\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -1911,6 +1820,42 @@ void vTaskMissedYield( void )
 {\r
        xMissedYield = pdTRUE;\r
 }\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+       unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask )\r
+       {\r
+       unsigned portBASE_TYPE uxReturn;\r
+       tskTCB *pxTCB;\r
+       \r
+               if( xTask != NULL )\r
+               {\r
+                       pxTCB = ( tskTCB * ) xTask;\r
+                       uxReturn = pxTCB->uxTaskNumber;\r
+               }\r
+               else\r
+               {\r
+                       uxReturn = 0U;\r
+               }\r
+               \r
+               return uxReturn;\r
+       }\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+       void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle )\r
+       {\r
+       tskTCB *pxTCB;\r
+       \r
+               if( xTask != NULL )\r
+               {\r
+                       pxTCB = ( tskTCB * ) xTask;\r
+                       pxTCB->uxTaskNumber = uxHandle;\r
+               }\r
+       }\r
+#endif\r
+\r
 \r
 /*\r
  * -----------------------------------------------------------\r
@@ -2205,6 +2150,7 @@ tskTCB *pxNewTCB;
        {\r
        volatile tskTCB *pxNextTCB, *pxFirstTCB;\r
        unsigned short usStackRemaining;\r
+       PRIVILEGED_DATA static char pcStatusString[ 50 ];\r
 \r
                /* Write the details of all the TCB's in pxList into the buffer. */\r
                listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );\r
@@ -2353,6 +2299,10 @@ tskTCB *pxNewTCB;
 \r
        static void prvDeleteTCB( tskTCB *pxTCB )\r
        {\r
+               /* This call is required specifically for the TriCore port.  It must be\r
+               above the vPortFree() calls. */\r
+               portCLEAN_UP_TCB( pxTCB );\r
+\r
                /* Free up the memory allocated by the scheduler for the task.  It is up to\r
                the task to free any memory allocated at the application level. */\r
                vPortFreeAligned( pxTCB->pxStack );\r
@@ -2438,6 +2388,8 @@ tskTCB *pxNewTCB;
                                /* Just inherit the priority. */\r
                                pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
                        }\r
+\r
+                       traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority );\r
                }\r
        }\r
 \r
@@ -2458,8 +2410,9 @@ tskTCB *pxNewTCB;
                                Remove ourselves from the ready list we currently appear in. */\r
                                vListRemove( &( pxTCB->xGenericListItem ) );\r
 \r
-                               /* Disinherit the priority before adding ourselves into the new\r
+                               /* Disinherit the priority before adding the task into the new\r
                                ready list. */\r
+                               traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority );\r
                                pxTCB->uxPriority = pxTCB->uxBasePriority;\r
                                listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority );\r
                                prvAddTaskToReadyQueue( pxTCB );\r