嵌入式技术william hill官网
直播中

青sky

8年用户 1240经验值
擅长:模拟技术
私信 关注
[问答]

list_thread显示的栈空间不准怎么解决

代码如下,就是先打印一下任务信息,调用函数,再打印任务信息

extern long list_thread(void);
void test(void)
{
rt_uint8_t array[256] = {0};
rt_memcpy(array,"goodbadtool",12);
list_thread();
}
void screen_fresh(void *parameter)
{
uint16_t i,j;
RUN_PAGE = 1;
while (1)
{
list_thread();
test();
#if 1
rt_event_send(&feed_dog_event, EVENT_FLAG1);

此时任务栈指针是0x46,十进制70,1023-70=953 此时栈顶应该在堆栈数组953这里吧

最大使用是43%,但是sp是在0x46也不符合43%的比例

1.jpg

但是看着不像啊

1.jpg

然后调用函数,在函数里局部变量,显示用了66%,sp是0x2ae 686,除法结果是0.6699,这个算准吧

查看keil,发现字符串是从下标762开始的,我只是申请了256个字节是数组,结果sp变化了686-70=616这么多,为什么会是从762开始呢?

另外,list_thread这个功能不是显示最大的栈使用率,随着程序的进行,它会变,那用list_thread看栈使用率的时候,会不会输入命令的时刻,占用率低,感觉没问题,然后下一秒到一个分支里,一个大的局部变量数组,导致栈不够用呢,用这个阵容率来设置任务栈的空间大小,会不会有问题

回帖(3)

李芳

2022-10-20 10:48:10
以STM32的满递减栈为例,如下图所示,
1.jpg


栈初始化时,所有格子都是绿色的,内容被初始化为0x23, 即’#’。
线程调用函数,thread->sp减小,向低地址生长;调用函数结束,thread->sp增大,向高地址方向生长。
打印时,显示的sp的计算公式是:
thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp)
显然,thread->stack_addr - thread->sp是个负数。
你可以按照(thread->stack_size +thread->stack_addr) - thread->sp来进行理解,所以,sp就相当于线程指针thread->sp距离线程栈栈底的距离,是一个相对量。
至于max used部分,就是从stack_addr处递增,直到找到的数据不是0x23为止,即图中的ptr处,表示线程栈指针thread->sp曾经最多用到了此处。
所以计算公式是:

(thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100
/ thread->stack_size
结论:
max used表示栈曾经最多被用到的百分比,sp只是线程在当前时刻的栈占用情况。不能直接根据sp来推断max used。我在开发中,一般max used在70%左右可以接受,适当留些余量。
举报

李英

2022-10-20 10:48:18
sp是当前线程栈指针的位置,线程创建时会把所有的线程栈空间初始化成0x23, max_used是根据栈空间的使用情况计算的。

ptr = (rt_uint8_t *)thread->stack_addr;
while (*ptr == '#')ptr ++;
举报

青sky

2022-10-20 10:48:33
像我这个就不准了,调用test函数前和调用test函数后,最大占用的半分比不一样
举报

更多回帖

发帖
×
20
完善资料,
赚取积分