文章目录

  • 目的
  • 基础说明
  • 入门体验
    • 基础配置
    • 任务调度
    • 消息队列
    • 信号量
    • 互斥量
    • 定时器
  • 其它补充
    • 使用ST-LINK调试
    • 中断嵌套
  • 总结

目的

FreeRTOS是现在比较流行的主要应用于单片机等性能相对较低,对实时性要求又比较高的嵌入式应用场景中的操作系统。通常说FreeRTOS主要指的就是其内核,提供了线程、信号、内存管理等功能。使用FreeRTOS等RTOS可以方便复杂项目开发或是团队合作开发。

在STM32Cube中可以通过图形化的工具来配置使用FreeRTOS,生成初始化代码,省去了自己移植FreeRTOS的步骤,使用起来非常方便。这篇文章将对相关内容做个介绍。

基础说明

ST官方对这块相关内容有文档进行介绍:
《UM1722 - Developing applications on STM32Cube with RTOS》

可以在官网搜索下载:
https://www.st.com/content/st_com/en.html

另外也可以在下面网站搜索下载到中文版本的:
https://www.stmcu.com.cn/

在STM32Cube中可以通过图形化的工具来配置使用FreeRTOS,但是以这种方式使用时又不是原汁原味的FreeRTOS,它在FreeRTOS和用户应用之间又封装了一层 CMSIS-RTOS ,我们在这种方式下写代码主要是和这一层进行交互:

需要注意的是上面两个文档都是基于CMSIS-RTOS-V1的,现在有CMSIS-RTOS-V2了,两者的API稍有不同,不过在STM32Cube中对此做了一定的兼容处理。这篇文章中主要以CMSIS-RTOS-V2为中间层进行介绍。

入门体验

本文中使用的主控为 STM32F405RG ,开发环境如下:
STM32CubeIDE - V1.9.0
STM32Cube MCU Package for STM32F4 Series - V1.27.1

基础配置

这里先以最基础的配置开始使用:

  • 启用SWD调试,启用UART1,参数默认即可;
  • FreeRTOS选用CMSIS_V2接口,并启用USE_NEWLIB_REENTRANT,其它保持默认;

根据上面配置生成初始化代码,在左侧资源管理器中可以看到相关代码文件目录,其中就有FreeRTOS,通常来说我们是不需要手动修改这里的代码的,有需要尽量在图形化配置界面中调整。

生成代码的 main.c 中可以看到引用了 cmsis_os.h 文件, cmsis_os.h 文件中又引用了 cmsis_os2.h 文件,通常我们需要与RTOS交互只要使用这两个文件里面定义的各种接口即可。

main函数中可以看到调用了 osKernelInitializeosKernelStart 两个函数。用户与操作系统相关初始化操作都可以放在这两者间。特别需要注意的是RTOS正常工作时 osKernelStart 是无限循环的,不停的在此处对各个任务进行调度,通常写在这后面的所有操作都不会被执行,如果执行那说明系统运行出错了。

任务调度

默认配置下会自动创建一个任务,如下图所示,使用 osThreadNew 方法创建了一个任务,该任务执行 StartDefaultTask 这个函数,我们可以对这个函数稍加修改来测试任务运行:

/* USER CODE BEGIN Includes */
#include "stdio.h" // 引入该库为了可以使用 printf 函数
/* USER CODE END Includes */// ----------------------------------------/* USER CODE BEGIN 0 */
int __io_putchar(int ch) // 实现该方法,以使printf可以正确工作
{HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);return ch;
}
/* USER CODE END 0 */// ----------------------------------------/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{/* USER CODE BEGIN 5 *//* Infinite loop */for(;;){osDelay(1000); // 延时1000 rtos时间片,默认情况下即为1000msprintf("%d\n", (int)osKernelGetTickCount()); // 打印时间// printf("%d\n", (int)HAL_GetTick());}/* USER CODE END 5 */
}


上面延时中时间末尾数字的变化主要是因为程序调度以及串口发送操作等耗时引起的。

上面默认的这个任务是在图形界面中配置生成的,我们也可以直接使用代码来建立任务:

/* USER CODE BEGIN 0 */
osThreadId_t naisuTaskHandle; // 任务IDconst osThreadAttr_t naisuTask_attributes = {  // 任务属性参数.name = "naisuTask",.stack_size = 128 * 4,.priority = (osPriority_t) osPriorityNormal,
};void StartNaisuTask(void *argument) // 任务函数
{for(;;){osDelay(1);}
}
/* USER CODE END 0 *//* USER CODE BEGIN RTOS_THREADS */
naisuTaskHandle = osThreadNew(StartNaisuTask, NULL, &naisuTask_attributes); // 创建任务
/* USER CODE END RTOS_THREADS */


上面演示中还在创建任务时向任务传递了参数。

除了建立并运行任务,RTOS中还有暂停、销毁等操作任务的函数。

通常RTOS中的Task(任务)就相当于一般操作系统中的Thread(线程)。RTOS内核最核心的工作就是管理一个个的线程,调度线程运行,以实现对系统CPU和内存等资源的合理利用。使用RTOS从操作而言就是根据功能需求分割创建并运作一个个的任务,其它的功能都是围绕这些任务展开的能。

消息队列

消息队列主要用于任务间传递数据使用,下面是个简单的演示:

上面演示中使用图形化界面配置生成队列,默认建立的队列中数据是uint16_t类型的。

在一个任务中定期将数据通过 osMessageQueuePut 方法放入队列;另一个任务使用 osMessageQueueGet 不停地等待队列中数据,有数据可用时就取出数据,然后通过串口打印。

实际使用中队列中数据可以是任意类型的,可以通过队列的属性参数来配置。

信号量

信号量相当于一个简化版的消息队列,无非传递数据,只是通知一下有资源可用。信号量有二进制信号量和计数型信号量。

二进制信号量只表达资源可用和不可用两种状态,下面是个简单的演示:

上面演示中使用 osSemaphoreRelease 方法来释放一个资源,使用 osSemaphoreAcquire 方法来获取这个资源。

计数型信号量表达资源的数量,下面是个简单的演示:

计数型信号量在创建的时候可以设置计数上限以及初始计数值。

互斥量

互斥量用于保护数量只有一个的资源在被一个任务所用的时候不会被其它任务抢占。

比如下面情况下没有互斥量的保护输出就会出现问题:

上面两个任务会平等的执行,理想中想要两个任务各自打印出消息,但是两个任务使用的串口是同一个,其中一个任务在使用的时候另一个任务去使用它就会失败或者会覆盖前一个的输出(取决于这里调用的串口库函数逻辑)。

这里使用互斥量就可以解决上面的问题:

对同一个资源使用同一个互斥量,在使用资源前先用 osMutexAcquire 上个锁,这样其它任务就无法在获取到这个互斥量了;使用完成后使用 osMutexRelease 解锁,使用时需要注意谁上锁就由谁解锁。

如果在任务中有可能对同一资源出现嵌套上锁,那就需要使用 Recursive Mutexes 了,要注意上了几次锁就需要解锁几次。

定时器

RTOS和普通的操作系统一样也提供了软件定时器功能,下面是个简单的演示:

要注意的是上面演示中在定时器回调函数里进行了串口打印这种耗时操作,通常来说定时器回调函数中不推荐进行耗时操作,更多的是设置一个标识,然后在其它任务中进行操作。

其它补充

使用ST-LINK调试

FreeRTOS的很多功能也可以使用ST-LINK进行调试:

中断嵌套

STM32 MCU硬件本身中断优先级有0~15可以选择,数值越低优先级越高。

在RTOS中中断嵌套和两个变量相关:

LIBRARY_LOWEST_INTERRUPT_PRIORITY为RTOS的最低优先级,一般保持最低即可

LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY表示如果硬件中断优先级比它高(比如这里就指0~4)则不能在中断回调函数中使用RTOS的API

在中断控制器设置中也可以看到相关选择:

总结

在STM32Cube中使用FreeRTOS总体来说并不复杂,通过图形界面可以方便的配置FreeRTOS,省去了手动移植的步骤。不过从另一方面来说配置生成的代码中又封装了一个中间层,出发点来说是不错的,但是功能体验上来说并不原汁原味,还多一层封装多几个坑。实际使用时需要结合各自实际情况选择。

在STM32Cube中使用FreeRTOS:入门体验相关推荐

  1. python课程推荐-课程推荐:四天人工智能 python入门体验课

    作为一名被大数据和数量信息包裹的文案,我们必定要在文案力.创意和策略能力之外,准备一个加薪引擎--以技术思维处理数据运算的能力. 只有跑得足够快,才能不被行业当成 "老古董" 落下 ...

  2. figma设计_如何在Figma中构建设计入门套件(第1部分)

    figma设计 Figma教程 (Figma Tutorial) Do you like staring at a blank canvas every time you start a new pr ...

  3. PHPWeb开发入门体验学习笔记

    PHPWeb开发入门体验学习笔记 4 一.PHP web应用开发须知 1.入门要点 程序员三个阶段:码农(速成技能)->工程师(长期知识)->专家(研究论文) 编程三要素:声明变量(系统. ...

  4. springboot导包显示不存在_基础篇:Spring Boot入门体验(图文教程)

    优质文章,及时送达 什么是 Spring Boot? Spring Boot 是由 Pivotal 团队提供的全新框架.Spring Boot 是所有基于 Spring Framework 5.0 开 ...

  5. python体验课是上纯代码_大陈教初中生学Python,入门体验第二课教学设计,溯本追源...

    第一课我们已经对Python有了一定的了解,那么接下来再通过补充程序.改正程序.编写程序,和学生一起明确变量.常量.表达式.数据类型.赋值语句.输入输出语句.数据类型转换函数.算术运算符等基础知识,溯 ...

  6. activiti7入门体验(2)

    activiti7入门体验(2) 在大家学习了activiti7基本学习过后想必都对activiti7有一定的理解了,接下来我就给大伙讲述一下activiti7基本的功能和环境的搭建 开发环境 jav ...

  7. Spring Security(1) 入门体验

    一.前言 Spring Security 和 Apache Shiro 都是安全框架,为Java应用程序提供身份认证和授权. 二者区别 Spring Security:重量级安全框架 Apache S ...

  8. OpenStack 入门体验

    ** OpenStack 入门体验 ** 技能目标: 了解云计算概念 了解 OpenStack 了解 OpenStack 的构成 会 OpenStack 单机环境一键部署 从控制台认识 OpenSta ...

  9. ormlite android studio,OrmLite-android入门体验

    入门体验 OrmLite 是一个轻量级的ORM(Object Relational Mapping)数据库工具,方便持久化java对象到数据库 1. 使用准备 使用androidADT创建androi ...

最新文章

  1. 深度学习开源库tiny-dnn的使用(MNIST)
  2. Android 动画小知识点
  3. python flask web开发_Python Flask web后端开发
  4. 程序员为什么不会修电脑?
  5. YUIDoc的使用方法小结
  6. 跨链(6)波卡Polkadot “系统框架”
  7. MAC随机修改批处理
  8. python回测量化交易策略收益率
  9. table加载动态数据(亲测)
  10. 001.从零到1之Linux高性能服务器开发
  11. date-打印或者设置系统日期和时间
  12. 分子动力学模拟的主要步骤
  13. 电信光猫找不到服务器,高手说说电信光猫没网如何设置?
  14. 基于人脸识别录入 人脸图片识别 及测试的效果
  15. python编程入门自学
  16. SPI全双工模式下收发字节的理解
  17. 学生用计算机的使用技巧,选学生笔记本电脑的小窍门
  18. 如何挑选合适的卫星影像
  19. 让你重新爱上 Windows 的小众软件
  20. 微星ZH77A-G43老主板加持SSD 成功!

热门文章

  1. Unity3D编辑器插件开发
  2. java中计算百分比
  3. 基于高斯两步移动搜寻法(2SFCA)的城市绿地可达性分析
  4. java 首字母大写方法
  5. tcp支持浏览器websocket协议
  6. adf的主要功能之一是_ADF软件介绍
  7. 微信内分享域名防红方案-微信域名防封跳转技术的方案解析_微信域名防封推广源码
  8. 如何用python制作三维动画_python-如何在m??atplotlib中更新3D箭头动画
  9. 手机必备的广告过滤利器---X浏览器
  10. unity之二维数组实现正六边形地图