/*\r
- FreeRTOS.org V4.7.2 - Copyright (C) 2003-2008 Richard Barry.\r
+ FreeRTOS.org V4.8.0 - Copyright (C) 2003-2008 Richard Barry.\r
\r
This file is part of the FreeRTOS.org distribution.\r
\r
of http://www.FreeRTOS.org for full details of how and when the exception\r
can be applied.\r
\r
+ ***************************************************************************\r
+ ***************************************************************************\r
+ * *\r
+ * SAVE TIME AND MONEY! Why not get us to quote to get FreeRTOS.org *\r
+ * running on your hardware - or even write all or part of your application*\r
+ * for you? See http://www.OpenRTOS.com for details. *\r
+ * *\r
+ ***************************************************************************\r
***************************************************************************\r
\r
- Please ensure to read the configuration and relevant port sections of the \r
+ Please ensure to read the configuration and relevant port sections of the\r
online documentation.\r
\r
- +++ http://www.FreeRTOS.org +++\r
- Documentation, latest information, license and contact details. \r
-\r
- +++ http://www.SafeRTOS.com +++\r
- A version that is certified for use in safety critical systems.\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and \r
+ contact details.\r
\r
- +++ http://www.OpenRTOS.com +++\r
- Commercial support, development, porting, licensing and training services.\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety \r
+ critical systems.\r
\r
- ***************************************************************************\r
+ http://www.OpenRTOS.com - Commercial support, development, porting, \r
+ licensing and training services.\r
*/\r
\r
-/*\r
-Changes from V1.00:\r
- \r
- + Call to portRESTORE_CONTEXT has been removed. The first context\r
- switch is now performed within sPortStartScheduler().\r
-\r
-Changes from V1.01:\r
-\r
- + More use of 8bit data types.\r
- + Function name prefixes changed where the data type returned has changed.\r
- + configUSE_TRACE_FACILITY is no longer defined by default.\r
-\r
-Changes from V1.2.0\r
-\r
- + Introduced ucTopReadyPriority. This tracks the highest priority ready\r
- queue that contains a valid TCB and thus makes the context switch\r
- slightly faster.\r
-\r
- + prvAddTaskToReadyQueue() has been made a macro.\r
-\r
-Changes from V1.2.6\r
-\r
- + Added conditional compilation directives.\r
- + Extended API.\r
- + Rearranged function order.\r
- + Creating a task now causes a context switch if the task being created\r
- has a higher priority than the calling task - assuming the kernel is\r
- running.\r
- + vTaskDelete() now only causes a context switch if the calling task is\r
- the task being deleted.\r
-\r
-Changes from V2.0.0\r
-\r
- + Allow the type of the tick count to be 16 or 32 bits.\r
- + Introduce xPendingReadyList feature to allow the time interrupts have to\r
- be disabled to be minimised.\r
- + Remove the #if( INCLUDE_vTaskSuspendAll ) statements. vTaskSuspendAll()\r
- is now always included as it is used by the scheduler itself.\r
-\r
-Changes from V2.1.0\r
-\r
- + Bug fix - pxCurrentTCB is now initialised before the call to\r
- prvInitializeTaskLists(). Previously pxCurrentTCB could be accessed\r
- while null.\r
-\r
-Changed from V2.1.1\r
-\r
- + Change to where lStackSize is declared within sTaskCreate() to prevent\r
- compiler warnings with 8051 port.\r
-\r
-Changes from V2.2.0\r
-\r
- + Explicit use of 'signed' qualifier on portCHAR types added.\r
- + Changed odd calculation of initial pxTopOfStack value when\r
- portSTACK_GROWTH < 0.\r
- + Removed pcVersionNumber definition.\r
-\r
-Changes from V2.5.3\r
-\r
- + cTaskResumeAll() modified to ensure it can be called prior to the task\r
- lists being initialised.\r
-\r
-Changes from V2.5.5\r
-\r
- + Added API function vTaskDelayUntil().\r
- + Added INCLUDE_vTaskDelay conditional compilation.\r
-\r
-Changes from V2.6.0\r
-\r
- + Updated the vWriteTraceToBuffer macro to always be 4 byte aligned so it\r
- can be used on ARM architectures.\r
- + tskMAX_TASK_NAME_LEN definition replaced with the port specific\r
- configMAX_TASK_NAME_LEN definition.\r
- + Removed the call to strcpy when copying across the task name into the\r
- TCB.\r
- + Added ucTasksDeleted variable to prevent vTaskSuspendAll() being called\r
- too often in the idle task.\r
-\r
-Changes between V3.0.0 and V2.6.1\r
-\r
- + When resuming the scheduler a yield is performed if either a tick has\r
- been missed, or a task is moved from the pending ready list into a ready\r
- list. Previously a yield was not performed on this second condition.\r
- + Introduced the type portBASE_TYPE. This necessitates several API\r
- changes.\r
- + Removed the sUsingPreemption variable. The constant defined in\r
- portmacro.h is now used directly.\r
- + The idle task can now include an optional hook function - and no longer\r
- completes its time slice if other tasks with equal priority to it are\r
- ready to run.\r
- + See the FreeRTOS.org documentation for more information on V2.x.x to\r
- V3.x.x modifications.\r
-\r
-Changes from V3.1.1\r
-\r
- + Modified vTaskPrioritySet() and vTaskResume() to allow these functions to\r
- be called while the scheduler is suspended.\r
- + Corrected the task ordering within event lists.\r
-\r
-Changes from V3.2.0\r
-\r
- + Added function xTaskGetCurrentTaskHandle().\r
-\r
-Changes from V3.2.4\r
-\r
- + Changed the volatile declarations on some variables to reflect the \r
- changes to the list definitions.\r
- + Changed the order of the TCB definition so there is commonality between\r
- the task control block and a co-routine control block.\r
- + Allow the scheduler to be started even if no tasks other than the idle\r
- task has been created. This allows co-routines to run even when no tasks\r
- have been created.\r
- + The need for a context switch is now signalled if a task woken by an \r
- event has a priority greater or equal to the currently running task.\r
- Previously this was only greater than.\r
-\r
-Changes from V4.0.0\r
-\r
- + Added the xMissedYield handling.\r
-\r
-Changes from V4.0.1\r
-\r
- + The function vTaskList() now suspends the scheduler rather than disabling\r
- interrupts during the creation of the task list. \r
- + Allow a task to delete itself by passing in its own handle. Previously \r
- this could only be done by passing in NULL.\r
- + The tick hook function is now called only within a tick isr. Previously\r
- it was also called when the tick function was called during the scheduler\r
- unlocking process.\r
-\r
-Changes from V4.0.3\r
-\r
- + Extra checks have been placed in vTaskPrioritySet() to avoid unnecessary\r
- yields.\r
-\r
-Changed from V4.0.4\r
-\r
- + Bug fix: The 'value' of the event list item is updated when the priority\r
- of a task is changed. Previously only the priority of the TCB itself was\r
- changed.\r
- + When resuming a task a check is first made to see if the task is actually\r
- suspended.\r
- + vTaskPrioritySet() and vTaskResume() no longer use the event list item.\r
- This has not been necessary since V4.0.1 when the xMissedYield handling\r
- was added.\r
- + Implement xTaskResumeFromISR().\r
-\r
-Changes from V4.0.5\r
-\r
- + Added utility functions and xOverflowCount variable to facilitate the\r
- queue.c changes.\r
-\r
-Changes from V4.1.2\r
- \r
- + Tasks that block on events with a timeout of portMAX_DELAY are now\r
- blocked indefinitely if configINCLUDE_vTaskSuspend is defined. \r
- Previously portMAX_DELAY was just the longest block time possible.\r
-\r
-Changes from V4.1.3\r
-\r
- + 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
#include <stdlib.h>\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
#define vWriteTraceToBuffer()\r
\r
#endif\r
-\r
+/*-----------------------------------------------------------*/\r
\r
/*\r
* Place the task represented by pxTCB into the appropriate ready queue for\r
uxTopReadyPriority = pxTCB->uxPriority; \\r
} \\r
vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ); \\r
-} \r
+}\r
+/*-----------------------------------------------------------*/ \r
\r
/*\r
* Macro that looks at the list of tasks that are currently delayed to see if\r
{ \\r
vListRemove( &( pxTCB->xEventListItem ) ); \\r
} \\r
- prvAddTaskToReadyQueue( pxTCB ); \\r
+ prvAddTaskToReadyQueue( pxTCB ); \\r
} \\r
-} \r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Call the stack overflow hook function if the stack of the task being swapped\r
+ * out is currently overflowed, or looks like it might have overflowed in the\r
+ * past.\r
+ *\r
+ * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check\r
+ * the current stack state only - comparing the current top of stack value to\r
+ * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1\r
+ * will also cause the last few stack bytes to be checked to ensure the value\r
+ * to which the bytes were set when the task was created have not been \r
+ * overwritten. Note this second test does not guarantee that an overflowed\r
+ * stack will always be recognised.\r
+ */\r
+\r
+#if( configCHECK_FOR_STACK_OVERFLOW == 0 )\r
+\r
+ /* FreeRTOSConfig.h is not set to check for stack overflows. */\r
+ #define taskCHECK_FOR_STACK_OVERFLOW()\r
+\r
+#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */\r
+\r
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH >= 0 ) )\r
+\r
+ /* This is an invalid setting. */\r
+ #error configCHECK_FOR_STACK_OVERFLOW can only be set to a non zero value on architectures where the stack grows down from high memory.\r
+\r
+#endif /* ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH >= 0 ) */\r
+\r
+#if( configCHECK_FOR_STACK_OVERFLOW == 1 )\r
+\r
+ /* Only the current stack state is to be checked. */\r
+ #define taskCHECK_FOR_STACK_OVERFLOW() \\r
+ { \\r
+ extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName ); \\r
+ \\r
+ /* Is the currently saved stack pointer within the stack limit? */ \\r
+ if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \\r
+ { \\r
+ vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
+ } \\r
+ }\r
+\r
+#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */\r
+\r
+#if( configCHECK_FOR_STACK_OVERFLOW > 1 )\r
+\r
+ /* Both the current statck state and the stack fill bytes are to be checked. */\r
+ #define taskCHECK_FOR_STACK_OVERFLOW() \\r
+ { \\r
+ extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName ); \\r
+ static const unsigned portCHAR ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \\r
+ \\r
+ /* Is the currently saved stack pointer within the stack limit? */ \\r
+ if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \\r
+ { \\r
+ vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
+ } \\r
+ \\r
+ /* Has the extremity of the task stack ever been written over? */ \\r
+ if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \\r
+ { \\r
+ vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
+ } \\r
+ }\r
+\r
+#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */\r
+\r
+/*-----------------------------------------------------------*/\r
\r
/*\r
* Several functions take an xTaskHandle parameter that can optionally be NULL,\r
* 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_uxGetStackHighWaterMark == 1 ) )\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
\r
unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR * pucStackByte );\r
\r
\r
\r
\r
-\r
-\r
/*-----------------------------------------------------------\r
* TASK CREATION API documented in task.h\r
*----------------------------------------------------------*/\r
\r
taskENTER_CRITICAL();\r
{\r
- /* Ensure a yield is performed if the current task is being \r
+ /* Ensure a yield is performed if the current task is being\r
deleted. */\r
if( pxTaskToDelete == pxCurrentTCB )\r
{\r
taskEXIT_CRITICAL();\r
\r
/* Force a reschedule if we have just deleted the current task. */\r
- if( xSchedulerRunning != pdFALSE ) \r
+ if( xSchedulerRunning != pdFALSE )\r
{\r
if( ( void * ) pxTaskToDelete == NULL )\r
{\r
{\r
/* The priority change may have readied a task of higher\r
priority than the calling task. */\r
- if( uxNewPriority > uxCurrentPriority ) \r
+ if( uxNewPriority > uxCurrentPriority )\r
{\r
if( pxTask != NULL )\r
{\r
\r
taskENTER_CRITICAL();\r
{\r
- /* Ensure a yield is performed if the current task is being \r
+ /* Ensure a yield is performed if the current task is being\r
suspended. */\r
if( pxTaskToSuspend == pxCurrentTCB )\r
{\r
{\r
xList *pxTemp;\r
\r
- /* Tick count has overflowed so we need to swap the delay lists. \r
- If there are any items in pxDelayedTaskList here then there is \r
+ /* Tick count has overflowed so we need to swap the delay lists.\r
+ If there are any items in pxDelayedTaskList here then there is\r
an error! */\r
pxTemp = pxDelayedTaskList;\r
pxDelayedTaskList = pxOverflowDelayedTaskList;\r
{\r
++uxMissedTicks;\r
\r
- /* The tick hook gets called at regular intervals, even if the \r
+ /* The tick hook gets called at regular intervals, even if the\r
scheduler is locked. */\r
#if ( configUSE_TICK_HOOK == 1 )\r
{\r
return;\r
}\r
\r
+ taskCHECK_FOR_STACK_OVERFLOW();\r
+\r
/* Find the highest priority queue that contains ready tasks. */\r
while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )\r
{\r
\r
\r
#if ( INCLUDE_vTaskSuspend == 1 )\r
- { \r
+ { \r
if( xTicksToWait == portMAX_DELAY )\r
{\r
/* Add ourselves to the suspended task list instead of a delayed task\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
+ portENTER_CRITICAL();\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
+ 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
+ xReturn = pdTRUE;\r
+ }\r
+ else if( ( xTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait )\r
{\r
+ /* Not a genuine timeout. Adjust parameters for time remaining. */\r
+ *pxTicksToWait -= ( xTickCount - pxTimeOut->xTimeOnEntering );\r
+ vTaskSetTimeOutState( pxTimeOut );\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
- 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
- xReturn = pdTRUE;\r
- }\r
- else if( ( xTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait )\r
- {\r
- /* Not a genuine timeout. Adjust parameters for time remaining. */\r
- *pxTicksToWait -= ( xTickCount - pxTimeOut->xTimeOnEntering );\r
- vTaskSetTimeOutState( pxTimeOut );\r
- xReturn = pdFALSE;\r
- }\r
- else\r
- {\r
- xReturn = pdTRUE;\r
- }\r
+ else\r
+ {\r
+ xReturn = pdTRUE;\r
+ }\r
+ }\r
+ portEXIT_CRITICAL();\r
\r
return xReturn;\r
}\r
#endif\r
/*-----------------------------------------------------------*/\r
\r
-#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxGetStackHighWaterMark == 1 ) )\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+\r
unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR * pucStackByte )\r
{\r
register unsigned portSHORT usCount = 0;\r
\r
return usCount;\r
}\r
+\r
#endif\r
/*-----------------------------------------------------------*/\r
\r
-#if ( INCLUDE_uxGetStackHighWaterMark == 1 )\r
- unsigned portBASE_TYPE uxGetStackHighWaterMark( void )\r
+#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )\r
+\r
+ unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask )\r
{\r
- return usTaskCheckFreeStackSpace( pxCurrentTCB->pxStack );\r
+ tskTCB *pxTCB;\r
+\r
+ pxTCB = prvGetTCBFromHandle( xTask );\r
+ return usTaskCheckFreeStackSpace( ( unsigned portCHAR * ) pxTCB->pxStack );\r
}\r
+\r
#endif\r
/*-----------------------------------------------------------*/\r
\r