1 /* 2 * FreeRTOS Kernel V10.4.3 3 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 * this software and associated documentation files (the "Software"), to deal in 7 * the Software without restriction, including without limitation the rights to 8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 * the Software, and to permit persons to whom the Software is furnished to do so, 10 * subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in all 13 * copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * https://www.FreeRTOS.org 23 * https://github.com/FreeRTOS 24 * 25 */ 26 27 #ifndef STACK_MACROS_H 28 #define STACK_MACROS_H 29 30 /* 31 * Call the stack overflow hook function if the stack of the task being swapped 32 * out is currently overflowed, or looks like it might have overflowed in the 33 * past. 34 * 35 * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check 36 * the current stack state only - comparing the current top of stack value to 37 * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 38 * will also cause the last few stack bytes to be checked to ensure the value 39 * to which the bytes were set when the task was created have not been 40 * overwritten. Note this second test does not guarantee that an overflowed 41 * stack will always be recognised. 42 */ 43 44 /*-----------------------------------------------------------*/ 45 46 #if( configCHECK_FOR_STACK_OVERFLOW == 0 ) 47 48 /* FreeRTOSConfig.h is not set to check for stack overflows. */ 49 #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() 50 #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() 51 52 #endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */ 53 /*-----------------------------------------------------------*/ 54 55 #if( configCHECK_FOR_STACK_OVERFLOW == 1 ) 56 57 /* FreeRTOSConfig.h is only set to use the first method of 58 overflow checking. */ 59 #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() 60 61 #endif 62 /*-----------------------------------------------------------*/ 63 64 #if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) ) 65 66 /* Only the current stack state is to be checked. */ 67 #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \ 68 { \ 69 /* Is the currently saved stack pointer within the stack limit? */ \ 70 if( pxCurrentTCB[ xPortGetCoreID() ]->pxTopOfStack <= pxCurrentTCB[ xPortGetCoreID() ]->pxStack ) \ 71 { \ 72 vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB[ xPortGetCoreID() ], pxCurrentTCB[ xPortGetCoreID() ]->pcTaskName ); \ 73 } \ 74 } 75 76 #endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */ 77 /*-----------------------------------------------------------*/ 78 79 #if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) ) 80 81 /* Only the current stack state is to be checked. */ 82 #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \ 83 { \ 84 \ 85 /* Is the currently saved stack pointer within the stack limit? */ \ 86 if( pxCurrentTCB[ xPortGetCoreID() ]->pxTopOfStack >= pxCurrentTCB[ xPortGetCoreID() ]->pxEndOfStack ) \ 87 { \ 88 vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB[ xPortGetCoreID() ], pxCurrentTCB[ xPortGetCoreID() ]->pcTaskName ); \ 89 } \ 90 } 91 92 #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 93 /*-----------------------------------------------------------*/ 94 95 #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) 96 97 #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ 98 { \ 99 static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 100 tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 101 tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 102 tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 103 tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ 104 \ 105 \ 106 /* Has the extremity of the task stack ever been written over? */ \ 107 if( memcmp( ( void * ) pxCurrentTCB[ xPortGetCoreID() ]->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ 108 { \ 109 vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB[ xPortGetCoreID() ], pxCurrentTCB[ xPortGetCoreID() ]->pcTaskName ); \ 110 } \ 111 } 112 113 #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 114 /*-----------------------------------------------------------*/ 115 116 #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) 117 118 #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ 119 { \ 120 int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB[ xPortGetCoreID() ]->pxEndOfStack; \ 121 static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 122 tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 123 tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 124 tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 125 tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ 126 \ 127 \ 128 pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ 129 \ 130 /* Has the extremity of the task stack ever been written over? */ \ 131 if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ 132 { \ 133 vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB[ xPortGetCoreID() ], pxCurrentTCB[ xPortGetCoreID() ]->pcTaskName ); \ 134 } \ 135 } 136 137 #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 138 139 #endif /* STACK_MACROS_H */ 140