\r
#include "FreeRTOS.h"\r
#include "task.h"\r
+#include "StackMacros.h"\r
\r
/*\r
* Macro to define the amount of stack available to the idle task.\r
portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */\r
signed portCHAR pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */\r
\r
+ #if ( portSTACK_GROWTH > 0 )\r
+ portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */\r
+ #endif\r
+\r
#if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
unsigned portBASE_TYPE uxCriticalNesting;\r
#endif\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
* where NULL is used to indicate that the handle of the currently executing\r
#else\r
{\r
pxTopOfStack = pxNewTCB->pxStack; \r
+\r
+ /* If we want to use stack checking on architectures that use\r
+ a positive stack growth direction then we also need to store the\r
+ other extreme of the stack space. */\r
+ pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );\r
}\r
#endif\r
\r
return;\r
}\r
\r
- taskCHECK_FOR_STACK_OVERFLOW();\r
+ taskFIRST_CHECK_FOR_STACK_OVERFLOW();\r
+ taskSECOND_CHECK_FOR_STACK_OVERFLOW();\r
\r
/* Find the highest priority queue that contains ready tasks. */\r
while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )\r
#endif\r
/*-----------------------------------------------------------*/\r
\r
-#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )\r
\r
unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR * pucStackByte )\r
{\r
unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask )\r
{\r
tskTCB *pxTCB;\r
+ unsigned portCHAR *pcEndOfStack;\r
\r
pxTCB = prvGetTCBFromHandle( xTask );\r
- return usTaskCheckFreeStackSpace( ( unsigned portCHAR * ) pxTCB->pxStack );\r
+\r
+ #if portSTACK_GROWTH < 0\r
+ {\r
+ pcEndOfStack = ( unsigned portCHAR * ) pxTCB->pxStack;\r
+ }\r
+ #else\r
+ {\r
+ pcEndOfStack = ( unsigned portCHAR * ) pxTCB->pxEndOfStack;\r
+ }\r
+ #endif\r
+\r
+ return usTaskCheckFreeStackSpace( pcEndOfStack );\r
}\r
\r
#endif\r