当前位置:   article > 正文

01_FreeRTOS 任务优先级_osthreaddef

osthreaddef

01_FreeRTOS 任务优先级


RTOS即为操作系统。主要目的是使我们可以同时使用多个任务。
本文将介绍:
a. 使用CubeMX 设置的免费RTOS。
b. 使用RTOS的好处。
c. 在没有CubeMX情况下创建任务。
d. 使用优先级来解决一些常见的问题

  1. 设置CubeMX
    1.1 由于FreeRTOS v1大多数STM32设备都支持,故选择CMSIS_V1。
    1.2 转到Tasks and Queues, 注意Task name、priority和entry function即可。
    1.3 新建另外一个任务Task2,修改Task name 和 entry function分别为 Task2 和 Task2_init

    1.4 用RTOS的话,则不能用systick作为时基,则选用其他时基源,并且选用Serial Wire 作为debug方式

    1.5 用USART1作为数据传输口用异步模式,同时打开中断

    1.6 由于板子外接高速时钟,配置HSE,同样开启中断:

    时钟配置,7种时钟的简介

  2. 使用RTOS的优势
    多线程

  3. 创建任务
    创建任务必须遵循:
    3.1 定义任务的ThreadID,后续对于此任务的所有操作都需要此ID

    3.2 定义任务的输入函数,这就是任务的主要函数,程序将被写入,RTOS任务是没有返回值,故入口函数是一个死循环函数。

    3.3 主函数中需要先定义任务再创建任务。

    osThreadDef 参数分别为:任务名称,输入函数,优先级,实例和堆栈大小。定义任务后,我们可以使用创建任务osThreadCreate,并将ID分配给Task3Handle。

  4. FreeRTOS中的优先级
    当我们尝试在优先级相同的任务之间使用共享资源时,就会发生这种情况。第二项任务必须等待第一个任务完成,然后才能完成控制。同样,第三个任务将等待第二个任务完成(任务中间有延时,就效率很低)。
    可以定义任务间不同优先级,就能合理安排任务的调用。

  5. 用串口看任务优先级
    注意: 当用osDelay()时,让任务阻塞,任务阻塞后,RTOS系统调用其它处于就绪状态的优先级最高的任务来执行。当使用HAL_Delay()时,HAL_Delay一直不停的调用获取系统时间的函数,直到指定的时间流逝然后退出,故其占用了全部CPU时间。

   void send_task1(void){
	uint8_t data[] = "task1\n";
	HAL_UART_Transmit(&huart1, data, sizeof(data),500);
}
void send_task2(void){
	uint8_t data[] = "task2\n";
	HAL_UART_Transmit(&huart1, data, sizeof(data),500);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
void Task1_init(void const * argument)
{
  /* USER CODE BEGIN 5 */
  /* Infinite loop */
  for(;;)
  {
	send_task1();
	HAL_Delay(1000);
  }
  /* USER CODE END 5 */
}

void Task2_init(void const * argument)
{
  /* USER CODE BEGIN Task2_init */
  /* Infinite loop */
  for(;;)
  {
	// 执行函数
	send_task2();
	HAL_Delay(1000);
  }
  /* USER CODE END Task2_init */
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
1.1 任务优先级相同时
  • 1
  osThreadDef(Task1, Task1_init, osPriorityNormal, 0, 128);
  Task1Handle = osThreadCreate(osThread(Task1), NULL);

  /* definition and creation of Task2 */
  osThreadDef(Task2, Task2_init, osPriorityNormal, 0, 128);
  Task2Handle = osThreadCreate(osThread(Task2), NULL);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
    输出结果:
  • 1

说明:当定义相同优先级输出如下,调度器会让这些任务轮流执行。
  • 1

1.2 当定义不同优先级输出如下:
  • 1

  osThreadDef(Task1, Task1_init, osPriorityNormal, 0, 128);
  Task1Handle = osThreadCreate(osThread(Task1), NULL);

  /* definition and creation of Task2 */
  osThreadDef(Task2, Task2_init, osPriorityAboveNormal, 0, 128);
  Task2Handle = osThreadCreate(osThread(Task2), NULL);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
    输出结果:
  • 1

说明:调度器总是选择具有最高优先级的可运行任务来执行。任务 2 的优先级比任务 1高,并且总是可运行,因此任务 2 是唯一一个一直处于运行态的任务。而任务 1 不可能进入运行态,所以不可能输出字符串。这种情况我们称为任务 1 的执行时间被任务 2”饿死(starved)”了。
  • 1

Code 下载地址

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/398018
推荐阅读
相关标签
  

闽ICP备14008679号