freertos学习笔记2

任务的挂起与恢复

相关API函数:(使用对应函数要去修改宏对应的值)

1.vTaskSuspend(): 挂起任务

2.vTaskResume():恢复任务运行

3.vTaskResumeFromISR():中断服务函数中恢复一个任务的运行

那么问题来了,为什么我们不能像上节那样用删除再创建来控制任务的运行呢?

原因其实很明显,不仅是写代码变得冗杂,而且删除任务这个操作,会把之前任务的堆载删除,然后后面想运行这个任务就找不到了。但是如果只是挂起,它的任务堆载及其数据都是有效的。

我们来链接上一节的代码来完善一下

观前知识拓展:

what is 临界区?

简单来说,临界区是多个访问资源共用的一个程序片段。当某个线程进入时,其他线程需要等待,防止程序因这些共用资源而发生出错。


#define START_TASK_PRIO 1//任务优先级(这里一般不设为0,因为系统开启需要一个空闲函数)
#define START_STK_SIZE  120//任务内存
void start_task(void*pvParameters);//任务函数
TaskHandle_t StartTask_Handler;//任务句柄

#define TASK1_TASK_PRIO 2//任务优先级(这里一般不设为0,因为系统开启需要一个空闲函数)
#define TASK1_STK_SIZE  120//任务内存
void task1_task(void*pvParameters);//任务函数
TaskHandle_t Task1Task_Handler;//任务句柄

#define TASK2_TASK_PRIO 3//任务优先级(这里一般不设为0,因为系统开启需要一个空闲函数)
#define TASK2_STK_SIZE  120//任务内存
void task2_task(void*pvParameters);//任务函数
TaskHandle_t Task2Task_Handler;//任务句柄

int main
{
    xTaskCreate(
    (TaskFunction_t)start_task,
    (char*         )"start_task",
    (uint16_t      )START_STK_SIZE,
    (void*         )NULL,
    (UBaseType_t   )START_TASK_PRIO,
    (TaskHandle_t* )&StartTask_Handler,
);//创建任务环
    vTaskStartScheduler();//开启任务调度
}
void start_task(void*pvParemeters)
{

    taskENTER_CRITICAL();//进入临界区
    //创建任务一
    xTaskCreate((TaskFunction_t)task1_task,
                (char*         )"task1_task",
                (uint16_t      )TASK1_STK_SIZE,
                (void*         )NULL,
                (UBaseType_t   )TASK1_TASK_PRIO,
                (TaskHandle_t* )&Task1Task_Handler,);
    //创建任务二
    xTaskCreate((TaskFunction_t)task2_task,
                (char*         )"task2_task",
                (uint16_t      )TASK2_STK_SIZE,
                (void*         )NULL,
                (UBaseType_t   )TASK2_TASK_PRIO,
                (TaskHandle_t* )&Task2Task_Handler,);
    vTaskDelete(StartTask_Handler);//删除任务,注意要用该任务的任务句柄 
    taskEXIT_CRITICAL(); // 退出临界区    
}

//这里我们写一个识别颜色的程序
void task1_task(void*pvParemeters//这里的意思是动态创建任务函数)
{
    u8 task1_num=0;//系统运行次数,加到255次会清零。
    Read_OpenData();//识别颜色外设(接收openmv的数据)
    //假定读取颜色green正确赋值为一,假定接收五次任务挂起
    while(1)
    {
        if(green==1)
            {
                task1_num++;
                if(task==5)
                    {

                        printf("green")
                        vTaskSuspend();//挂起当前任务
                       }
             }
       }
}


void task2_task(void*pvParemeters//这里的意思是动态创建任务函数
{
    while(1)
    {
    /*写具体的任务*/
    }
}
```

####

接下来我们来引用一下正点原子的设计实验

1.设计实验

(1)本实验设计4个任务:start_task,key_task,task1_task和task2_task

start_task:用来创建其他三个任务。

key_task: 按键服务任务,检测按键的按下结果,根据不同的按键结果执行不同操作

task1_task:应用任务1

task2_task:应用任务2


#define START_TASK_PRIO 1//任务优先级(这里一般不设为0,因为系统开启需要一个空闲函数)
#define START_STK_SIZE  120//任务内存
void start_task(void*pvParameters);//任务函数
TaskHandle_t StartTask_Handler;//任务句柄


#define KEY_TASK_PRIO 2//任务优先级(这里一般不设为0,因为系统开启需要一个空闲函数)
#define KEY_STK_SIZE  120//任务内存
void KEY_task(void*pvParameters);//任务函数
TaskHandle_t KEYTask_Handler;//任务句柄


#define TASK1_TASK_PRIO 3//任务优先级(这里一般不设为0,因为系统开启需要一个空闲函数)
#define TASK1_STK_SIZE  120//任务内存
void task1_task(void*pvParameters);//任务函数
TaskHandle_t Task1Task_Handler;//任务句柄

#define TASK2_TASK_PRIO 4//任务优先级(这里一般不设为0,因为系统开启需要一个空闲函数)
#define TASK2_STK_SIZE  120//任务内存
void task2_task(void*pvParameters);//任务函数
TaskHandle_t Task2Task_Handler;//任务句柄

int main
{
    xTaskCreate(
    (TaskFunction_t)start_task,
    (char*         )"start_task",
    (uint16_t      )START_STK_SIZE,
    (void*         )NULL,
    (UBaseType_t   )START_TASK_PRIO,
    (TaskHandle_t* )&StartTask_Handler,
);//创建任务环
    vTaskStartScheduler();//开启任务调度
}
void start_task(void*pvParemeters)
{

    taskENTER_CRITICAL();//进入临界区

     xTaskCreate((TaskFunction_t)key_task,
                (char*         )"key_task",
                (uint16_t      )KEY_STK_SIZE,
                (void*         )NULL,
                (UBaseType_t   )KEY_TASK_PRIO,
                (TaskHandle_t* )&KEYTask_Handler,);
    //创建任务一
    xTaskCreate((TaskFunction_t)task1_task,
                (char*         )"task1_task",
                (uint16_t      )TASK1_STK_SIZE,
                (void*         )NULL,
                (UBaseType_t   )TASK1_TASK_PRIO,
                (TaskHandle_t* )&TASK1Task_Handler,);
    //创建任务二
    xTaskCreate((TaskFunction_t)task2_task,
                (char*         )"task2_task",
                (uint16_t      )TASK2_STK_SIZE,
                (void*         )NULL,
                (UBaseType_t   )TASK2_TASK_PRIO,
                (TaskHandle_t* )&TASK2Task_Handler,);
    vTaskDelete(StartTask_Handler);//删除任务,注意要用该任务的任务句柄 
    taskEXIT_CRITICAL();  // 退出临界区 
}

void key_task(void*pvParemeters)//这里的意思是动态创建任务函数
{

    u8 key;
    while(1)
    {
        key=KEY_Scan(0);
        switch(key)
        {
            case WKUP_PRES:
                    vTaskSuspend(Task1Task_Handler);//挂起任务一
                    vTaskSuspend(Task2Task_Handler);//挂起任务二
                    break;
            case KEY1_PRES:
                    vTaskResume(Task1Task_Handler);
                    break;
}
    }
}

//这里我们写一个识别颜色的程序
void task1_task(void*pvParemeters)//这里的意思是动态创建任务函数
{
    u8 task1_num=0;//系统运行次数,加到255次会清零。
    Read_OpenData();//识别颜色外设(接收openmv的数据)
    //假定读取颜色正确赋值为一,假定接收五次任务挂起
    while(1)
    {
        if(green==1)
            {
                task1_num++;
                if(task==5)
                    {
                        vTaskResume(Task2Task_Handler);
                        printf("green")
                        //vTaskSuspend();//挂起当前任务
                       }
             }
         if(red==1)
            {
                task1_num++;
                if(red==5)
                    {
                        vTaskResume(Task2Task_Handler);
                        printf("red")
                        //vTaskSuspend();//挂起当前任务
                       }
             }
          if(blue==1)
            {
                task1_num++;
                if(task==5)
                    {
                        vTaskResume(Task2Task_Handler);
                        printf("blue")
                        //vTaskSuspend();//挂起当前任务
                       }
             }
       }
}


void task2_task(void*pvParemeters)//这里的意思是动态创建任务函数
{
    while(1)
    {
            move();
    }
}
```

####
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

JIAlonglong11

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

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

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

打赏作者

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

抵扣说明:

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

余额充值