freeRTOS学习 — 任务的创建与管理

1、freeRTOS的任务

(1)任务的状态

        freeRTOS中,任务在运行时,可能出现以下几种状态:

        1)运行态。任务当前正在运行中,占有cpu的使用权。

        2)就绪态。满足了运行条件,但是当前没有运行,可能是有高优先级任务在执行或者在中断,处于等待获得cpu使用权然后运行的状态中。

        3)阻塞态。在某些条件下被阻塞了,不能得到运行。比如等待某些信号量,消息队列或者调用了延迟函数。

        4)挂起态。任务被通过调用挂起操作被终止执行了,直到被从挂起状态中恢复为止,否则将一直处于挂起的状态中。

(2)任务的优先级

        freeRTOS的任务优先级是数值越大,任务的优先级越高。

        freeRTOS 中任务的最高优先级是通过 FreeRTOSConfig.h 文件中的

configMAX_PRIORITIES

        进行配置的,用户实际可以使用的优先级范围是 0 到 configMAX_PRIORITIES – 1。

2、freeRTOS的任务切换的实现

为了说明FreeRTOS的任务切换,以STM32为例:

1)PendSV中断

        freeRTOS系统的任务切换的具体过程最终都是在pendSV中断服务函数里面完成的。

        PendSV是一种不精确的异常处理,优先级和挂起状态可以通过编程实现,一般在实时操作系统中 PendSV 的优先级都会被设置为最低,在其他所有的异常中断处理完以后才执行,对上下文的切换非常有用。

        在freeRTOS系统中,执行上下文切换依靠的是任务调度器。上下文切换被触发的场合可有:

        1> 执行一个系统调用。如:任务切换函数taskYIELD()、延时vTaskDelay()。

        2> Systick中断。

2Systick中断

        Systick中断服务函数中会进行任务切换。

3、freeRTOS的任务管理的API函数


3.1、FreeRTOS任务创建

        在freeRTOS中,可以根据实际使用的需要创建一定数量的任务(线程),任务只有被成功创建了,才有可能被执行到。

        在FreeRTOS实时操作系统中,创建任务可以使用如下的API:

      

portBASE_TYPE xTaskCreate(

         pdTASK_CODE pvTaskCode,

         const char * const pcName,

         unsigned short usStackDepth,

         void *pvParameters,

         unsigned portBASE_TYPE uxPriority,

         xTaskHandle *pvCreatedTask

        );

函数参数说明:

    pvTaskCode:指向任务入口函数的指针。即任务函数。

    pcName:任务的描述。一般都是为了调试方便而使用的。由 tskMAX_TASK_NAME_LEN 定义的最大长度,默认为 16。

    usStackDepth:任务堆栈的大小。不是字节数而是以字为单位。例如,如果堆栈为 16 位宽,并且             usStackDepth 定义为 100,则将分配 200 个字节用于堆栈存储。

    pvParameters:任务的参数的指针。可以向创建的任务中传入参数,不需要传送参数可以选NULL。

    uxPriority:任务运行的优先级。

    pvCreatedTask:任务的句柄,通过该句柄引用创建的任务。

返回值:

    任务创建成功返回 pdPASS;创建失败返回 pdFAIL。

创建一个任务的示例如下:

xTaskCreate((TaskFunction_t )Start_Task,            //任务函数

            (const char*    )"Start_Task",          //任务名称

            (uint16_t       )128,                   //任务堆栈大小

            (void *         )NULL,                  //传递给任务函数的参数

            (UBaseType_t    )5,                     //任务优先级

            (TaskHandle_t * )&StartTask_Handler);   //任务句柄

注意:

        1)任务的优先级要根据 FreeRTOSConfig.h 文件中的

configMAX_PRIORITIES

        进行设置的,可以使用的优先级范围是 0 到 configMAX_PRIORITIES – 1,如果创建的任务所选的任务优先级超过了这个设置的范围,会被忽略掉,不会被执行。

3.2、FreeRTOS任务挂起

        当任务在系统运行过程中,因为某些条件或者有其他的更加重要的事情要做的时候,可以考虑把某些任务先挂起,等候条件到达之后再恢复任务继续调度运行。

        挂起任务的函数为:

void vTaskSuspend( xTaskHandle pxTaskToSuspend )

参数:

    pxTaskToSuspend:需要被挂起的任务的优先级

返回值:无

        要使用这个函数,需要在 FreeRTOSConfig.h中将宏定义 INCLUDE_vTaskSuspend 定义为 1,如下:

         此外,如果要挂起、恢复整个系统所有的任务,freeRTOS也提供了一个API函数,如下:

void vTaskSuspendAll( void )  // 挂起所有的任务

BaseType_t xTaskResumeAll( void ) // 恢复所有被挂起的任务

        要恢复某个被挂起的任务,可以使用函数:

3.3、FreeRTOS任务删除

        如果有某些任务只是需要存在于某些条件,当条件满足之后就不再需要这个任务参与运行,这个时候可以选择删除掉这个任务,释放该任务所占用的堆栈空间。

        删除任务可以使用函数:

void vTaskDelete( xTaskHandle pxTask )

参数:

    pxTask:需要被删除的任务句柄

返回值:无

        注意:要使用这个函数,需要将宏定义 INCLUDE_vTaskDelete  设置为 1 。

4、freeRTOS的内核管理函数

4.1、获取任务的优先级

        如果运行过程中需要知道当前运行的任务的优先级,可以调用优先级获取函数得到任务的优先级:

 unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask )

 参数:

       pxTask:需要获取优先级的任务的句柄。

 返回值:

       句柄对应的任务的优先级。

4.2、修改任务的优先级

任务在运行过程中,优先级希望能被改变成其他的优先级,可以使用函数:

void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority )

参数:

    pxTask:任务的句柄。

    uxNewPriority:需要修改的新的优先级的值。

5、freeRTOS的延时函数

5.1、相对延时函数

void vTaskDelay(const TickType_t TicksToDelay)

5.2、绝对延时函数

void vTaskDelayUntil(TickType_t* const pxPreviousWakeTime,

                 const TickType_t  xTimeIncrement

                    )

 对嵌入式技术感兴趣的欢迎关注“嵌入式之入坑笔记”,一起学习交流吧!

 

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式之入坑笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值