zoukankan      html  css  js  c++  java
  • 7-FreeRTOS时间片进行任务调度

    注意:

    ①任务切换会存在时间片开销;

    FreeRTOS 支持时间片,每个优先级可以支持无限多个任务,这些任务的调度就是时间片调度;

    FreeRTOS 中允许一个任务运行一个时间片(一个时钟节拍的长度)后让出 CPU 的使用权,让拥有同优先级的下一个任务运行, 至于下一个要运行
    哪个任务? 由时间片来调度,时间片调度发生在滴答定时器的中断服务函数中 。

    下面三个任务优先级相同,为N

    (1)任务 3 正在运行。
    (2)这时一个时钟节拍中断(滴答定时器中断)发生,任务 3 的时间片用完,但是任务 3 还没有执行完
    (3)FreeRTOS 将任务切换到任务 1,任务 1 是优先级 N 下的下一个就绪任务。
    (4) 任务 1 连续运行至时间片用完。
    (5) 任务 3 再次获取到 CPU 使用权,接着运行。
    (6) 任务 3 运行完成, 调用任务切换函数 portYIELD()强行进行任务切换放弃剩余的时间片,从而使优先级 N 下的下一个就绪的任务运行。
    (7)FreeRTOS 切换到任务 1
    (8) 任务 1 执行完其时间片。
     

     实验需求:

    ①使用时间片调度的话宏 configUSE_PREEMPTION(抢占式内核或协程) 和宏 configUSE_TIME_SLICING(时间片调度使能) 必须为 1;

    task1_task 和 task2_task的任务优先级设置为相同,都为 2;

    ③时间片的长度由宏 configTICK_RATE_HZ 来确定,一个时间片的长度就是滴答定时器的中断周期,设置 configTICK_RATE_HZ 10 则时间片是1/10 =100ms,那么任务一和任务二运行的时候都是占用一个100ms的时间片;

    ④任务一和任务二中每25ms让串口打印一次,那么每个任务在自己时间片下执行的话,至少打印4次。

     

    代码:

     //----------------------------------------任务优先级
     #define START_TASK_PRIO     1 
     #define KEY_TASK_PRIO       2
     #define TASK1_PRIO          2 
     #define TASK2_PRIO          2 //优先级高
     
     
     //----------------------------------------任务堆栈大小
     #define START_STK_SIZE 128 
     #define TASK1_STK_SIZE 128 
     #define TASK2_STK_SIZE 128 
     #define KEY_STK_SIZE   128 
     
     //----------------------------------------任务句柄
     TaskHandle_t Task1_Handler; 
     TaskHandle_t Task2_Handler; 
     TaskHandle_t StartTask_Handler; 
     TaskHandle_t KeyTask_Handler; //任务句柄
     
     
     //----------------------------------------任务函数
     void start_task(void *pvParameters); 
     void task1_task(void *pvParameters); 
     void task2_task(void *pvParameters); 
     void key_task(void *pvParameters); //任务函数
    
     
     int main(void)
     {
       BaseType_t OS;
       NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);  
       User_GPIO_Init();
         Delay_init();
         USART_Config();
         
    
     
         
         OS= xTaskCreate(
                                                (TaskFunction_t        ) start_task,       //任务函数
                                                (const char *          )  "start_task",    //任务名
                                                (configSTACK_DEPTH_TYPE) START_STK_SIZE,   //堆栈大小
                                                (void *                )NULL,              //传递给任务函数的参数
                                                (UBaseType_t           ) START_TASK_PRIO,  //任务优先级
                                                (TaskHandle_t *        ) &StartTask_Handler  //任务句柄
                        );
                                      
         if(OS==pdPASS) 
             GPIO_SetBits(GPIOA, GPIO_Pin_8);
             
         vTaskStartScheduler(); //开启任务调度
         
     }
     
     
     void start_task(void *pvParameters)
     {
      
             taskENTER_CRITICAL(); //进入临界区
             
           //创建任务Task1
    xTaskCreate((TaskFunction_t )task1_task, //任务函数
             (const char* )"task1_task", //任务名称
             (uint16_t )TASK1_STK_SIZE, //任务堆栈大小
             (void* )NULL,
             (UBaseType_t )TASK1_PRIO, //任务优先级
             (TaskHandle_t* )&Task1_Handler); //任务句柄
     
    xTaskCreate((TaskFunction_t )task2_task, //任务函数
             (const char* )"task2_task", //任务名称
             (uint16_t )TASK2_STK_SIZE, //任务堆栈大小
             (void* )NULL,
             (UBaseType_t )TASK2_PRIO, //任务优先级
             (TaskHandle_t* )&Task2_Handler); //任务句柄           
                     
             vTaskDelete(StartTask_Handler); //vTaskDelete(NULL)也可以   删除开始任务
             taskEXIT_CRITICAL();            //退出临界区
     }
     
     
     //任务1
     void task1_task(void *pvParameters)
     {  
         uint8_t count_num=0; 
         while(1)
         {
           count_num++; 
           printf("任务1已经执行:%d次
    ",count_num);
           delay_xms(25);  //vTaskDelay     delay_xms不发生任务切换
         }
             
     }
     
     
      //任务2
     void task2_task(void *pvParameters)
     {  
         uint8_t count_num1=0; 
         while(1)
         {
           count_num1++;
                 printf("任务2已经执行:%d次
    ",count_num1);
           delay_xms(25);  //configTICK_RATE_HZ 10则时间片是100ms    这里延时25ms,则每个任务基本上执行4次会切换任务
         }
             
     }

    执行结果:

  • 相关阅读:
    Linux官方源、镜像源汇总
    python3 pip报错 TypeError: 'module' object is not callable
    2019-11-27:kali 2019-4中文乱码解决方法
    2019-11-26:密码学基础知识,csrf防御
    2019-11-25:信息收集,笔记
    2019-11-24:postgresql数据库安装,最后报错failed to load SQLModule 问题的解决方案
    2019-11-22:xss绕过笔记
    2019-11-20:xss学习笔记
    2019-11-19:无返回的盲型xxe,使用带外读取数据
    2019-11-19:xxe漏洞利用,笔记
  • 原文地址:https://www.cnblogs.com/darren-pty/p/14202700.html
Copyright © 2011-2022 走看看