如何利用FreeRTOS的多任务机制优化程序呢?

电子说

1.2w人已加入

描述

1

创建任务

创建任务时使用的函数如下:

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //函数指针,任务函数
const char * const pcName, //任务的名字
const configSTACK_DEPTH_TYPE usStackDepth,//栈大小,单位为word,10表示40字节
void * const pvParameters, //调用任务函数时传入的参数
UBaseType_t uxPriority, //优先级
TaskHandle_t * const pxCreatedTask );//任务句柄,以后使用它来操作这个任务

参数说明:

  • pvTaskCode:函数指针,可以简单地认为任务就是一个C函数。它稍微特殊一点:永远不退出,或者退出时要调用"vTaskDelete(NULL)"
  • pcName:任务的名字,FreeRTOS内部不使用它,仅仅起调试作用。长度为:confifigMAX_TASK_NAME_LEN
  • usStackDepth:每个任务都有自己的栈,这里指定栈大小。单位是 word ,比如传入 100 ,表示栈大小为 100 word ,也就是 400 字节。最大值为 uint16_t 的最大值。怎么确定栈的大小,并不容易,很多时候是估计。精确的办法是看反汇编码。
  • pvParameters:传入参数,调用 pvTaskCode 函数指针时用到:pvTaskCode(pvParameters)
  • uxPriorit:优先级范围:0~(confifigMAX_PRIORITIES – 1) 数值越小优先级越低, 如果传入过大的值,xTaskCreate会把它调整为(confifigMAX_PRIORITIES – 1)
  • pxCreatedTask:用来保存 xTaskCreate 的输出结果:task handle 。以后如果想操作这个任务,比如修改它的优先级,就需要这个 handle 。如果不想使用该 handle ,可以传入 NULL 。
  • 返回值:成功:pdPASS ;失败:errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY( 失败原因只有内存不足 )
  • 注意:文档里都说失败时返回值是 pdFAIL ,这不对。pdFAIL 是 0 , errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY 是 -1 。

实例:

void Task1Function(void * param)
{
  while (1)
  {
    printf("1");
  }
}
void Task2Function(void * param)
{
  while (1)
  {
    printf("2");
  }
}
xTaskCreate(Task1Function, "Task1", 100, NULL, 1, &xHandleTask1);
xTaskCreate(Task2Function, "Task2", 100, NULL, 1, NULL);

开启任务调度:

vTaskStartScheduler();          //开启任务调度

结果:

状态机

2

删除任务

删除任务使用的函数如下:

void vTaskDelete( TaskHandle_t xTaskToDelete );

参数说明:

  • xTaskToDelete:任务句柄,使用 xTaskCreate 创建任务时可以得到一个句柄,也可传入NULL ,这表示删除自己。
  • 句柄的实质就是这个任务结构体的指针,在FreeRTOS中任务的创建利用面向对象的思想,创建的一个个任务都是结构体,删除任务的实质就类似于C语言中的free释放内存

实例:

void vTask1( void *pvParameters )
{
const TickType_t xDelay100ms = pdMS_TO_TICKS( 100UL );
BaseType_t ret; 
/* 任务函数的主体一般都是无限循环 */
for( ;; ) 
{ 
/* 打印任务的信息 */ 
printf("Task1 is runningrn");
ret = xTaskCreate( vTask2, "Task 2", 1000, NULL, 2, &xTask2Handle ); 
if (ret != pdPASS) printf("Create Task2 Failedrn");
// 如果不休眠的话, Idle任务无法得到执行 
// Idel任务会清理任务2使用的内存
// 如果不休眠则Idle任务无法执行, 最后内存耗尽
vTaskDelay( xDelay100ms ); 
}

3

任务状态

  • 当前正在进行的任务,是running状态;其他所有任务都处于not running状态
  • "not running"状态还可以细分为:
    ready :就绪,随时可以运行
    
      blocked :阻塞,该任务在等待某一事件发生
    
      suspended :挂起,该任务暂停休息
    

状态机

当创建任务并开始任务调度后,所有任务都处于Ready就绪状态,系统随机挑选一个任务Running,正在执行的任务可以使用vTaskSuspend函数使自己进入挂起状态(传入参数NULL或自己的句柄),也可以使其他任务进入挂起状态(传入参数为需要挂起任务的句柄),进入暂停状态后,需要在别的任务执行过程中调用vTaskResume函数该任务才会重新进入Ready状态;

在任务执行过程中,需要等待某个函数或事件的发生,则进入挂起状态(Baocked),当等待的事件(可能是中断或某个任务)发生后该任务才会恢复Ready状态。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分