7-FreeRTOS时间片进行任务调度

摘要:
它是按时间片调度的,这发生在滴答计时器的中断服务功能中。FreeRTOS切换到任务1。

注意:

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

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

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

下面三个任务优先级相同,为N
7-FreeRTOS时间片进行任务调度第1张

(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次会切换任务
     }
         
 }

执行结果:

7-FreeRTOS时间片进行任务调度第2张

免责声明:文章转载自《7-FreeRTOS时间片进行任务调度》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇QMesageBox的使用web安全:x-content-type-options头设置下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

stm32操作系统ucosiii笔记02

临界段 Critical Sections :  1、为了实现资源共享,一个操作系统必须提供临界段操作的功能   2、uc/os-iii 为了处理林阶段代码需要关中断,处理完毕后需要开中断-——避免其他任务或中断服务进入临界段代码   3、uc/os-iii 定义两个宏(macros)开关中断————OS_ENTER_CRITICAL()         ...

RTT学习之线程管理

获得线程:rt_thread_t rt_thread_self(void);一 线程的创建和删除:rt_thread_create()创建的句柄,对应的删除rt_thread_delete(),注意线程的删除只是将线程的状态该为close,进入空闲任务才删除。rt_thread_init()函数对应的是rt_thread_detach()二 线程的就绪和挂...

【官网翻译】性能篇(一)应用待机群组

前言        本文翻译了Android开发者文档中的一篇官方文档,用于介绍Android9的一个新特性——应用待机群组(App Standby Buckets)。        中国版官网原文地址为:https://developer.android.google.cn/topic/performance/appstandby。        路径为...

记一次FreeRTOS错误配置导致无法进入临界区

  最近项目用到FreeRTOS,在实际调试中发现我自己的一段代码本来好用的(在无RTOS的情况下),但是当我在带RTOS的情况下把代码放到一个单独的任务中运行时我发现本来好用的代码莫名其妙的出现问题,有一定的概率会失败,考虑到应该是内核发生了调度导致代码中时序比较严格的地方被打断因此会出现时好时不好的现象,因此我对时序严格的地方调用了taskENTER_...

关于WinForm/Web如何使用缓存Cach

Cache 的绝对到期与滑动到期 绝对到期:设置绝对过期时间 到了指定时间以后会失效。(类似Cookie机制) 相对到期也称滑动到期:设置相对过期时间 指定时间内无访问会失效。(类似Session机制) HttpRuntime.Cache与HttpContext.Current.Cache 为同一个对象HttpRuntime.Cache.Add 存在相同...

c中的基本运算

一、 算术运算 C语言一共有34种运算符,包括了常见的加减乘除运算 1. 加法运算+ l 除开能做加法运算,还能表示正号:+5、+90 2. 减法运算- l 除开能做减法运算,还能表示符号:-10、-29 3. 乘法运算* 注意符号,不是x,而是* 4. 除法运算/ l 注意符号,不是÷,也不是,而是/ l 整数除于整数,还是整数。1/2的值是0,这个并不...