首页
学习
活动
专区
工具
TVP
发布

TencentOS tiny RTOS快速入门

上节,我们介绍了TencentOS tiny,参考官方给出的移植教程亲自动手做了一遍,文章如下:

趁着最近有时间,这节,我撸了几个例程作为后面做项目参考的基本框架,当然也有一些是直接拿了官方文档的例程:

一般来说,学习任何一个RTOS,本质是没有什么太大的区别的,通常在最简版nano上进行开发,关于,我个人认为,掌握以下基础组件的用法足矣,其它的一些组件,可以等需要使用的时候再参考文档学习应用即可。

TencentOS tiny多任务

TencentOS tiny RTOS软件定时器

TencentOS tiny RTOS任务间通信(互斥锁、信号量、事件、队列)

在使用基本组件之前,我们需要配置文件:

这样后面我们才能正常使用。

1、TencentOS tiny多任务

1.1 为什么要采用RTOS多任务?

对于普通的项目来说,比如密码锁类项目,单独的一个传感器模块的开发,某些简单的仪器仪表等等,对于这类场景单一,业务需求也单一的项目来说,使用状态机或者事件驱动的方式就足以完成项目的基本功能了。

但是如果开发一个巨量代码的工程项目,项目可能设计到传感器数据读取、无线数据上传与接收、数据传输、UI实时刷新、算法处理等等,功能诸多还需要相互配合的情况下,那么如果还在用裸机的思想去完成,那么开发者一般会面临以下两个问题:

设计思路过于复杂,光怎么想程序的设计思路就得想好久了

设计下来的各个功能,要考虑相互配合的问题,实时性可能得不到要求

RTOS的多任务就可以解决对应的问题,它既能让项目开发起来思路清晰,方便易维护;同时RTOS也能保证整个产品运行的实时性,典型的程序设计架构,就可以按下面的方式来划分:

1.2 TencentOS tiny RTOS多任务实践

关于怎么创建多个任务,可以参考文档,以下工程是我基于上一节的移植工程,在移植工程的基础上,由于官方给的OLED驱动例程是软件模拟驱动的,后来我将其改为I2C硬件驱动,所以,在STM32CubeMX上对OLED的I2C接口进行了配置:

更改后重新生成软件工程,然后修改oled.c中关于写命令和写数据的接口为硬件I2C驱动:

接下来,进入多任务程序编写,我们主要实现以下两个功能:

task1以1s的频率循环打印

task2以100ms的频率循环翻转。

main.c

定义两个基本任务:

在main函数中:

编译后下载到EVB_MX+开发板后,运行结果如下:

task1以1s的频率循环打印,task2以100ms的频率循环翻转。

1.3 总结

概念性总结:

多任务适合业务场景更加复杂的应用场景

多任务适合对实时响应要求更高的场景

使用总结:

详情请参考文档

2、TencentOS tiny RTOS软件定时器

2.1、为什么要采用RTOS软件定时器?

软件定时器,顾名思义就是软件实现的定时器,它是和硬件定时器有本质区别的,软件定时器使用的是系统调度所依赖的嘀嗒定时器,也就是Systick来实现的,它主要解决一些不需要特别精准的定时触发场合,目前github仓库上有开源不少软件定时器的实例,比如multi_timer,TecentOS tiny也在自己的内核中集成了自己的一套软件定时器,实现原理其实也是差不多的。

2.2、TencentOS tiny RTOS软件定时器实践

关于怎么使用定时器,可以参考文档,以下工程基于多任务例程修改,接下来,进入软件定时器程序编写,我们主要实现以下两个功能:

task1以1s的频率循环打印

软件定时器以500ms的频率翻转LED

main.c

在main函数中:

编译后下载到EVB_MX+开发板后,运行结果如下:

task1以1s的频率循环打印,软件定时器以500ms的频率执行,此时LED会以500ms的速率循环翻转。

2.3 总结

概念性总结:

软件定时器就是用"软件逻辑"实现的定时器

软件定时器适合一些不需要特别精准的定时触发场合.

使用总结:

详情请参考文档

3、TencentOS tiny RTOS任务间通信

3.1、TencentOS tiny RTOS互斥锁3.1.1 、为什么要采用RTOS互斥锁?

互斥锁适用于实现临界区资源的互斥性访问,当有多个任务同时并行对一个数据操作时,就会存在不确定性,典型的案例就是全局变量,在不带操作系统的裸机功能开发中,我们通常会使用全局变量,让其在整个工程中通过外部引用的方式全局可见,这样我们就可以很方便的在任何一个地方对其进行读写操作,但如果在操作系统中却恰恰相反,这种奇怪的现象被称为不可重入,通常在操作系统里叫临界区资源,在字符串操作中,典型的不可重入函数是strtok,strtok函数内部有一个static变量,这种类型的变量可以被多次重入调用共同控制,其最终的结果依赖于它们的执行顺序,所以,使用互斥锁可以解决这种不确定性的问题,也就是说在任意时刻,只会有一个任务对其进行访问。

3.1.2、TencentOS tiny RTOS互斥锁实践

关于怎么使用互斥锁,可以参考文档,以下工程基于多任务例程修改,接下来,进入互斥锁程序编写,我们主要实现三个任务同时执行一段代码:

main.c

在main函数中:

编译后下载到EVB_MX+开发板后,运行结果如下:

3.1.3、总结

概念性总结:

互斥锁在任意时刻,只会有一个任务对临界资源进行访问

互斥锁用于实现临界区资源的互斥性访问

使用总结:

详情请参考文档

3.2、TencentOS tiny RTOS信号量

3.2.1、为什么要采用RTOS信号量?

信号量,俗话说就是信号的数量,它是一种任务间传递系统可用资源的机制;举一个生产者与消费者的问题;也就是说消费者在消费了一个资源之前需要等待资源释放,生产者生产资源以后要即时去通知其它的消费者,简单的说就是凡事都要有个先来后到,所以信号量最常用的地方就是实现任务间同步。

3.2.2、TencentOS tiny RTOS信号量实践

关于怎么使用信号量,可以参考文档,以下工程基于多任务例程修改,接下来,进入信号量程序编写,我们主要实现生产者和消费者的问题,这段程序在参考文档里可以找到:

main.c

main函数实现如下:

编译后下载到EVB_MX+开发板后,运行结果如下:

3.2.3、总结

概念性总结:

信号量可以用于实现任务间同步

信号量最典型的应用就是处理生产者与消费者的问题

使用总结:

详情请参考文档

3.3、TencentOS tiny RTOS事件

3.3.1、为什么要采用RTOS事件?

事件,是RTOS任务间用来传递的一种信号的信息,它可以传递多个信息,事件和信号量的区别就是信号量只能传递0和1两个信息,而事件的类型通常用进行描述,它的本质是一个数据类型,也就是说事件最多可以定义32个,使用事件可以很方便的实现任务间同步和信息传递,但是要注意的是事件达到的是一种类似通知的效果,本身是不带负载的。

3.3.2、TencentOS tiny RTOS事件实践

关于怎么使用事件,可以参考文档,以下工程基于多任务例程修改,我们在多任务例程的基础上,移植了multi_button组件,这个组件的移植方法在之前写小熊派相关的文章中都有详细的方法,这里就不再多说了,参考文章如下:

这里的我把它放在函数中进行处理,实现如下:

接下来进入事件程序的编写,我们主要实现以下两个功能:

定义任务task1,用于初始化multi_button,通过按键回调发送事件

定义任务task2,用于接收task1发送过来的事件,并进行处理

main.c

定义multi_button结构体变量以及事件相关的变量

定义按键电平读取以及按键处理的函数:

在main函数中:

编译后下载到EVB_MX+开发板后,运行结果如下:

当分别按下四个按键后,task2接收到具体消息后执行不同的逻辑

3.3.3 总结

概念性总结:

事件区别于信号量,信号量是0-1传递,而事件可以传递多个信息

事件是用于RTOS任务间传递的一种没有信息负载的信号类信息

使用总结:

详情请参考文档

3.4、TencentOS tiny RTOS队列

3.4.1、为什么要采用RTOS队列?

队列也是任务间传递信息的一种方式,它和事件最本质的区别就是,事件传递没有负载,而队列的传递是包含数据负载的,在事件章节中,当我们按下按键的时候其中一个任务发出事件,另一个任务则接收事件,而接收的这个事件是非常单一的,除此之外并没有更多具体的新信息载体,而队列就是为了解决这个问题而诞生的,比如串口接收数据,当数据接收满了,此时我们就可以使用队列将接收满的数据通过队列的信息发出去,然后任务里进行接收处理。

3.4.2、TencentOS tiny RTOS队列实践

关于怎么使用队列,可以参考文档,但该文档的API过老,可能不适合现在的版本,于是找来了一个新版的API,参考网友修改的,以下工程基于多任务例程修改:

main.c

main函数实现:

编译后下载到EVB_MX+开发板后,运行结果如下:

3.4.3、总结

概念性总结:

事件传递不带信息负载,而队列是带信息负载的

队列除了可以告诉我们发生了什么事,还可以告诉我们发生这件事情的详细过程

使用总结:

详情请参考腾讯物联网终端操作系统开发指南.pdf文档

4、总结

关于还有非常多的组件可以学习,这里只是列出了最常用的几种,最后我们给本文做下简短的总结:

多任务

解决复杂需求、实时性问题。

互斥锁

解决不可重入,资源的竞争关系。

信号量

解决任务间同步问题,典型为生产者-消费者的问一体。

事件

解决任务间同步问题,相比信号量,事件可以传递多个,但不带负载。

队列

解决任务间传递带负载的问题。

案例下载

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20201027A00FJQ00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券