]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/tasks.c
First task running in RISC-V-Qemu-sifive_e-FreedomStudio demo.
[freertos] / FreeRTOS / Source / tasks.c
index f6009fcc757500359fafc286a440e3915e98c259..faf46713e393413b714e8e03c826008f2b7b6351 100644 (file)
@@ -100,7 +100,7 @@ changed then the definition of StaticTask_t must also be updated. */
 /* If any of the following are set then task stacks are filled with a known\r
 value so the high water mark can be determined.  If none of the following are\r
 set then don't fill the stack so there is no unnecessary dependency on memset. */\r
-#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) )\r
        #define tskSET_NEW_STACKS_TO_KNOWN_VALUE        1\r
 #else\r
        #define tskSET_NEW_STACKS_TO_KNOWN_VALUE        0\r
@@ -521,7 +521,7 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseT
  * This function determines the 'high water mark' of the task stack by\r
  * determining how much of the stack remains at the original preset value.\r
  */\r
-#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) )\r
 \r
        static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION;\r
 \r
@@ -861,8 +861,6 @@ UBaseType_t x;
                uxPriority &= ~portPRIVILEGE_BIT;\r
        #endif /* portUSING_MPU_WRAPPERS == 1 */\r
 \r
-       configASSERT( pcName );\r
-\r
        /* Avoid dependency on memset() if it is not required. */\r
        #if( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 )\r
        {\r
@@ -905,26 +903,35 @@ UBaseType_t x;
        #endif /* portSTACK_GROWTH */\r
 \r
        /* Store the task name in the TCB. */\r
-       for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ )\r
+       if( pcName != NULL )\r
        {\r
-               pxNewTCB->pcTaskName[ x ] = pcName[ x ];\r
-\r
-               /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than\r
-               configMAX_TASK_NAME_LEN characters just in case the memory after the\r
-               string is not accessible (extremely unlikely). */\r
-               if( pcName[ x ] == ( char ) 0x00 )\r
+               for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ )\r
                {\r
-                       break;\r
-               }\r
-               else\r
-               {\r
-                       mtCOVERAGE_TEST_MARKER();\r
+                       pxNewTCB->pcTaskName[ x ] = pcName[ x ];\r
+\r
+                       /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than\r
+                       configMAX_TASK_NAME_LEN characters just in case the memory after the\r
+                       string is not accessible (extremely unlikely). */\r
+                       if( pcName[ x ] == ( char ) 0x00 )\r
+                       {\r
+                               break;\r
+                       }\r
+                       else\r
+                       {\r
+                               mtCOVERAGE_TEST_MARKER();\r
+                       }\r
                }\r
-       }\r
 \r
-       /* Ensure the name string is terminated in the case that the string length\r
-       was greater or equal to configMAX_TASK_NAME_LEN. */\r
-       pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0';\r
+               /* Ensure the name string is terminated in the case that the string length\r
+               was greater or equal to configMAX_TASK_NAME_LEN. */\r
+               pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0';\r
+       }\r
+       else\r
+       {\r
+               /* The task has not been given a name, so just ensure there is a NULL\r
+               terminator when it is read out. */\r
+               pxNewTCB->pcTaskName[ 0 ] = 0x00;\r
+       }\r
 \r
        /* This is used as an array index so must ensure it's not too large.  First\r
        remove the privilege bit if one is present. */\r
@@ -2838,24 +2845,17 @@ BaseType_t xSwitchRequired = pdFALSE;
 \r
        TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask )\r
        {\r
-       TCB_t *xTCB;\r
+       TCB_t *pxTCB;\r
        TaskHookFunction_t xReturn;\r
 \r
-               /* If xTask is NULL then we are setting our own task hook. */\r
-               if( xTask == NULL )\r
-               {\r
-                       xTCB = ( TCB_t * ) pxCurrentTCB;\r
-               }\r
-               else\r
-               {\r
-                       xTCB = xTask;\r
-               }\r
+               /* If xTask is NULL then set the calling task's hook. */\r
+               pxTCB = prvGetTCBFromHandle( xTask );\r
 \r
                /* Save the hook function in the TCB.  A critical section is required as\r
                the value can be accessed from an interrupt. */\r
                taskENTER_CRITICAL();\r
                {\r
-                       xReturn = xTCB->pxTaskTag;\r
+                       xReturn = pxTCB->pxTaskTag;\r
                }\r
                taskEXIT_CRITICAL();\r
 \r
@@ -2865,6 +2865,31 @@ BaseType_t xSwitchRequired = pdFALSE;
 #endif /* configUSE_APPLICATION_TASK_TAG */\r
 /*-----------------------------------------------------------*/\r
 \r
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
+\r
+       TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask )\r
+       {\r
+       TCB_t *pxTCB;\r
+       TaskHookFunction_t xReturn;\r
+       UBaseType_t uxSavedInterruptStatus;\r
+\r
+               /* If xTask is NULL then set the calling task's hook. */\r
+               pxTCB = prvGetTCBFromHandle( xTask );\r
+\r
+               /* Save the hook function in the TCB.  A critical section is required as\r
+               the value can be accessed from an interrupt. */\r
+               uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
+               {\r
+                       xReturn = pxTCB->pxTaskTag;\r
+               }\r
+               portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
+\r
+               return xReturn;\r
+       }\r
+\r
+#endif /* configUSE_APPLICATION_TASK_TAG */\r
+/*-----------------------------------------------------------*/\r
+\r
 #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
 \r
        BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter )\r
@@ -2912,28 +2937,28 @@ void vTaskSwitchContext( void )
 \r
                #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
                {\r
-                               #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE\r
-                                       portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime );\r
-                               #else\r
-                                       ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();\r
-                               #endif\r
+                       #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE\r
+                               portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime );\r
+                       #else\r
+                               ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();\r
+                       #endif\r
 \r
-                               /* Add the amount of time the task has been running to the\r
-                               accumulated time so far.  The time the task started running was\r
-                               stored in ulTaskSwitchedInTime.  Note that there is no overflow\r
-                               protection here so count values are only valid until the timer\r
-                               overflows.  The guard against negative values is to protect\r
-                               against suspect run time stat counter implementations - which\r
-                               are provided by the application, not the kernel. */\r
-                               if( ulTotalRunTime > ulTaskSwitchedInTime )\r
-                               {\r
-                                       pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );\r
-                               }\r
-                               else\r
-                               {\r
-                                       mtCOVERAGE_TEST_MARKER();\r
-                               }\r
-                               ulTaskSwitchedInTime = ulTotalRunTime;\r
+                       /* Add the amount of time the task has been running to the\r
+                       accumulated time so far.  The time the task started running was\r
+                       stored in ulTaskSwitchedInTime.  Note that there is no overflow\r
+                       protection here so count values are only valid until the timer\r
+                       overflows.  The guard against negative values is to protect\r
+                       against suspect run time stat counter implementations - which\r
+                       are provided by the application, not the kernel. */\r
+                       if( ulTotalRunTime > ulTaskSwitchedInTime )\r
+                       {\r
+                               pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );\r
+                       }\r
+                       else\r
+                       {\r
+                               mtCOVERAGE_TEST_MARKER();\r
+                       }\r
+                       ulTaskSwitchedInTime = ulTotalRunTime;\r
                }\r
                #endif /* configGENERATE_RUN_TIME_STATS */\r
 \r
@@ -3070,6 +3095,20 @@ BaseType_t xReturn;
        {\r
                ( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) );\r
                prvAddTaskToReadyList( pxUnblockedTCB );\r
+\r
+               #if( configUSE_TICKLESS_IDLE != 0 )\r
+               {\r
+                       /* If a task is blocked on a kernel object then xNextTaskUnblockTime\r
+                       might be set to the blocked task's time out time.  If the task is\r
+                       unblocked for a reason other than a timeout xNextTaskUnblockTime is\r
+                       normally left unchanged, because it is automatically reset to a new\r
+                       value when the tick count equals xNextTaskUnblockTime.  However if\r
+                       tickless idling is used it might be more important to enter sleep mode\r
+                       at the earliest possible time - so reset xNextTaskUnblockTime here to\r
+                       ensure it is updated at the earliest possible time. */\r
+                       prvResetNextTaskUnblockTime();\r
+               }\r
+               #endif\r
        }\r
        else\r
        {\r
@@ -3094,20 +3133,6 @@ BaseType_t xReturn;
                xReturn = pdFALSE;\r
        }\r
 \r
-       #if( configUSE_TICKLESS_IDLE != 0 )\r
-       {\r
-               /* If a task is blocked on a kernel object then xNextTaskUnblockTime\r
-               might be set to the blocked task's time out time.  If the task is\r
-               unblocked for a reason other than a timeout xNextTaskUnblockTime is\r
-               normally left unchanged, because it is automatically reset to a new\r
-               value when the tick count equals xNextTaskUnblockTime.  However if\r
-               tickless idling is used it might be more important to enter sleep mode\r
-               at the earliest possible time - so reset xNextTaskUnblockTime here to\r
-               ensure it is updated at the earliest possible time. */\r
-               prvResetNextTaskUnblockTime();\r
-       }\r
-       #endif\r
-\r
        return xReturn;\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -3686,7 +3711,7 @@ static void prvCheckTasksWaitingTermination( void )
 #endif /* configUSE_TRACE_FACILITY */\r
 /*-----------------------------------------------------------*/\r
 \r
-#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) )\r
 \r
        static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte )\r
        {\r
@@ -3703,7 +3728,47 @@ static void prvCheckTasksWaitingTermination( void )
                return ( configSTACK_DEPTH_TYPE ) ulCount;\r
        }\r
 \r
-#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */\r
+#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 )\r
+\r
+       /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the\r
+       same except for their return type.  Using configSTACK_DEPTH_TYPE allows the\r
+       user to determine the return type.  It gets around the problem of the value\r
+       overflowing on 8-bit types without breaking backward compatibility for\r
+       applications that expect an 8-bit return type. */\r
+       configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask )\r
+       {\r
+       TCB_t *pxTCB;\r
+       uint8_t *pucEndOfStack;\r
+       configSTACK_DEPTH_TYPE uxReturn;\r
+\r
+               /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are\r
+               the same except for their return type.  Using configSTACK_DEPTH_TYPE\r
+               allows the user to determine the return type.  It gets around the\r
+               problem of the value overflowing on 8-bit types without breaking\r
+               backward compatibility for applications that expect an 8-bit return\r
+               type. */\r
+\r
+               pxTCB = prvGetTCBFromHandle( xTask );\r
+\r
+               #if portSTACK_GROWTH < 0\r
+               {\r
+                       pucEndOfStack = ( uint8_t * ) pxTCB->pxStack;\r
+               }\r
+               #else\r
+               {\r
+                       pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack;\r
+               }\r
+               #endif\r
+\r
+               uxReturn = prvTaskCheckFreeStackSpace( pucEndOfStack );\r
+\r
+               return uxReturn;\r
+       }\r
+\r
+#endif /* INCLUDE_uxTaskGetStackHighWaterMark2 */\r
 /*-----------------------------------------------------------*/\r
 \r
 #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )\r