• FreeRTOS 任务调度和任务的状态


    目录

    什么是任务调度?

    FreeRTOS的任务调度规则是怎样的?

    抢占式调度运行过程​编辑

    时间片调度运行过程​编辑

    任务的状态

    任务调度和任务的状态案例分析


    什么是任务调度?

    调度器就是使用相关的调度算法来决定当前需要执行的哪个任务。

    FreeRTOS中开启任务调度的函数是 vTaskStartScheduler() ,但在 CubeMX 中被封装为 osKernelStart()

    FreeRTOS的任务调度规则是怎样的?

    FreeRTOS 是一个实时操作系统,它所奉行的调度规则:

    1. 高优先级抢占低优先级任务,系统永远执行最高优先级的任务(即抢占式调度

    2. 同等优先级的任务轮转调度(即时间片调度

    还有一种调度规则是协程式调度,但官方已明确表示不更新,主要是用在小容量的芯片上,用得 也不多。

    抢占式调度运行过程

    总结:

    1. 高优先级任务,优先执行;

    2. 高优先级任务不停止,低优先级任务无法执行;

    3. 被抢占的任务将会进入就绪态

    时间片调度运行过程

    总结:

    1. 同等优先级任务,轮流执行,时间片流转;

    2. 一个时间片大小,取决为滴答定时器中断周期;

    3. 注意没有用完的时间片不会再使用,下次任务 Task3 得到执行,还是按照一个时间片的时钟 节拍运行

    任务的状态

    FreeRTOS中任务共存在4种状态:

    • Running 运行态

    当任务处于实际运行状态称之为运行态,即CPU的使用权被这个任务占用(同一时间仅一个任务 处于运行态)。

    • Ready 就绪态

    处于就绪态的任务是指那些能够运行(没有被阻塞和挂起),但是当前没有运行的任务,因为同 优先级或更高优先级的任务正在运行。

    • Blocked 阻塞态

    如果一个任务因延时,或等待信号量、消息队列、事件标志组等而处于的状态被称之为阻塞态。

    • Suspended 挂起态

    类似暂停,通过调用函数 vTaskSuspend() 对指定任务进行挂起,挂起后这个任务将不被执行, 只有调用函数 xTaskResume() 才可以将这个任务从挂起态恢复。

    总结:

    • 1. 仅就绪态可转变成运行态
    • 2. 其他状态的任务想运行,必须先转变成就绪态

    任务调度和任务的状态案例分析

    实验需求

    创建 4 个任务:taskLED1,taskLED2,taskKEY1,taskKEY2,任务要求如下:

    taskLED1:间隔 500ms 闪烁 LED1;

    taskLED2:间隔 1000ms 闪烁 LED2;

    taskKEY1:如果 taskLED1 存在,则按下 KEY1 后删除 taskLED1 ,否则创建 taskLED1 ;

    taskKEY2:如果 taskLED2 正常运行,则按下 KEY2 后挂起 taskLED2 ,否则恢复 taskLED2。

    1.打开CubeMX,将FreeRTOS移植到STM32F103C8T6,具体看我之前写过的文章

    将FreeRTOS移植到STM32F103C8T6

    2.然后创建四个任务

    3.查看原理图配置按键跟LED灯引脚,导出代码

    代码示例:

    uart.c 重定向printf

    1. #include "stdio.h"
    2. int fputc(int ch,FILE *f)
    3. {
    4. unsigned char temp[1] = {ch};
    5. HAL_UART_Transmit(&huart1,temp,1,0xffff);
    6. return ch;
    7. }

    freertos.c

    1. void StartTaskLED1(void const * argument)
    2. {
    3. for(;;)
    4. {
    5. HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
    6. osDelay(500);
    7. }
    8. }
    9. void StartTask02(void const * argument)
    10. {
    11. for(;;)
    12. {
    13. HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);
    14. osDelay(1000);
    15. }
    16. }
    17. void StartTaskKey1(void const * argument)
    18. {
    19. for(;;)
    20. {
    21. if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
    22. {
    23. osDelay(20); // 延时消抖
    24. if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
    25. {
    26. printf("Key1 被按下\r\n");
    27. if(TaskLED1Handle == NULL)
    28. {
    29. printf("任务1不存在,准备创建任务1\r\n");
    30. osThreadDef(TaskLED1, StartTaskLED1, osPriorityNormal, 0, 128);
    31. TaskLED1Handle = osThreadCreate(osThread(TaskLED1), NULL);
    32. if(TaskLED1Handle != NULL)
    33. {
    34. printf("任务1创建成功\r\n");
    35. }
    36. }
    37. else
    38. {
    39. printf("删除任务1\r\n");
    40. osThreadTerminate(TaskLED1Handle);
    41. TaskLED1Handle = NULL;
    42. }
    43. }
    44. while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET);
    45. }
    46. osDelay(10);
    47. }
    48. }
    49. void StartTaskKey2(void const * argument)
    50. {
    51. static int flag = 0;
    52. for(;;)
    53. {
    54. if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
    55. {
    56. osDelay(20); // 延时消抖
    57. if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
    58. {
    59. printf("Key2 被按下\r\n");
    60. if(flag == 0)
    61. {
    62. osThreadSuspend(TaskLED2Handle);
    63. printf("任务2被挂起暂停\r\n");
    64. flag = 1;
    65. }
    66. else
    67. {
    68. osThreadResume(TaskLED2Handle);
    69. printf("任务2重新恢复\r\n");
    70. flag = 0;
    71. }
    72. }
    73. while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET);
    74. }
    75. osDelay(10);
    76. }
    77. }

    编译烧录代码后打开串口助手:

  • 相关阅读:
    VMware虚拟机中的Linux通过NAT模式共享主机网卡实现与外部设备通信
    【机器学习】岭回归和LASSO回归详解以及相关计算实例-加利福尼亚的房价数据集、红酒数据集
    Set 集合和其之类 HashSet、LinkedHashSet
    什么蓝牙耳机音质高?四款公认音质高的蓝牙耳机
    ATECLOUD二极管测试系统可以解决反向电流测试哪些痛点?
    Git 版本回退 超神步骤
    01【MyBatis-快速入门】
    项目经理晋升为企业高管,需要杀死自己三次
    【Java处理小数运算】0.1024-0.1等于多少
    Foxit PDF SDK for Linux (C++ Library) 8.4.1 Crack
  • 原文地址:https://blog.csdn.net/m0_74712453/article/details/133977395