当前位置: 首页 > 科技观察

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

时间:2023-03-16 00:19:33 科技观察

有朋友问了这个问题:我有一个任务,代码量很大。是不是说这个任务的栈需要分配很多?其实并不是代码量越大分配的栈空间就越大,主要是看你任务中包含的“临时变量”。1、RTOS任务栈分配市面上很多RTOS任务都需要提前分配栈大小,即在创建任务时分配栈大小。例如uCOS创建一个检查任务://任务优先级#defineTASK_CHECK_PRIO6//任务堆栈大小#defineTASK_CHECK_STK_SIZE128//堆栈OS_STKTaskCheckStk[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_SIZvoid*)0,(INT16U)(OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR));//任务应用实现voidAppTaskCheck(void*p_arg){//代码···(void)p_arg;for(;;){//代码··}}FreeRRTOS创建任务类似,创建时同样分配栈大小:#defineTASK_CHECK_PRIO6#defineTASK_CHECK_STK_SIZE128BaseType_txReturn;xReturn=xTaskCreate(AppTaskCheck,“AppTaskCheck”,TASK_CHECK_STK_SIZE,NULL,TASK_CHECK_PRIO,NULL);除了栈之外,还有消息队列、消息邮箱等需要提前分配。例如,FreeRTOS创建一个CLI消息队列:#defineCLI_QUEUE_NUM256//CLI接收队列号#defineCLI_PACKAGE_LEN2//CLI数据包长度QueueHandle_txCLIRcvQueue=NULL;/*创建队列*/if(xCLIRcvQueue==NULL){xCLIRcvQueue=xQueueCreate(CLI_QUEUE_NUM,CLI_PACKAGE_LEN);}这是创建任务(或队列)的分配栈,至于分配多少,看你的实际情况,我会在后面的章节中介绍。2.任务代码量一个任务的代码量就是你的任务调用的代码量。比如上例中的代码://TaskapplicationimplementationvoidAppTaskCheck(void*p_arg){//Code···(void)p_arg;for(;;){//代码···}}这里可能会写几千行代码,或者调用上百个函数,每个函数都包含很多代码。这样一来,这个任务的代码量就非常大了。3、任务代码量和栈大小有关系吗?很多人都有一个疑问:当一个任务被挂起时,需要把这个任务暂时保存在栈中。如果这个任务的代码量很大,是否需要很大的栈空间?答:不一定需要很大的栈空间,任务代码量与栈没有直接关系。很多初学者可能有这样一个误区:保存一个任务就是保存这个任务的所有代码(在栈中)。栈主要保存任务本身的变量(控制块),以及临时变量等关键变量信息,而不是保存所有代码。4堆栈分配有多大?任务栈的大小主要取决于你任务中[临时变量]的数量。注意:临时变量包括代码中所有嵌套函数中的临时变量。对于RAM资源比较大的处理器,可以尝试多分配一点堆栈资源。然而,很多时候,我们的RAM资源是比较紧张的。这时候就需要综合平衡。例如静态局部变量:voidAppTaskCheck(void*p_arg){staticuint8_taaa;//静态局部变量(void)p_arg;for(;;){//code}}这里的aaa变量不会占用任务的栈空间,但是会占用全局变量(RAM)空间。使用静态局部变量还是临时变量取决于你项目的具体情况,比如:RAM资源,代码运行效率等。(临时变量也会有数据拷贝的过??程)因此,栈如何分配,是否使用静态变量还是临时变量,需要根据自己项目的情况综合考虑。