3

Rtos 任务堆栈大小与代码量有关吗?

 2 years ago
source link: https://www.51cto.com/article/717100.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Rtos 任务堆栈大小与代码量有关吗?

作者:strongerHuang 2022-08-26 01:25:20
有小伙伴问了这样的问题:我有个任务中的代码量很多,是不是这个任务的堆栈需要分配很大才行?

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

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

1.RTOS任务堆栈分配

市面上很多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资源、代码运行效率等。(临时变量还会有一个数据拷贝过程)所以,该如何分配堆栈,该用静态还是临时变量,需要综合考虑你项目的情况而定。​

责任编辑:武晓燕 来源: strongerHuang

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK