基于BetaFlight开源代码框架简介的框架设计,逐步分析内部模块功能设计。
栈监测任务
描述:主要了解飞控动态情况下,最大栈使用情况,是否会出现超支导致异常的问题。
├──> 初始化
│ ├──> [x]硬件初始化
│ └──> [x]业务初始化
├──> 任务
│ ├──> [x]实时任务
│ ├──> [x]事件任务
│ └──> [v]时间任务[TASK_STACK_CHECK] = DEFINE_TASK("STACKCHECK", NULL, NULL, taskStackCheck, TASK_PERIOD_HZ(10), TASK_PRIORITY_LOWEST),
├──> 驱动
│ ├──> [x]查询
│ └──> [x]中断
└──> 接口
├──> uint32_t stackUsedSize(void)
├──> uint32_t stackTotalSize(void)
└──> uint32_t stackHighMem(void)
栈检查函数
该代码似乎存在问题,如果是我阅读理解问题,也请指正!
整个工程只有STM32F4DISCOVERY模型用到了这个功能,是否也导致这个问题没有被发现???参见:./src/main/target/STM32F4DISCOVERY/target.h:27:#define USE_STACK_CHECK
分析代码
问题:这个for循环里面p < stackCurrent,感觉不太合理。
- 【1】stackCurrent = (char *)&stackLowMem
- 【2】p是从stackLowMem开始,//p = stackLowMem
- 【3】上面两条的结果是p=stackCurrent,而不会< stackCurrent
- 【4】修改为p < stackHighMem,感觉才是对的
taskStackCheck
├──> stackHighMem = &_estack;
├──> stackSize = (uint32_t)&_Min_Stack_Size;
├──> stackLowMem = stackHighMem - stackSize;
├──> stackCurrent = (char *)&stackLowMem;
├──> for (p = stackLowMem; p < stackCurrent; ++p)
│ └──> <*p != STACK_FILL_CHAR>
│ └──> break;
└──> usedStackSize = (uint32_t)stackHighMem - (uint32_t)p;
源代码
void taskStackCheck(timeUs_t currentTimeUs)
{
UNUSED(currentTimeUs);
char * const stackHighMem = &_estack;
const uint32_t stackSize = (uint32_t)&_Min_Stack_Size;
char * const stackLowMem = stackHighMem - stackSize;
const char * const stackCurrent = (char *)&stackLowMem;
char *p;
for (p = stackLowMem; p < stackCurrent; ++p) {
if (*p != STACK_FILL_CHAR) {
break;
}
}
usedStackSize = (uint32_t)stackHighMem - (uint32_t)p;
DEBUG_SET(DEBUG_STACK, 0, (uint32_t)stackHighMem & 0xffff);
DEBUG_SET(DEBUG_STACK, 1, (uint32_t)stackLowMem & 0xffff);
DEBUG_SET(DEBUG_STACK, 2, (uint32_t)stackCurrent & 0xffff);
DEBUG_SET(DEBUG_STACK, 3, (uint32_t)p & 0xffff);
}
预填充0x5A
STACK_FILL_CHAR=0xa5的源头在于链接脚本。
# vi ./src/link/stm32_flash_f7_split.ld +196
/* User_heap_stack section, used to check that there is enough RAM left */
_heap_stack_end = ORIGIN(STACKRAM)+LENGTH(STACKRAM) - 8; /* 8 bytes to allow for alignment */
_heap_stack_begin = _heap_stack_end - _Min_Stack_Size - _Min_Heap_Size;
. = _heap_stack_begin;
._user_heap_stack :
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
} >STACKRAM = 0xa5