FreeRTOS栈最大剩余深度#
任务在创建时就将其栈内存写入了特定的初始化值 0xA5
检测任务最大入栈的原理是,从栈顶开始按照栈增长方向开始依次检测内存是否为初始化值。
如果是侧继续循环检测;
如果不是侧停止检测,最大剩余空间就是刚刚循环检测的次数。
备注
如果该值越接近于0,哪么该任务就越接近栈溢出
3916#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
3917
3918UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask )
3919{
3920 TCB_t * pxTCB;
3921 uint8_t * pucEndOfStack;
3922 UBaseType_t uxReturn;
3923
3924 pxTCB = prvGetTCBFromHandle( xTask );
3925
3926 #if portSTACK_GROWTH < 0
3927 {
3928 pucEndOfStack = ( uint8_t * ) pxTCB->pxStack;
3929 }
3930 #else
3931 {
3932 pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack;
3933 }
3934 #endif
3935
3936 uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack );
3937
3938 return uxReturn;
3939}
3940
3941#endif /* INCLUDE_uxTaskGetStackHighWaterMark */
3856#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) )
3857
3858static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte )
3859{
3860 uint32_t ulCount = 0U;
3861
3862 while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE )
3863 {
3864 pucStackByte -= portSTACK_GROWTH;
3865 ulCount++;
3866 }
3867
3868 ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */
3869
3870 return ( configSTACK_DEPTH_TYPE ) ulCount;
3871}
3872
3873#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) */
函数 uxTaskGetStackHighWaterMark 将任务控制块的 pxStack
值传给了函数 prvTaskCheckFreeStackSpace
然后 prvTaskCheckFreeStackSpace 沿着内存增长的反方向开始循环检测内存是否为初始化值
循环检测的次数即为最大剩余栈深度。
备注
任务控制(TCB)的 pxStack
记录的是栈顶值吗?