想要成为大神的小菜鸟 2022-08-29 12:16 采纳率: 20%
浏览 41

在FreeRTOS系统中,任务如何进行切换?

   问题:在FreeRTOS系统实例中,task1优先级级别高于task2的优先级,task1有一个while1函数,不应该是一直在task1中吗?为啥task1和task2会同时执行?

** main.c代码如下:**


//任务优先级
#define START_TASK_PRIO        1
//任务堆栈大小    
#define START_STK_SIZE         128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define KEY_TASK_PRIO        2
//任务堆栈大小    
#define KEY_STK_SIZE         128  
//任务句柄
TaskHandle_t KeyTask_Handler;
//任务函数
void key_task(void *pvParameters);

//任务优先级
#define TASK1_TASK_PRIO        3
//任务堆栈大小    
#define TASK1_STK_SIZE         128  
//任务句柄
TaskHandle_t Task1Task_Handler;
//任务函数
void task1_task(void *pvParameters);

//任务优先级
#define TASK2_TASK_PRIO        4
//任务堆栈大小    
#define TASK2_STK_SIZE         128  
//任务句柄
TaskHandle_t Task2Task_Handler;
//任务函数
void task2_task(void *pvParameters);

//LCD刷屏时使用的颜色
int lcd_discolor[14]={    WHITE, BLACK, BLUE,  BRED,      
                        GRED,  GBLUE, RED,   MAGENTA,            
                        GREEN, CYAN,  YELLOW,BROWN,             
                        BRRED, GRAY };

int main(void)
{ 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
    delay_init(168);                    //初始化延时函数
    uart_init(115200);                     //初始化串口
    LED_Init();                            //初始化LED端口
    KEY_Init();                            //初始化按键
    EXTIX_Init();                        //初始化外部中断
    LCD_Init();                            //初始化LCD
    
    POINT_COLOR = RED;
    LCD_ShowString(30,10,200,16,16,"ATK STM32F103/407");    
    LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 6-3");
    LCD_ShowString(30,50,200,16,16,"Task Susp and Resum");
    LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
    LCD_ShowString(30,90,200,16,16,"2016/11/25");
    
    //创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建KEY任务
    xTaskCreate((TaskFunction_t )key_task,             
                (const char*    )"key_task",           
                (uint16_t       )KEY_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )KEY_TASK_PRIO,        
                (TaskHandle_t*  )&KeyTask_Handler);  
    //创建TASK1任务
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //创建TASK2任务
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

//key任务函数
void key_task(void *pvParameters)
{
    u8 key;
    while(1)
    {
        key=KEY_Scan(0);
        switch(key)
        {
            case WKUP_PRES:
                vTaskSuspend(Task1Task_Handler);//挂起任务1
                printf("挂起任务1的运行!\r\n");
                break;
            case KEY1_PRES:
                vTaskResume(Task1Task_Handler);    //恢复任务1
                printf("恢复任务1的运行!\r\n");
                break;
            case KEY2_PRES:
                vTaskSuspend(Task2Task_Handler);//挂起任务2
                printf("挂起任务2的运行!\r\n");
                break;
        }
        vTaskDelay(10);            //延时10ms 
    }
}

//task1任务函数
void task1_task(void *pvParameters)
{
    u8 task1_num=0;
    
    POINT_COLOR = BLACK;

    LCD_DrawRectangle(5,110,115,314);     //画一个矩形    
    LCD_DrawLine(5,130,115,130);        //画线
    POINT_COLOR = BLUE;
    LCD_ShowString(6,111,110,16,16,"Task1 Run:000");
    while(1)
    {
        task1_num++;    //任务执1行次数加1 注意task1_num1加到255的时候会清零!!
        LED0=!LED0;
        printf("任务1已经执行:%d次\r\n",task1_num);
        LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //填充区域
        LCD_ShowxNum(86,111,task1_num,3,16,0x80);    //显示任务执行次数
        vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍    
    }
}

//task2任务函数
void task2_task(void *pvParameters)
{
    u8 task2_num=0;
    
    POINT_COLOR = BLACK;

    LCD_DrawRectangle(125,110,234,314); //画一个矩形    
    LCD_DrawLine(125,130,234,130);        //画线
    POINT_COLOR = BLUE;
    LCD_ShowString(126,111,110,16,16,"Task2 Run:000");
    while(1)
    {
        task2_num++;    //任务2执行次数加1 注意task1_num2加到255的时候会清零!!
        LED1=!LED1;
        printf("任务2已经执行:%d次\r\n",task2_num);
        LCD_ShowxNum(206,111,task2_num,3,16,0x80);  //显示任务执行次数
        LCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //填充区域
        vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍    
    }
}

  • 写回答

4条回答 默认 最新

  • much0726 2022-08-29 14:04
    关注

    vTaskDelay(1000); 这个是释放CPU的关键,如果你task1的优先级高,那么将task1中的这个TaskDelay操作给屏蔽掉,task2就会被挂起无法执行了

    评论

报告相同问题?

问题事件

  • 修改了问题 8月29日
  • 创建了问题 8月29日

悬赏问题

  • ¥15 k8s生产配置推荐配置及部署方案
  • ¥15 matlab提取运动物体的坐标
  • ¥15 人大金仓下载,有人知道怎么解决吗
  • ¥15 一个小问题,本人刚入门,哪位可以help
  • ¥15 python安卓开发
  • ¥15 使用R语言GD包一直不出结果
  • ¥15 计算机微处理器与接口技术相关问题,求解答图片的这个问题,有多少个端口,端口地址和解答问题的方法和思路,不要AI作答
  • ¥15 如何根据一个截图编写对应的HTML代码
  • ¥15 stm32标准库的PID角度环
  • ¥15 ADS已经下载好了,但是DAS下载不了,一直显示这两种情况,有什么办法吗,非常急!