STM32F1与STM32CubeIDE编程实例-CMSIS-RTOS V2配置(基于FreeRTOS)

CMSIS-RTOS V2配置(基于FreeRTOS)

1、什么是CMSIS-RTOS V2

CMSIS-RTOS v2 (CMSIS-RTOS2) 为基于 Arm® Cortex® 处理器的设备提供通用 RTOS 接口。 它为需要 RTOS 功能的软件组件提供标准化 API,从而为用户和软件行业带来巨大的好处:

  • CMSIS-RTOS2 提供了许多应用程序所需的基本功能。
  • CMSIS-RTOS2 的统一功能集减少了学习工作并简化了软件组件的共享。
  • 使用 CMSIS-RTOS2 的中间件组件与 RTOS 无关,并且更容易适应。
  • CMSIS-RTOS2 的标准项目模板可以随免费提供的 CMSIS-RTOS2 实施一起提供。

注意:CMSIS-RTOS API 版本 2 定义了最小功能集。 RTOS 供应商可能会提供具有扩展功能的实现。

CMSIS-RTOS2 管理微控制器系统的资源并实现并发运行的并行线程的概念。

应用程序经常需要多个并发活动。 CMSIS-RTOS2 可以在需要时管理多个并发活动。 每个活动都有一个执行特定任务的单独线程,这简化了整个程序结构。 CMSIS-RTOS2 系统是可扩展的,并且可以在以后轻松添加额外的线程。 线程具有优先级,允许更快地执行用户应用程序的时间关键部分。

CMSIS-RTOS2 提供许多实时应用程序所需的服务,例如,定时激活定时器功能、内存管理和有时间限制的线程之间的消息交换。

CMSIS-RTOS2 满足以下新要求:

  • 动态对象创建不再需要静态内存,静态内存缓冲区现在是可选的。
  • 支持 Armv8-M 架构,提供安全和非安全的代码执行状态。
  • 多核系统中消息传递的规定。
  • 完全支持 C++ 运行时环境。
  • 跨 ABI 兼容编译器二进制兼容的 C 接口。

由于这些要求,CMSIS-RTOS2 具有以下基本修改:

  • 函数 osXxxxNew 替换了 osXxxxCreate 函数; osXxxxNew 和 osXxxxDelete 创建和销毁对象。
  • C 函数 main 不再作为线程启动(这是 CMSIS-RTOS v1 中的可选功能)。
  • 返回 osEvent 的函数已被替换。

CMSIS-RTOS2 为 CMSIS-RTOS v1 提供了转换层。 可以在同一应用程序中混合使用 CMSIS-RTOS C API v2 和 CMSIS-RTOS C API v1。 随着时间的推移,可能会迁移到新的 API,请参考API v1 迁移到 API v2

CMSIS-RTOS2 不符合 POSIX,但具有启用 C++11/C++14 接口的规定。

2、CMSIS-RTOS V2与FreeRTOS配置

FreeRTOS 是一种 RTOS,设计得足够小,可以在微控制器上运行——尽管它的用途不限于微控制器应用程序。

由于微控制器尺寸限制和专用终端应用程序的性质很少保证使用完整的 RTOS 实现 - 或者确实使使用完整的 RTOS 实现成为可能。因此,FreeRTOS 仅提供核心实时调度功能、任务间通信、定时和同步原语。这意味着它被更准确地描述为实时内核或实时执行程序。然后可以将附加功能(例如命令控制台界面或网络堆栈)包含在附加组件中。

STM32CubeIDE集成了CMSIS-RTOS V2与FreeRTOS,并提供了相应的适配配置选项。下面将详细介绍如何配置CMSIS-RTOS V2与FreeRTOS。

第一步: 新建工程

新建工程,请参考前面文章:

串口配置,请参考前面文章:

第二步: 配置时钟

配置时钟,请参考前面文章:STM32F1与STM32CubeIDE快速入门-GPIO概述与点亮LED

由于使用了RTOS,因此,需要配置一个定时器作为RTOS的时基,配置如下:

在这里插入图片描述

第三步:配置FreeRTOS

在这里插入图片描述

在这里插入图片描述

该选项为可选项。

第四步:保存配置生成代码

3、工程生成代码解析

1)RTOS初始化及启动

在生成的代码文件main.c中的main函数:

1
2
3
4
5
6
7
/\* Init scheduler \*/
osKernelInitialize(); /\* Call init function for freertos objects (in freertos.c) \*/
MX\_FREERTOS\_Init();

/\* Start scheduler \*/
osKernelStart();

第一步:调用osKernelInitialize()函数,初始化RTOS内核

第二步:调用MX_FREERTOS_Init()函数,初始化各项线程任务、信号量,Mutex等等,该函数为STM32CubeIDE生成函数,在freertos.c文件中定义,其内容如下:

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/\* USER CODE BEGIN Header \*/
/\*\*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* File Name : freertos.c
\* Description : Code for freertos applications
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* @attention
\*
\* Copyright (c) 2022 STMicroelectronics.
\* All rights reserved.
\*
\* This software is licensed under terms that can be found in the LICENSE file
\* in the root directory of this software component.
\* If no LICENSE file comes with this software, it is provided AS-IS.
\*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*/
/\* USER CODE END Header \*/

/\* Includes ------------------------------------------------------------------\*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis\_os.h"

/\* Private includes ----------------------------------------------------------\*/
/\* USER CODE BEGIN Includes \*/

/\* USER CODE END Includes \*/

/\* Private typedef -----------------------------------------------------------\*/
/\* USER CODE BEGIN PTD \*/

/\* USER CODE END PTD \*/

/\* Private define ------------------------------------------------------------\*/
/\* USER CODE BEGIN PD \*/

/\* USER CODE END PD \*/

/\* Private macro -------------------------------------------------------------\*/
/\* USER CODE BEGIN PM \*/

/\* USER CODE END PM \*/

/\* Private variables ---------------------------------------------------------\*/
/\* USER CODE BEGIN Variables \*/

/\* USER CODE END Variables \*/
/\* Definitions for defaultTask \*/
osThreadId\_t defaultTaskHandle;
const osThreadAttr\_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 128 \* 4,
.priority = (osPriority\_t) osPriorityNormal,
};

/\* Private function prototypes -----------------------------------------------\*/
/\* USER CODE BEGIN FunctionPrototypes \*/

/\* USER CODE END FunctionPrototypes \*/

void StartDefaultTask(void \*argument);

void MX\_FREERTOS\_Init(void); /\* (MISRA C 2004 rule 8.1) \*/

/\*\*
\* @brief FreeRTOS initialization
\* @param None
\* @retval None
\*/
void MX\_FREERTOS\_Init(void) {
/\* USER CODE BEGIN Init \*/

/\* USER CODE END Init \*/

/\* USER CODE BEGIN RTOS\_MUTEX \*/
/\* add mutexes, ... \*/
/\* USER CODE END RTOS\_MUTEX \*/

/\* USER CODE BEGIN RTOS\_SEMAPHORES \*/
/\* add semaphores, ... \*/
/\* USER CODE END RTOS\_SEMAPHORES \*/

/\* USER CODE BEGIN RTOS\_TIMERS \*/
/\* start timers, add new ones, ... \*/
/\* USER CODE END RTOS\_TIMERS \*/

/\* USER CODE BEGIN RTOS\_QUEUES \*/
/\* add queues, ... \*/
/\* USER CODE END RTOS\_QUEUES \*/

/\* Create the thread(s) \*/
/\* creation of defaultTask \*/
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

/\* USER CODE BEGIN RTOS\_THREADS \*/
/\* add threads, ... \*/
/\* USER CODE END RTOS\_THREADS \*/

/\* USER CODE BEGIN RTOS\_EVENTS \*/
/\* add events, ... \*/
/\* USER CODE END RTOS\_EVENTS \*/

}

/\* USER CODE BEGIN Header\_StartDefaultTask \*/
/\*\*
\* @brief Function implementing the defaultTask thread.
\* @param argument: Not used
\* @retval None
\*/
/\* USER CODE END Header\_StartDefaultTask \*/
void StartDefaultTask(void \*argument)
{
/\* USER CODE BEGIN StartDefaultTask \*/
/\* Infinite loop \*/
for(;;)
{
osDelay(1);
}
/\* USER CODE END StartDefaultTask \*/
}

/\* Private application code --------------------------------------------------\*/
/\* USER CODE BEGIN Application \*/

/\* USER CODE END Application \*/



代码中默认生成一个StartDefaultTask任务。

第三步:启动内核调度:osKernelStart()

4、STM32F1与STM32CubeIDE快速入门系列文章

序号 内容
1 STM32F1与STM32CubeIDE快速入门-开发环境搭建
2 STM32F1与STM32CubeIDE快速入门-STM32F1微控制器概述
3 STM32F1与STM32CubeIDE快速入门-GPIO概述与点亮LED
4 STM32F1与STM32CubeIDE快速入门-按键与LED控制
5 STM32F1与STM32CubeIDE快速入门-中断、NVIC与EXTI概述
6 STM32F1与STM32CubeIDE快速入门-外部中断配置与功能实现
7 STM32F1与STM32CubeIDE快速入门-USART/UART串口通信
8 STM32F1与STM32CubeIDE快速入门-定时器(Timer)概述
9 STM32F1与STM32CubeIDE快速入门-定时器定时模式
10 STM32F1与STM32CubeIDE快速入门-定时器计数模式
11 STM32F1与STM32CubeIDE快速入门-定时器PWM模式
12 STM32F1与STM32CubeIDE快速入门-定时器编码(Encoder)模式
13 STM32F1与STM32CubeIDE快速入门-定时器输入捕获模式(Input Capture Mode)实现频率计数
14 STM32F1与STM32CubeIDE快速入门-DMA概述
15 STM32F1与STM32CubeIDE快速入门-USART通过DMA进行数据接收与发送
16 STM32F1与STM32CubeIDE快速入门-ADC概述
17 STM32F1与STM32CubeIDE快速入门-ADC轮询方式实现PWM调光器
18 STM32F1与STM32CubeIDE快速入门-ADC中断方式实现PWM调光器
19 STM32F1与STM32CubeIDE快速入门-ADC通过DMA方式与PWM实现调光器
20 STM32F1与STM32CubeIDE快速入门-DAC概述
21 STM32F1与STM32CubeIDE快速入门-SPI概述
22 STM32F1与STM32CubeIDE快速入门-M25P16串行闪存驱动
23 STM32F1与STM32CubeIDE快速入门-I2C概述
24 STM32F1与STM32CubeIDE快速入门-I2C驱动LCD1602显示屏(基于PCF8574)
25 STM32F1与STM32CubeIDE快速入门-独立看门狗(IWDG)
26 STM32F1与STM32CubeIDE快速入门-OLED-SSD1306-I2C驱动

文章来源: https://iotsmart.blog.csdn.net/article/details/124582809