本帖最后由 cc1989summer 于 2024-9-20 22:22 编辑
STM32H7R7/S7系列是一款基于bootflash的MCU,Cortex®-M7内核,运行频率最高600 MHz,64 KB用户bootflash、可配置的620 KB SRAM以及带Flex ECC的32 x 32 KB缓存。
如此强大的MCU,如果我们只跑裸机程序,就太浪费MCU强大的功能和丰富的资源了。
嵌入式操作系统的加持,则让这款MCU如虎添翼,本篇我们运用嵌入式操作系统Free-RTOS高科技点灯。
甚至有时能完成裸机难以完成的任务。
传统的处理器一次只能执行一个任务--但是多任务操作系统通过快速切换任务,使每个任务看起来一直在执行。下图显示了三个任务相对于时间的执行模式。任务名字是颜色编码的,并写在图片的左边。时间从左向右移动,带颜色的线展示在特定的时刻哪个任务在执行。上面的图片展示了我们感知到的并发的执行模式,下面的图片展示实际的多任务执行模式。
比如这段裸机程序:
while (1)
{
HAL_GPIO_TogglePin(GPIOO, GPIO_PIN_1);
/* Insert delay 100 ms */
HAL_Delay(100);
HAL_GPIO_TogglePin(GPIOO, GPIO_PIN_5);
/* Insert delay 100 ms */
HAL_Delay(100);
HAL_GPIO_TogglePin(GPIOM, GPIO_PIN_2);
/* Insert delay 100 ms */
HAL_Delay(100);
HAL_GPIO_TogglePin(GPIOM, GPIO_PIN_3);
/* Insert delay 100 ms */
HAL_Delay(100);
}
每个LED的闪烁Toggle时间间隔都是400ms。
但假如要求4个LED闪烁时间间隔分别是100ms,300ms,500ms,700ms,该怎么实现呢。
这几乎是个不可能完成的任务。
FreeRTOS是一个实时操作系统,适用于微控制器和微处理器,使小型低功耗设备的编程变得更容易。 FreeRTOS支持 40 多种处理器架构,内存占用小,执行时间快,具有尖端的 RTOS 功能和库,包括对称多处理 (SMP)、具有 IPv6 支持的线程安全 TCP 堆栈以及与云服务的无缝集成。它是开源的,并得到了积极的支持和维护。
首先我们需要安装FreeRTOS软件。
STM32CubeIDE对FreeRTOS的支持非常友好,在Help菜单中,点击Manage emmbedded software packages
在STMicroelectronics选项卡中,选择X-CUBE-FREERTOS,点击Install安装。
我们打开ioc文件,在middleware and software packs中选择FreeRTOS,勾选APP即可。
在右侧Interface选择CMSIS_V2
在下方的Tasks and Queues选择Add,共新建myTask02、myTask03、myTask04、myTask05四个用户任务,每个任务对应1个灯。
自动生成代码后,在main.c中,可以看到4个刚才创建的任务:
void StartTask02(void *argument);
void StartTask03(void *argument);
void StartTask04(void *argument);
void StartTask05(void *argument);
在函数中添加下述代码:使得
LED1 闪烁间隔100ms
LED2 闪烁间隔300ms
LED3 闪烁间隔500ms
LED4 闪烁间隔700ms
void StartTask02(void *argument)
{
/* USER CODE BEGIN StartTask02 */
/* Infinite loop */
for(;;)
{
HAL_GPIO_TogglePin(GPIOO, GPIO_PIN_1);
/* Insert delay 100 ms */
osDelay(100);
}
/* USER CODE END StartTask02 */
}
/* USER CODE BEGIN Header_StartTask03 */
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] Function implementing the myTask03 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask03 */
void StartTask03(void *argument)
{
/* USER CODE BEGIN StartTask03 */
/* Infinite loop */
for(;;)
{
HAL_GPIO_TogglePin(GPIOO, GPIO_PIN_5);
/* Insert delay 100 ms */
osDelay(300);
}
/* USER CODE END StartTask03 */
}
/* USER CODE BEGIN Header_StartTask04 */
/**
* @brief Function implementing the myTask04 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask04 */
void StartTask04(void *argument)
{
/* USER CODE BEGIN StartTask04 */
/* Infinite loop */
for(;;)
{
HAL_GPIO_TogglePin(GPIOM, GPIO_PIN_2);
/* Insert delay 100 ms */
osDelay(500);
}
/* USER CODE END StartTask04 */
}
/* USER CODE BEGIN Header_StartTask05 */
/**
* @brief Function implementing the myTask05 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask05 */
void StartTask05(void *argument)
{
/* USER CODE BEGIN StartTask05 */
/* Infinite loop */
for(;;)
{
HAL_GPIO_TogglePin(GPIOM, GPIO_PIN_3);
/* Insert delay 100 ms */
osDelay(700);
}
/* USER CODE END StartTask05 */
}
执行结果见以下视频:
FreeRTOS多任务点灯