23
为了解决物联网网关程序的多任务协调与实时工作,研究了定时器中断,μC/OS、FreeRTOS、RTX和RT-Thread嵌入式实时操作系统的特点。RT-Thread拥有硬实时核心,具有稳定、实时与可剪裁的性能,是一种“小而美”的物联网操作系统,适合物联网网关使用。分析了RT-Thread在物联网网关的STM32微控制器中运行的流程,编写了程序,利用Proteus软件实现了多线程任务实时运行仿真,并在物联网网关的STM32微控制器中稳定运行。
0 引言
研制的物联网网关采用STM32微控制器(MCU),需要控制多个复杂的外设,有传感器、NB-IoT通信模块等,
假设传感器每1s启动一次,控制传感器需要花费0.3s,NB-IoT通信模块每2s就要向外部发送一些信息,耗费的时间大约为0.5s,此时系统中还要执行其他的一些控制,
比如通过串口进行数据传输,使数据在液晶屏上显示等。如果采用中断的方式编写程序,不是单纯一个
定时器中断,会有其他的一些中断,不能把控制传感器和NB-IoT 通信模块的程序简单的放在定时器中断中去执行。当系统中断很多时,中断时间执行过长,将导致比它优先级低的中断被抢占而无法执行,对于不支持中断嵌套的MCU,采用这种方式,会导致一个更重要的事件被阻塞,对于支持中断嵌套的MCU,这样设计也不好,因为同级别的中断一般是不可以被另外一个同级别的中断抢占的。通常情况下,应该尽快的将中断程序执行结束。如何解决使物联网网关程序不是在各个任务协调工作上耗费大量的时间,而是专注于各个任务的功能,采用嵌入式实时操作系统(Embedded RTOS)是一种好的解决方案,常见的RTOS有μC/OS、FreeRTOS、RTX和RT-Thread等。
1 μC/OS、FreeRTOS、RTX和RT-Thread RTOS的特点
μC/OS分为μC/OS-Ⅱ和μC/OS-Ⅲ,有抢占式,高度便携式和可扩展的实时内核,是Embedded RTOS 的关键组件。它提供任务的调度和管理、多个任务之间的同步和通信、中断服务等功能,拥有高效的执行率、很
小的占用空间和较好的实时性等特点。FreeRTOS是为Embedded RTOS设计的可扩展的实时内核,能方便地移植到单片机上运行。它提供任务、时间和内存管理、信号量和消息队列等功能,拥有公开的源码、灵活的调度策略、可移植和裁减和免费等特点。Keil RTX是为ARM Cortex-M微控制器设计的Embedded RTOS。拥有免版
税和确定性,能够实时执行多个任务,应用程序的结构能
更好、维护更容易等特点。RT -Thread是中国的开源Embedded RTOS [1],除了有类似μC/OS和FreeRTOS 的内核外,也包括TCP/IP协议栈,虚拟文件系统,POSIX 接口,图形用户界面,FreeMODBUS主从协议栈,CAN框架,动态模块等应用组件和驱动框架。商业产品可以免费使用其内核和开源组件。拥有硬实时核心,稳定、实时与可剪裁的性能等特点[2-3]。RT-Thread和μC/OS-Ⅱ的特点对比,如表1所示。
2 基于RT-Thread的多线程任务实时运行仿真
研制的物联网网关使用RT-Thread作为Embedded
基于RT-Thread 的多线程任务实时运行仿真及应用*
崔业梅1 杨焕峥2
1.无锡商业职业技术学院;
2.江苏省无线传感系统应用工程技术研究开发中心
中图分类号:TP311.1
文献标识码:A
文章编号:1007-9416(2021)10-0023-04
嵌入式多线程编程
DOI:10.19695/jki12-1369.2021.10.08
收稿日期:2021-08-05
*基金项目:无锡商业职业技术学院课题“一种嵌入式AI 工业物联网网关的研发与应用”的阶段性研究成果(KJXJ                  20801)
作者简介:崔业梅(1983—),女,江苏东台人,硕士,实验师,高级技师,研究方向:教育学、电路技术。
. All Rights Reserved.
第  39  卷                      数字技术与应用    www.szjsyyy
24
RTOS [4]。使用Keil(MDK-ARM)软件对STM32 MCU进行编程,首先,程序启动后从汇编代码startup_stm32f103xe.s开始运行,通过编译系统提供的一个函数__main(),初始化库函数和应用程序的执行环境。其次,R T -Thread的启动用到了Keil提供的$Sub$$和$Super$$函数的功能,这个是在__CC_ARM编译器环境中的功能,程序从启动文件的__main()函数执行完毕之后,会优先执行$Sub$$main()函数,该函数包含了RT-Thread的初始化过程,通过$Sub$$main()函数的rt_thread_startup()函数来完成R T -T h r ea d 的初始化及启动等,具体有通过rt_hw_board_init()函数实现STM32 HAL库初始化、系统时钟、滴答时钟初始化、GPIO、串口初始化等,然后在rt_application_init()函数中会创建main线程,并将该线程设为就绪状态,main线程含有main_thread_entry()函数,它是用户应用程序main()函数的跳转入口,当程序执行到rt_system_ scheduler_start()函数后,此刻任务调度器已经启动。再次,含有$Super$$main()的线程会立即得到执行,从而转入到main()函数。最后,执行在main()函数里添加的用户应用程序
初始化代码等。如图1所示。
研制的物联网网关通过传感器采集数据,通过NB-IoT通信模块将数据传输到物联网云平台,在Em bedded RTOS的多线程任务中,可以将这个任
务分解成两个子任务,一个子任务不间断地读取传感器数据,并将数据写到共享内存中,另一个子任务周期性的从共享内存中读取数据,并将数据通过NB-
IoT通信模块传输到物联网云平台。在RT-Thread中,使用线程实现任务,线程描述了一个任务执行的运行环境和
所处的优先等级,根据任务的重要性不同可设置相对高低不同的优先级,不同的任务还可以设置相同的优先级,轮流运行[5-6]。使用Proteus软件的VSM Studio Keil编译器仿真RT-Thread多线程任务在STM32 MCU里实时运行,利用LED0指示灯模拟传感器,USART1串口数据传输模拟NB-IoT通信模块,编写的Source Code里main.c文件的开头线程定义如下:
static void led0_thread_entry(void *parameter){while(1){LED0=~LED0;rt_thread_mdelay(500);}}
项目 RT-Thread
μC/OS-Ⅱ 任务调度 分时调度,协作调度,优先级调度
优先级调度 调度算法 多级队列位图调度
纯位图调度
优先级数 256 64 支持任务数 不限
64
任务状态数 5(初始,挂起,就绪,运行,结束)
5(休眠,就绪,运行,挂起,被中断)
表1 RT-Thread 和μC/OS-Ⅱ的特点对比
Tab.1  Comparison of features between RT-Thread and μC/OS-Ⅱ
使用RT-Thread 操作系统
图1 RT-Thread 在STM32微控制器中运行的流程
Fig.1  The flow of RT-Thread running in the STM32 microcontroller
2021年第 10 期
25
static void USART1_thread_entry(void *parameter){
while(1){
printf("%s","RT-Thread STM32 RealTime USART1 Test!\r\n");
rt_thread_mdelay(500);}}
在main.c文件的main()函数中线程初始化及启动定义如下:
rst1= rt_thread_init(&led0_thread,"led0",
led0_thread_entry,RT_NULL,
&led0_thread_stack[0],sizeof(led0_thread_stack),
RT_THREAD_PRIORITY_MAX-1,20);
rst3= rt_thread_init(&USART1_thread,"USART1",
USART1_thread_entry,RT_NULL,
&USART1_thread_stack[0],sizeof(USART1_thread_stack),RT_THREAD_PRIORITY_MAX-3,20);
if(rst1==RT_EOK&&rst3==RT_EOK){rt_thread_startup(&led0_thread);rt_thread_startup(&USART1_thread);}while(1){
rt_thread_mdelay(100);}
定义了led0_thread_entry()和USART1_thread_entry()两个线程,分别实现LED0闪烁和通过USART1输出字符串。通过函数rt_thread_init()对线程进行初始化,通过函数rt_thread_startup()使线程实现就绪,调度器会调度就绪的线程使其进入运行,通过rt_thread_delay()等函数使运行的线程进入挂起,如果等待超时将返回就绪,
通过rt_thread_delete()函数使线程实现关闭或线程运行结束时执行rt_thread_exit()函数实现关闭。Proteus软件仿真结果如图2所示。
在STM32 MCU中运行RT-Thread,实现了LED0、USART1等多线程任务的实时运行,L ED 0不停闪烁,USART1不断输出字符串“RT-Thread STM32 RealTime USART1 Test!”,解决了系统需要控制多个复杂的外设,如果中断很多,中断时间执行过长,将导致比它优先级低的中断被抢占而无法执行等问题。
3 多线程任务实时运行在物联网网关中的应用
研制的物联网网关采用STM32 MCU,包含传感器、NB-IoT通信模块、RS-485电路、LED指示灯、继电器和LCD等。可以通过多路传感器采集数据,通过NB-IoT通信模块将数据发送到物联网云平台,可
以通过云平台下发命令控制继电器开关。使用RT-Thread实现多线程任务实时运行,内核使用了调度器,信号量等,调度器是为了创建多个线程来实现不同的工作,信号量是用来实现线程间的同步。组件部分使用了UART和SENSOR框架,UART框架指使用了2个串口,分别连接NB-IoT通信模块和RS-485电路,分别用于跟物联网云平台和外设通信,SEN SOR框架指使用传感器采集数据。通过RT -Thread对外设进行初始化,硬件驱动初始化,各个软件包初始化,初始化后进入传感器采集数据、LCD显示、RS-485数据传输线程,轮询线程,如图3所示。
STM32 MCU部分程序如下://初始化线程函数
void MX_RT_Thread_Init(void){
//初始化SENSOR1线程
rt_thread_init(&sensor1_thread,"sensor1",sensor1_task_entry,RT_NULL,&rt_sensor1_thread_stack[0],sizeof(rt_sensor1_thread_stack),3,20);
//初始化LCD线程
rt_thread_init(&LCD_thread,"LCD",LCD_task_entry,RT_NULL,&rt_LCD_thread_stack[0],sizeof (rt_LCD_thread_stack),3,20);
//初始化RS-485通信线程
rt_thread_init(&RS485_thread,"RS485",RS485_task_entry,RT_NULL,&rt_RS485_thread_
崔业梅 杨焕峥:基于R T -T h r e a d 的多线程任务实时运行仿真及应用
. All Rights Reserved.
第  39  卷                      数字技术与应用    www.szjsyyy
26
stack[0],sizeof(rt_RS485_thread_stack),3,20);
//开启线程调度
rt_thread_startup(&sensor1_thread);rt_thread_startup(&LCD_thread);rt_thread_startup(&RS485_thread);}//主任务
void MX_RT_Thread_Process(void){
printf("***基于RT-Thread的多线程任务实时运行仿真及应用***\r\n");
rt_thread_delay(2000);}
//SENSOR1任务void sensor1_task_entry(void *parameter){}
//LCD任务
void L CD _task_en try(void *parameter) {}
//RS-485任务
void RS485_task_entry(void *parameter){}
程序包含了初始化S E N S O R 1、LCD和RS-485通信线程等,并开启了它们的线程调度,SENSOR1线程的任务用于读取温度传感器的数据,LCD线程的任务用于将数据在液晶屏上显示,RS-485线程的任
务用于将数据传输给外设等,程序在研制的物联网网关
STM32 MCU中能稳定运行。
4 结语
RT-Thread拥有硬实时核心,具有稳定、实时与可剪裁的性能,具有全抢占的Embedded RTOS内核、轻型的TCP/IP协议栈和多窗口多线程图形用户界面等特点,是一种“小而美”的物联网操作系统。分析了RT-Thread在物联网网关的STM32微控制器中运行的流程,编写了程序,利用Proteus软件实现了多线程任务实时运行仿真,在物联网网关的STM32 MCU中使用,能稳定运行,解决了物联网网关程序的多任务协调与实时工作的问题。
引用
[1] 叶宏.国产嵌入式操作系统:在信息技术变迁中成长、发展与壮大[J].单片机与嵌入式系统应用,2021(3):3.
[2] 祎邱,熊谱翔,朱天龙.嵌入式实时操作系统:RT-Thread 设计与实现[D].北京:机械工业出版社,2019.
[3] 祎邱.RT-Thread:两大安全措施保障嵌入式软件开发的安全[J].电子产品世界,2021(4):9.
[4] 陈梦亮.基于嵌入式Linux 的物联网网关设计与实现[D].长沙:湖南大学,2020.
[5] 孙晋.基于北斗短报文和RT-Thread 的远程通信系统设计[D].南京:南京信息工程大学,2020.
[6] 张帝,权悦,国海,等.基于LoRa 与RT-Thread 的多功能矿灯设计[J].工矿自动化,2021(6):96-102.
图3 基于RT-Thread 的多线程任务实时运行程序框图Fig.3  Block diagram of real-time operation of multi-threaded tasks based on RT-Thread
图2 Proteus 软件的RT-Thread 多线程实时运行仿真Fig.2  RT-Thread multi-thread real-time running simulation of Proteus software