BetaFlight模块设计之五:最大栈使用量监测

BetaFlight模块设计之五:最大栈使用量监测

  • 栈监测任务
    • 栈检查函数
      • 分析代码
      • 源代码
    • 预填充0x5A

基于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

你可能感兴趣的:(飞控,c,stm32,mcu)