[STM32H7] STM32H743多线程应用开发:实现简单的RTOS任务调度

[复制链接]
1619|10
 楼主| 万图 发表于 2024-11-22 07:52 | 显示全部楼层 |阅读模式
在嵌入式开发中,实时操作系统(RTOS)已成为主流。它让开发者能够轻松实现多任务调度,提升系统效率。今天,我们以STM32H743为例,介绍如何在其上实现一个简单的RTOS任务调度器。
什么是RTOS?RTOS是一种用于实时应用的操作系统,它通过时间片轮转、抢占式调度等机制管理多个任务的执行。相比裸机编程,RTOS让开发者可以将复杂的功能分解为多个独立任务,从而更容易维护和扩展代码。
STM32H743简介STM32H743是ST公司高性能系列MCU的一员,具有480 MHz的主频,支持高达2 MB的Flash和1 MB的SRAM,非常适合用于需要处理复杂任务的嵌入式系统。
开发环境准备
  • 硬件:STM32H743核心板
  • 软件:STM32CubeIDE
  • 调试工具:ST-Link
RTOS实现关键点为了展示如何手动实现一个简单的RTOS调度器,我们将创建两个任务:
  • 任务1:周期性闪烁LED
  • 任务2:串口输出信息
以下是实现代码:
  1. #include "main.h"
  2. #include "cmsis_os.h"

  3. // 定义任务句柄
  4. osThreadId_t ledTaskHandle, uartTaskHandle;

  5. // LED任务函数
  6. void LedTask(void *argument) {
  7.     for (;;) {
  8.         HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); // 切换LED状态
  9.         osDelay(500); // 延时500ms
  10.     }
  11. }

  12. // UART任务函数
  13. void UartTask(void *argument) {
  14.     const char *message = "Hello from UART Task!\r\n";
  15.     for (;;) {
  16.         HAL_UART_Transmit(&huart1, (uint8_t *)message, strlen(message), HAL_MAX_DELAY);
  17.         osDelay(1000); // 延时1000ms
  18.     }
  19. }

  20. // 主函数
  21. int main(void) {
  22.     // 初始化HAL库
  23.     HAL_Init();
  24.     // 配置系统时钟
  25.     SystemClock_Config();
  26.     // 初始化外设
  27.     MX_GPIO_Init();
  28.     MX_USART1_UART_Init();
  29.    
  30.     // 创建任务
  31.     osKernelInitialize(); // 初始化内核
  32.     ledTaskHandle = osThreadNew(LedTask, NULL, NULL);
  33.     uartTaskHandle = osThreadNew(UartTask, NULL, NULL);
  34.     osKernelStart(); // 启动内核

  35.     while (1) {
  36.         // 主循环留空,由RTOS管理任务
  37.     }
  38. }

  39. // 初始化代码:GPIO和UART
  40. void MX_GPIO_Init(void) {
  41.     __HAL_RCC_GPIOB_CLK_ENABLE();
  42.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  43.     GPIO_InitStruct.Pin = GPIO_PIN_0;
  44.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  45.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  46.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  47.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  48. }

  49. void MX_USART1_UART_Init(void) {
  50.     huart1.Instance = USART1;
  51.     huart1.Init.BaudRate = 115200;
  52.     huart1.Init.WordLength = UART_WORDLENGTH_8B;
  53.     huart1.Init.StopBits = UART_STOPBITS_1;
  54.     huart1.Init.Parity = UART_PARITY_NONE;
  55.     huart1.Init.Mode = UART_MODE_TX_RX;
  56.     huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  57.     huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  58.     HAL_UART_Init(&huart1);
  59. }

  60. void SystemClock_Config(void) {
  61.     // 时钟配置代码,自动生成,保持不变
  62. }
核心逻辑分析
  • 任务创建:通过osThreadNew创建了两个任务,分别处理LED和UART操作。
  • 任务调度:RTOS内核通过osKernelStart启动,之后系统会按照优先级调度任务。
  • 延时函数:osDelay是一个阻塞函数,它能暂停任务运行指定的时间,以便内核调度其他任务。
测试与调试将代码烧录到STM32H743开发板后,可以看到:
  • LED以500ms周期闪烁
  • UART每隔1秒输出"Hello from UART Task!"
优化建议在实际应用中,可以通过以下方法进一步优化:
  • 使用优先级:为关键任务分配更高优先级。
  • 节省资源:合并相似任务,减少任务切换开销。
  • 增加监控:通过看门狗或任务监控功能提升系统可靠性。
通过上述方法,STM32H743的性能可以得到最大程度的利用。

公羊子丹 发表于 2024-11-22 07:53 来自手机 | 显示全部楼层
这个RTOS代码太实用了,手动实现调度器太适合初学者了!
周半梅 发表于 2024-11-22 07:53 来自手机 | 显示全部楼层
有没有可能分享下更多关于STM32H743的高性能应用案例?
帛灿灿 发表于 2024-11-22 07:53 来自手机 | 显示全部楼层
像这种多任务程序,怎么检测任务间冲突呢?
童雨竹 发表于 2024-11-22 07:54 来自手机 | 显示全部楼层
感谢分享,我准备把这个代码移植到我的STM32H745上试试。
Wordsworth 发表于 2024-11-22 07:54 来自手机 | 显示全部楼层
一直用裸机编程,这次要尝试下RTOS,看起来蛮有趣。
Bblythe 发表于 2024-11-22 07:54 来自手机 | 显示全部楼层
任务调度真是核心知识点,代码讲解得也很清晰!
Pulitzer 发表于 2024-11-22 07:54 来自手机 | 显示全部楼层
用RTOS写起来比裸机容易管理多了,就是入门有点难。
Uriah 发表于 2024-11-22 07:55 来自手机 | 显示全部楼层
STM32H743的性能确实强大,这个案例正好能充分发挥。
Clyde011 发表于 2024-11-22 07:55 来自手机 | 显示全部楼层
可否再详细讲讲osDelay是如何实现的?
suncat0504 发表于 2024-11-22 11:04 | 显示全部楼层
资源大,上OS就不用担心。单片机上操作系统是趋势。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

169

主题

6161

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部