]> git.sur5r.net Git - freertos/commitdiff
Modifications to correct behaviour when a task is blocked without specifying a wake...
authorRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sat, 28 Jul 2007 16:33:07 +0000 (16:33 +0000)
committerRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sat, 28 Jul 2007 16:33:07 +0000 (16:33 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@97 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/include/portable.h
Source/include/task.h
Source/tasks.c

index 06f290a719e6bca9ddb3b89643e7020028000276..04c8ec1e5bffbc722727a28980a5475b2ce479a3 100644 (file)
        #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"\r
 #endif\r
 \r
+#ifdef GCC_ARM7_ECLIPSE\r
+       #include "portmacro.h"\r
+#endif\r
+\r
 #ifdef ROWLEY_LPC23xx\r
        #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"\r
 #endif\r
index 888fe855c2287adfdc4d6ffa69e6b4296113126a..7a857f3ba2f130db2a73b8aec3c36df1e68b69f5 100644 (file)
        ***************************************************************************\r
 */\r
 \r
+/*\r
+Changes since V4.3.1:\r
+\r
+       + Added xTaskGetSchedulerState() function.\r
+*/\r
+\r
 #ifndef TASK_H\r
 #define TASK_H\r
 \r
@@ -131,6 +137,10 @@ typedef struct xTIME_OUT
  */\r
 #define taskENABLE_INTERRUPTS()                portENABLE_INTERRUPTS()\r
 \r
+/* Definitions returned by xTaskGetSchedulerState(). */\r
+#define taskSCHEDULER_NOT_STARTED      0\r
+#define taskSCHEDULER_RUNNING          1\r
+#define taskSCHEDULER_SUSPENDED                2\r
 \r
 /*-----------------------------------------------------------\r
  * TASK CREATION API\r
@@ -940,7 +950,7 @@ void vTaskSetTimeOutState( xTimeOutType *pxTimeOut );
  * Compare the time status now with that previously captured to see if the\r
  * timeout has expired.\r
  */\r
-portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType *pxTimeOut, portTickType *pxTicksToWait );\r
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType *pxTimeOut, portTickType * const pxTicksToWait );\r
 \r
 /*\r
  * Shortcut used by the queue implementation to prevent unnecessary call to\r
@@ -948,6 +958,12 @@ portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType *pxTimeOut, portTickType *pxTic
  */\r
 void vTaskMissedYield( void );\r
 \r
+/*\r
+ * Returns the scheduler state as taskSCHEDULER_RUNNING,\r
+ * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED.\r
+ */\r
+portBASE_TYPE xTaskGetSchedulerState( void );\r
+\r
 #endif /* TASK_H */\r
 \r
 \r
index 76b3d3c3c979e1bdade367156841e41afcf5c0f9..4e1261747f968a7194ef5f712be8009d8060f590 100644 (file)
@@ -196,6 +196,16 @@ Changes from V4.1.3
        + Very small change made to xTaskCheckForTimeout() as a result of the \r
        SafeRTOS testing.  This corrects the case where the function can return an\r
        invalid value - but only in an extremely unlikely scenario.\r
+\r
+Changes since V4.3.1:\r
+\r
+       + Added xTaskGetSchedulerState() function.\r
+       + Added prvIsTaskSuspended() to take into account the Occurrence of\r
+         vTaskResume() or vTaskResumeFromISR() being called passing in the\r
+         handle of a task that appears in the Suspended list only because it\r
+         is blocked on an event without a timeout being specified.\r
+       + Updated xTaskCheckForTimeout() to take into account that tasks blocked\r
+         using the Suspended list should never time out.\r
 */\r
 \r
 #include <stdio.h>\r
@@ -234,7 +244,11 @@ Changes from V4.1.3
 \r
 #ifndef INCLUDE_xTaskResumeFromISR\r
        #define INCLUDE_xTaskResumeFromISR 1\r
-#endif \r
+#endif\r
+\r
+#ifndef INCLUDE_xTaskGetSchedulerState\r
+       #define INCLUDE_xTaskGetSchedulerState 0\r
+#endif\r
 \r
 /*\r
  * Task control block.  A task control block (TCB) is allocated to each task,\r
@@ -486,6 +500,16 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
 \r
 #endif\r
 \r
+/*\r
+ * Checks that a task being resumed (unsuspended) is actually in the Suspended\r
+ * state.\r
+ */\r
+#if ( INCLUDE_vTaskSuspend == 1 )\r
+\r
+       static portBASE_TYPE prvIsTaskSuspended( const tskTCB * const pxTCB );  \r
+\r
+#endif\r
+\r
 /*lint +e956 */\r
 \r
 \r
@@ -936,11 +960,41 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
 #endif\r
 /*-----------------------------------------------------------*/\r
 \r
+#if ( INCLUDE_vTaskSuspend == 1 )\r
+\r
+       static portBASE_TYPE prvIsTaskSuspended( const tskTCB * const pxTCB )\r
+       {\r
+       portBASE_TYPE xReturn = pdFALSE;\r
+\r
+               /* Is the task we are attempting to resume actually in the\r
+               suspended list? */\r
+               if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+               {\r
+                       /* Has the task already been resumed from within an ISR? */\r
+                       if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )\r
+                       {                       \r
+                               /* Is it in the suspended list because it is in the\r
+                               Suspended state?  It is possible to be in the suspended\r
+                               list because it is blocked on a task with no timeout\r
+                               specified. */\r
+                               if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdTRUE )\r
+                               {\r
+                                       xReturn = pdTRUE;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               return xReturn;\r
+       }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
 #if ( INCLUDE_vTaskSuspend == 1 )\r
 \r
        void vTaskResume( xTaskHandle pxTaskToResume )\r
        {\r
-       tskTCB *pxTCB;\r
+       const tskTCB *pxTCB;\r
 \r
                /* Remove the task from whichever list it is currently in, and place\r
                it in the ready list. */\r
@@ -952,24 +1006,19 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                {\r
                        taskENTER_CRITICAL();\r
                        {\r
-                               /* Is the task we are attempting to resume actually suspended? */\r
-                               if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+                               if( prvIsTaskSuspended( pxTCB ) == pdTRUE )\r
                                {\r
-                                       /* Has the task already been resumed from within an ISR? */\r
-                                       if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )\r
-                                       {                       \r
-                                               /* As we are in a critical section we can access the ready \r
-                                               lists even if the scheduler is suspended. */\r
-                                               vListRemove(  &( pxTCB->xGenericListItem ) );\r
-                                               prvAddTaskToReadyQueue( pxTCB );\r
-\r
-                                               /* We may have just resumed a higher priority task. */\r
-                                               if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
-                                               {\r
-                                                       /* This yield may not cause the task just resumed to run, but\r
-                                                       will leave the lists in the correct state for the next yield. */\r
-                                                       taskYIELD();\r
-                                               }\r
+                                       /* As we are in a critical section we can access the ready\r
+                                       lists even if the scheduler is suspended. */\r
+                                       vListRemove(  &( pxTCB->xGenericListItem ) );\r
+                                       prvAddTaskToReadyQueue( pxTCB );\r
+\r
+                                       /* We may have just resumed a higher priority task. */\r
+                                       if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
+                                       {\r
+                                               /* This yield may not cause the task just resumed to run, but\r
+                                               will leave the lists in the correct state for the next yield. */\r
+                                               taskYIELD();\r
                                        }\r
                                }\r
                        }\r
@@ -986,29 +1035,24 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
        portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume )\r
        {\r
        portBASE_TYPE xYieldRequired = pdFALSE;\r
-       tskTCB *pxTCB;\r
+       const tskTCB *pxTCB;\r
 \r
                pxTCB = ( tskTCB * ) pxTaskToResume;\r
 \r
-               /* Is the task we are attempting to resume actually suspended? */\r
-               if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+               if( prvIsTaskSuspended( pxTCB ) == pdTRUE )\r
                {\r
-                       /* Has the task already been resumed from within an ISR? */\r
-                       if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )\r
+                       if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\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 preformed if necessary. */\r
-                                       vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );\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 preformed if necessary. */\r
+                               vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );\r
                        }\r
                }\r
 \r
@@ -1385,14 +1429,6 @@ inline void vTaskIncrementTick( void )
 \r
                        prvDeleteTCB( ( tskTCB * ) pxTCB );\r
                }               \r
-\r
-               while( !listLIST_IS_EMPTY( &xPendingReadyList ) )\r
-               {\r
-                       listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xPendingReadyList );\r
-                       vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );\r
-\r
-                       prvDeleteTCB( ( tskTCB * ) pxTCB );\r
-               }               \r
        }\r
 \r
 #endif\r
@@ -1545,13 +1581,24 @@ void vTaskSetTimeOutState( xTimeOutType *pxTimeOut )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType *pxTimeOut, portTickType *pxTicksToWait )\r
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType *pxTimeOut, portTickType * const pxTicksToWait )\r
 {\r
 portBASE_TYPE xReturn;\r
 \r
+       #if ( INCLUDE_vTaskSuspend == 1 )\r
+               /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is\r
+               the maximum block time then the task should block indefinitely, and\r
+               therefore never time out. */\r
+               if( *pxTicksToWait == portMAX_DELAY )\r
+               {\r
+                       xReturn = pdFALSE;\r
+               }\r
+               else /* We are not blocking indefinitely, perform the checks below. */\r
+       #endif\r
+\r
     if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xTickCount >= pxTimeOut->xTimeOnEntering ) )\r
     {\r
-        /* The tick count is greater than the time at which vTaskSetTimeout() \r
+        /* The tick count is greater than the time at which vTaskSetTimeout()\r
                was called, but has also overflowed since vTaskSetTimeOut() was called.\r
         It must have wrapped all the way around and gone past us again. This\r
         passed since vTaskSetTimeout() was called. */\r
@@ -1857,7 +1904,33 @@ tskTCB *pxNewTCB;
 \r
 #endif\r
 \r
+/*-----------------------------------------------------------*/\r
 \r
+#if ( INCLUDE_xTaskGetSchedulerState == 1 )\r
 \r
+       portBASE_TYPE xTaskGetSchedulerState( void )\r
+       {\r
+       portBASE_TYPE xReturn;\r
+       \r
+               if( xSchedulerRunning == pdFALSE )\r
+               {\r
+                       xReturn = taskSCHEDULER_NOT_STARTED;\r
+               }\r
+               else\r
+               {\r
+                       if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
+                       {\r
+                               xReturn = taskSCHEDULER_RUNNING;\r
+                       }\r
+                       else\r
+                       {\r
+                               xReturn = taskSCHEDULER_SUSPENDED;\r
+                       }\r
+               }\r
+               \r
+               return xReturn;\r
+       }\r
+\r
+#endif\r
 \r
 \r