FreeRTOS 任务的创建和删除、挂起和恢复

1、创建

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,

const char* const pxName,

const uint16_t usStackDepth,

void* const pvParameters,

UBaseType_t uxPriority,

TaskHandle_t* const pxCreateTask)

  • 该函数主要用于创建任务,它是以一种动态的方式对任务进行创建。动态任务创建函数创建的任务使用的空间、堆栈大小这些都是由FreeRTOS进行管理的。

参数

说明

pxTaskCode

任务函数

pxName

任务名字,一般用于追踪和调试,任务名字长度不能超过configMAX_TASK_NAME_LEN

usStackDepth

任务堆栈大小

pvParameters

传递给任务的参数

uxPriority

任务优先级

pxCreateTask

任务句柄,任务创建成功以后返回此任务的任务句柄,这个句柄就是任务的任务堆栈

返回值

说明

pdPASS

任务创建成功

errCOULD_NOT_ALLOCATE_ REQUIRED_MEMORY

任务创建失败,堆内存不足在堆内存不足的情况下,需要扩大任务堆栈大小

2、删除

void vTaskDelete(TaskHandle_t xTaskToDelete)

  • 当我们觉得某个任务已经不需要时,可用该函数来删除任务自身或者其他任务,任务一旦被删除之后,所有资源都被回收,后续也不会被调度。

参数

说明

xTaskToDelete

需要被删除的任务句柄

返回值

说明

void

3、挂起

void vTaskSuspend(TaskHandle_t xTaskToSuspend)

将某个任务设置为挂起态,并且进入挂起态的任务永远不会进入运行态

参数

说明

xTaskToSuspend

要挂起的任务的句柄

返回值

说明

void

4、恢复

void vTaskResume(TaskHandle_t xTaskToResume)

  • 将任务从挂起态恢复到就绪态,只能通过函数 vTaskSuspend()设置为挂起态的任务才可以使用 vTaskResume()恢复

参数

说明

xTaskToResume

要恢复的任务的任务句柄

返回值

说明

void

BaseType_t vTaskResumeFromISR(TaskHandle_t xTaskToResume)

  • 此函数是 vTaskResume()的中断版本,用于在中断服务函数中恢复一个挂起态的任务

参数

说明

xTaskToResume

需要被删除的任务句柄

返回值

说明

pdTRUE

恢复运行的任务的任务优先级等于或高于当前正在运行的任务(被中断打断的任务),这意味着在退出中断服务函数以后必须进行一次上下文切换

pdFALSE

恢复运行的任务的任务优先级低于当前正在运行的任务(被中断打断的任务),这意味着在退出中断服务函数以后不需要进行上下文切换

5、实验

5.1、实验设计

  • 创建一个开始任务,在开始任务里面再创建task 1和task 2两个任务后,删除开始任务;

  • task 1运行10次后,挂起task 2;

  • task 1再运行10次后,恢复task 2;

5.2、实验代码

k_task_handle_t task1_handle;                  //task 1 句柄
#define TSK1_PRIO                  3           //task 1 优先级
#define TASK1_STK_SIZE             (1*1024)    //task 1 分配的堆栈大小

k_task_handle_t task2_handle;                  //task 2 句柄
#define TSK2_PRIO                  2           //task 2 优先级
#define TASK2_STK_SIZE             (1*1024)    //task 2 分配的堆栈大小

k_task_handle_t start_task_handle;             //start task 句柄
#define START_TSK_PRIO             1           //start task 优先级
#define START_TSK_STK_SIZE         (1*1024)    //start task 分配的堆栈大小

#define TEST_TIME_QUANTA 100

void task1(void)
{
        uint8_t count = 0;
        uint32_t uwRet;
        while(1)
        {
                count++;
                my_printf("task 1 run %d times!!!\r\n", count);
                
                if(count == 10)
                {
                        uwRet = csi_kernel_task_suspend(task2_handle);   //挂起 task 2
                        if(uwRet != 0)
                        {
                                my_printf("task 2 is suspended return error\r\n");
                        }
                        else 
                        {
                                my_printf("task 2 is suspended\r\n");
                        }
                }
                else if(count == 20)
                {
                        uwRet = csi_kernel_task_resume(task2_handle);   //恢复 task 2
                        if(uwRet != 0)  
                        {
                                my_printf("task 2 is resumed return error\r\n");
                        }
                        else 
                        {
                                my_printf("task 2 is resumed\r\n");
                        }
                        
                        count = 0;
                }
                else;
       
                csi_kernel_delay_ms(1000);
        }
}

void task2(void)
{
        
        while(1)
        {
                my_printf("task 2 is working now!!!\r\n");
                csi_kernel_delay_ms(1000);
        }          
}

void start_task(void)
{
    //进入临界区
    taskENTER_CRITICAL();           

    //创建task 1
    csi_kernel_task_new((k_task_entry_t)task1, 
                                     "task1", 
                                       NULL, 
                                  TSK1_PRIO, 
                           TEST_TIME_QUANTA, 
                                       NULL, 
                             TASK1_STK_SIZE, 
                               &task1_handle);

    if (task1_handle == NULL) 
    {
        csi_kernel_sched_resume(0);
        my_printf("Fail to create task 1!\r\n");
    }

    //创建task 2
    csi_kernel_task_new((k_task_entry_t)task2, 
                                     "task2", 
                                         NULL, 
                                    TSK2_PRIO, 
                             TEST_TIME_QUANTA, 
                                         NULL, 
                               TASK2_STK_SIZE, 
                               &task2_handle);

    if (task2_handle == NULL) 
    {
        csi_kernel_sched_resume(0);
        my_printf("Fail to create task 2!\r\n");
    }

        //删除开始任务
    if(0 != csi_kernel_task_del(csi_kernel_task_get_cur()))
    {
         my_printf("Fail to delete start_task!\r\n");
    }

     //退出临界区
     taskEXIT_CRITICAL();            
}


void freertos_demo(void)
{

    my_printf("\r\n-->this is freertos task test demo!!!\r\n");  
    //系统初始化
    csi_kernel_init();

    //创建开始任务
    csi_kernel_task_new((k_task_entry_t)start_task, 
                                      "start_task", 
                                                 0, 
                                    START_TSK_PRIO, 
                                                 0, 
                                                 0, 
                                START_TSK_STK_SIZE, 
                               &start_task_handle);

    //任务调度开始
    csi_kernel_start();
}

实验现象

  • start task在创建后,创建好task 1 task 2即被删除

  • 初始阶段task 1, task 2并发运行

  • task 1运行10次后,挂起task 2。只有task 1在运行

  • task 1再运行10次后,恢复task 2。task 1和task 2又同时运行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值