当前位置:首页 > 公众号精选 > strongerHuang
[导读]用静态局部变量,还是临时变量,要牵涉到你项目具体情况,比如:RAM资源、代码运行效率等。(临时变量还会有一个数据拷贝过程)所以,该如何分配堆栈,该用静态还是临时变量,需要综合考虑你项目的情况而定。

有小伙伴问了这样的问题:我有个任务中的代码量很多,是不是这个任务的堆栈需要分配很大才行?


其实,并不是代码量越大,就分配更多堆栈空间,主要取决于你任务中包含的“临时变量”。


1RTOS任务堆栈分配

市面上很多RTOS的任务都是需要提前分配堆栈大小,也就是在创建任务的时候分配好堆栈的大小。
比如uCOS创建一个检测(Check)任务:
// 任务优先级#define TASK_CHECK_PRIO                        6 // 任务堆栈大小#define TASK_CHECK_STK_SIZE                    128 // 堆栈OS_STK TaskCheckStk[TASK_CHECK_STK_SIZE]; // 创建任务 - 信号检测OSTaskCreateExt((void (*)(void *)) AppTaskCheck, (void           *) 0, (OS_STK         *)&TaskCheckStk[TASK_CHECK_STK_SIZE-1], (INT8U           ) TASK_CHECK_PRIO, (INT16U          ) TASK_CHECK_PRIO, (OS_STK         *)&TaskCheckStk[0], (INT32U          ) TASK_CHECK_STK_SIZE, (void           *) 0, (INT16U          )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR)); // 任务应用实现void AppTaskCheck(void *p_arg){ // 代码···  (void)p_arg;  for(;;) { // 代码··· }}

FreeRRTOS创建一个任务类似,也是在创建时分配堆栈大小:
#define TASK_CHECK_PRIO                        6#define TASK_CHECK_STK_SIZE                    128 BaseType_t xReturn; xReturn = xTaskCreate(AppTaskCheck, "AppTaskCheck", TASK_CHECK_STK_SIZE, NULL, TASK_CHECK_PRIO, NULL);

除了堆栈,其实还有像消息队列、消息邮箱等也是需要提前分配堆栈。
比如FreeRTOS创建CLI消息队列:
#define CLI_QUEUE_NUM             256 //CLI接收队列数#define CLI_PACKAGE_LEN           2 //CLI数据包长度 QueueHandle_t xCLIRcvQueue = NULL; /* 创建队列 */if(xCLIRcvQueue == NULL){ xCLIRcvQueue = xQueueCreate(CLI_QUEUE_NUM, CLI_PACKAGE_LEN);}

这就是创建任务(或队列)的分配堆栈,至于具体分配多少,与你实际情况有关,下面章节我会描述。


2任务代码量

一个任务的代码量,就是你任务中调用的那些代码。
比如上面例子中的代码:
// 任务应用实现void AppTaskCheck(void *p_arg){ // 代码···  (void)p_arg;  for(;;) { // 代码··· }}


这里可能写了几千行代码,或者调用了上百个函数,每个函数里面都有不少代码。


这样下来,这一个任务的代码量就很大了。


3任务代码量和堆栈大小有关系吗?

很多人就存在一个疑惑:任务挂起,要在堆栈中临时保存任务,如果这个任务的代码量很大,是不需要很大堆栈空间才行?


答案:不一定需要很大堆栈空间,任务代码量和堆栈也没有直接关系。


可能很多初学者存在这么一个误区:保存一个任务,就是把这个任务所有代码都保存起来(在堆栈中)。


堆栈主要保存是这个任务自身的变量(控制块),还有临时变量等这些关键变量信息,而并非要保存所有代码。


4堆栈分配多大才合适?

任务堆栈大小,主要取决于你任务中【临时变量】的多少。
注意:临时变量包含你代码中所有嵌套函数中的临时变量。

对于RAM资源相对较大的处理器,你可以尽量分配多一点堆栈资源。
但是,很多时候,我们的RAM资源都是相对比较紧张的。这个时候,就需要你综合平衡。
比如静态局部变量:
void AppTaskCheck(void *p_arg){ static uint8_t aaa; //静态局部变量  (void)p_arg;  for(;;) { // 代码··· }}

这里的aaa变量就不会占用该任务的堆栈空间,但是它会占用全局变量(RAM)空间。

用静态局部变量,还是临时变量,要牵涉到你项目具体情况,比如:RAM资源、代码运行效率等。(临时变量还会有一个数据拷贝过程)
所以,该如何分配堆栈,该用静态还是临时变量,需要综合考虑你项目的情况而定。
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

C语言是一种高级程序设计语言,它提供了十分完备的规范化流程控制结构。因此采用C51语言设计单片机应用系统程序时,首先要尽可能地采用结构化的程序设计方法,这样可使整个应用系统程序结构清晰,易于调试和维护。对于一个较大的程序...

关键字: C51语言 变量 存储

2020年11月3-5日,首届慕尼黑华南电子展(electronica South China)登陆深圳国际会展中心(宝安新馆)。慕尼黑华南电子展立足粤港澳大湾区,辐射华南、西南及东南亚市场,聚焦5G、物联网、蓝牙技术、...

关键字: 电子行业 海尔曼太通 项目

最近一个引起广泛劳苦群众共鸣的话题是“996.ICU”。此话题源自Github前不久出现的一个非常火爆的项目。996.ICU的代码仓库从26号开始建立,只用了两天时间就超过了大名鼎鼎linux的一半。截止发稿,这个项目的...

关键字: Github 项目 代码

定义一个变量,就是在内存中为你定义的这个变量开辟一段内存空间,如果这个变量没有初始化,那么系统会随机给这个变量赋一个值,这个值我一般称它为"垃圾数"。没有初始化的变量我认为它是没有意义的,是在浪费内存,就比如人刚出生的时...

关键字: 变量 初始化 赋值

大家好,我是杂烩君。嵌入式大杂烩周记主要是一些实用项目学习分享,每篇一个主题。SDS 是 C 的字符串库,旨在通过添加堆分配的字符串来增强有限的 libc 字符串处理功能。

关键字: 嵌入式 项目 字符串

个人感觉,如果是一直在小公司,那相当于是泥腿子出身,小公司的产品开发流程并不健全,产品的质量保障可能更多的取决于个人能力,流程上缺少了环节虽然可以让项目跑得更快,但是可能会出问题。对于出问题比较多的地方,可以看看这本书,...

关键字: 小公司 产品 项目

字节的新人培养一直是个迷,有的实习生入职前就会有 mentor(导师)联系,一对一交流。而有的实习生入职,没有 mentor,Leader 对新人唯一的交流就是帮他找到工位。

关键字: 实习生 导师 项目

现在网上有很多播放量巨高的免费编程项目教程,很多学编程的同学可能都看过,就导致大家可能写在简历上的内容都差不多。

关键字: 项目 编程 简历

流水账式的推文比较乱,不够系统,也形成不了好的宣传效应,所以我整理了一个硬件基础知识框架,后面推文会围绕这个展开,中间也会穿插一些项目和实际应用例程。

关键字: 硬件 项目 例程

在C语言中,按照生命周期来分,变量只有两类:静态变量和动态变量。

关键字: C语言 变量
关闭