强烈推荐一款国产物联网实时操作系统RT-Thread

Posted 从善若水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了强烈推荐一款国产物联网实时操作系统RT-Thread相关的知识,希望对你有一定的参考价值。

文章目录

强烈推荐一款国产物联网实时操作系统RT-Thread

       RT-Thread,全称是 Real Time-Thread,顾名思义,它是一个嵌入式实时多线程操作系统,基本属性之一是支持多任务,允许多个任务同时运行并不意味着处理器在同一时刻真地执行了多个任务。

       RT-Thread 主要采用 C 语言编写,浅显易懂,方便移植。它把面向对象的设计方法应用到实时系统设计中,使得代码风格优雅、架构清晰、系统模块化并且可裁剪性非常好。针对资源受限的微控制器(MCU)系统,可通过方便易用的工具,裁剪出仅需要 3KB Flash、1.2KB RAM 内存资源的 NANO 版本(NANO 是 RT-Thread 官方于 2017 年 7 月份发布的一个极简版内核);而对于资源丰富的物联网设备,RT-Thread 又能使用在线的软件包管理工具,配合系统配置工具实现直观快速的模块化裁剪,无缝地导入丰富的软件功能包,实现类似 android 的图形界面及触摸滑动效果、智能语音交互效果等复杂功能。

       相较于 Linux 操作系统,RT-Thread 体积小,成本低,功耗低、启动快速,除此以外 RT-Thread 还具有实时性高、占用资源小等特点,非常适用于各种资源受限(如成本、功耗限制等)的场合。虽然 32 位 MCU 是它的主要运行平台,实际上很多带有 MMU、基于 ARM9、ARM11 甚至 Cortex-A 系列级别 CPU 的应用处理器在特定应用场合也适合使用 RT-Thread。


RT-Thread 的架构

       近年来,物联网(Internet Of Things,IoT)概念广为普及,物联网市场发展迅猛,嵌入式设备的联网已是大势所趋。终端联网使得软件复杂性大幅增加,传统的 RTOS 内核已经越来越难满足市场的需求,在这种情况下,物联网操作系统(IoT OS)的概念应运而生。物联网操作系统是指以操作系统内核(可以是 RTOS、Linux 等)为基础,包括如文件系统、图形库等较为完整的中间件组件,具备低功耗、安全、通信协议支持和云端连接能力的软件平台,RT-Thread 就是一个 IoT OS

       RT-Thread 与其他很多 RTOS 如 FreeRTOS、uC/OS 的主要区别之一是,它不仅仅是一个实时内核,还具备丰富的中间层组件,如下图所示。

它具体包括以下部分:

  • 内核层:RT-Thread 内核,是 RT-Thread 的核心部分,包括了内核系统中对象的实现,例如多线程及其调度、信号量、邮箱、消息队列、内存管理、定时器等;libcpu/BSP(芯片移植相关文件 / 板级支持包)与硬件密切相关,由外设驱动和 CPU 移植构成。
  • 组件与服务层:组件是基于 RT-Thread 内核之上的上层软件,例如虚拟文件系统、FinSH 命令行界面、网络框架、设备框架等。采用模块化设计,做到组件内部高内聚,组件之间低耦合。
  • RT-Thread 软件包:运行于 RT-Thread 物联网操作系统平台上,面向不同应用领域的通用软件组件,由描述信息、源代码或库文件组成。RT-Thread 提供了开放的软件包平台,这里存放了官方提供或开发者提供的软件包,该平台为开发者提供了众多可重用软件包的选择,这也是 RT-Thread 生态的重要组成部分。软件包生态对于一个操作系统的选择至关重要,因为这些软件包具有很强的可重用性,模块化程度很高,极大的方便应用开发者在最短时间内,打造出自己想要的系统。RT-Thread 已经支持的软件包数量已经达到 60+,如下举例:
    • 物联网相关的软件包:Paho MQTT、WebClient、mongoose、WebTerminal 等等。
    • 脚本语言相关的软件包:目前支持 JerryScript、MicroPython。
    • 多媒体相关的软件包:Openmv、mupdf。
    • 工具类软件包:CmBacktrace、EasyFlash、EasyLogger、SystemView。
    • 系统相关的软件包:RTGUI、Persimmon UI、lwext4、partition、SQLite 等等。
    • 外设库与驱动类软件包:RealTek RTL8710BN SDK。
    • 其他

实操一把

       你的手上可能没有一个和RT-Thread 操作系统相配套的硬件模块,我们可以使用软件方式来模拟一个能够运行 RT-Thread 操作系统的硬件模块,这里我们使用ARM公司的MDK-ARM 仿真模拟环境。

准备工作

       MDK 开发环境:需要安装 MDK-ARM 5.24 (正式版或评估版,5.14 版本及以上版本均可),这个版本也是当前比较新的版本,它能够提供相对比较完善的调试功能。

       使用 STM32F103 软件仿真 ,还需要下载安装 STM32F103 pack 文件,如果在 MDK 中下载较慢,也可以点击此处下载,下载后双击安装即可。

下载RT-Thread Simulator 例程

传送门
这个例子是一个压缩包文件,将它解压,我们这里解压到 D:/。解压完成后的目录结构如下图所示:

各个目录所包含的文件类型的描述如下表所示:

目录名描述
applicationsRT-Thread 应用程序
rt-threadRT-Thread 的源文件
- componentsRT-Thread 的各个组件目录
- includeRT-Thread 内核的头文件
- libcpu各类芯片的移植代码,此处包含了 STM32 的移植文件
- srcRT-Thread 内核的源文件
- toolsRT-Thread 命令构建工具的脚本文件
driversRT-Thread 的驱动,不同平台的底层驱动具体实现
LibrariesST 的 STM32 固件库文件
kernel-sample-0.1.0RT-Thread 的内核例程

在目录下,有一个 project.uvprojx 文件,它是本文内容所引述的例程中的一个 MDK5 工程文件,双击 “project.uvprojx” 图标,打开此工程文件:

目录组描述
Applications对应的目录为 rtthread_simulator_v0.1.0/applications,它用于存放用户应用代码
Drivers对应的目录为 rtthread_simulator_v0.1.0/drivers,它用于存放 RT-Thread 底层的驱动代码
STM32_HAL对应的目录为 rtthread_simulator_v0.1.0/Libraries/CMSIS/Device/ST/STM32F1xx,它用于存放 STM32 的固件库文件
kernel-sample对应的目录为 rtthread_simulator_v0.1.0/kernel-sample-0.1.0,它用于存放 RT-Thread 的内核例程
Kernel对应的目录为 rtthread_simulator_v0.1.0/src,它用于存放 RT-Thread 内核核心代码
CORTEX-M3对应的目录为 rtthread_simulator_v0.1.0/rt-thread/libcpu,它用于存放 ARM Cortex-M3 移植代码
DeviceDrivers对应的目录为 rtthread_simulator_v0.1.0/rt-thread/components/drivers,它用于存放 RT-Thread 驱动框架源码
finsh对应的目录为 rtthread_simulator_v0.1.0/rt-thread/components/finsh,它用于存放 RT-Thread 命令行 finsh 命令行组件

现在我们点击一下窗口上方工具栏中的按钮​

,对该工程进行编译,如图所示:

       编译的结果显示在窗口下方的 “Build” 栏中,没什么意外的话,最后一行会显示“0 Error(s), * Warning(s).”,即无任何错误和警告。

注:由于工程中包含的内核例程代码较多,若使用的是 MDK 试用版本,则会有 16KB 限制,此时可以只保留某个目标例程的代码(例如内核例程只保留一个 thread_sample.c 参与编译),将其他不用的例程先从工程中移除,然后编译。

       在编译完 RT-Thread/STM32 后,我们可以通过 MDK-ARM 的模拟器来仿真运行 RT-Thread。点击窗口右上方的按钮

或直接按 “Ctrl+F5” 进入仿真界面,再按 F5 开始运行,然后点击该图工具栏中的按钮或者选择菜单栏中的 “View→Serial Windows→UART#1”,打开串口 1 窗口,可以看到串口的输出只显示了 RT-Thread 的 LOGO,这是因为用户代码是空的,其模拟运行的结果如图所示:

提示:我们可以通过输入Tab键或者 help + 回车 输出当前系统所支持的所有命令,如下图所示。

系统启动代码

       一般了解一份代码大多从启动部分开始,同样这里也采用这种方式,先寻找启动的源头。以 MDK-ARM 为例,MDK-ARM 的用户程序入口为 main() 函数,位于 main.c 文件中。系统启动后先从汇编代码 startup_stm32f103xe.s 开始运行,然后跳转到 C 代码,进行 RT-Thread 系统功能初始化,最后进入用户程序入口 main()

下面我们来看看在 components.c 中定义的这段代码:

//components.c 中定义 
/* re-define main function */ 
int $Sub$$main(void) 
 
    rt_hw_interrupt_disable(); 
    rtthread_startup(); 
    return 0; 

在这里 $Sub$$main 函数仅仅调用了 rtthread_startup() 函数。RT-Thread 支持多种平台和多种编译器,而rtthread_startup() 函数是 RT-Thread 规定的统一入口点,所以 $Sub$$main 函数只需调用 rtthread_startup() 函数即可。例如采用 GNU GCC 编译器编译的 RT-Thread,就是直接从汇编启动代码部分跳转到 rtthread_startup() 函数中,并开始第一个 C 代码的执行的。在 components.c 的代码中找到 rtthread_startup() 函数,我们将可以看到 RT-Thread 的启动流程:

int rtthread_startup(void) 
 
    rt_hw_interrupt_disable();
    
    /* board level initalization 
    * NOTE: please initialize heap inside board initialization. 
    */ 
    rt_hw_board_init(); 
    
    /* show RT-Thread version */ 
    rt_show_version(); 
    
    /* timer system initialization */ 
    rt_system_timer_init(); 
    
    /* scheduler system initialization */ 
    rt_system_scheduler_init(); 
    
#ifdef RT_USING_SIGNALS 
    /* signal system initialization */ 
    rt_system_signal_init(); 
#endif 

    /* create init_thread */ 
    rt_application_init(); 
    
    /* timer thread initialization */ 
    rt_system_timer_thread_init(); 
    
    /* idle thread initialization */ 
    rt_thread_idle_init(); 
    
    /* start scheduler */ 
    rt_system_scheduler_start();
     
    /* never reach here */ 
    return 0; 

这部分启动代码,大致可以分为四个部分:

  • 初始化与系统相关的硬件;
  • 初始化系统内核对象,例如定时器,调度器;
  • 初始化系统设备,这个主要是为 RT-Thread 的设备框架做的初始化;
  • 初始化各个应用线程,并启动调度器。

用户入口代码

       上面的启动代码基本上可以说都是和 RT-Thread 系统相关的,那么用户如何加入自己的应用程序的初始化代码呢?RT-Thread 将 main 函数作为了用户代码入口,只需要在 main 函数里添加自己的代码即可。

int main(void)
 
    /* user app entry */ 
    
    return 0; 

跑马灯的例子

       我们 UART#1 中输入 msh 命令:led 然后回车就可以运行起来了,如图所示:

/* 
* 程序清单:跑马灯例程 
*
* 跑马灯大概是最简单的例子,就类似于每种编程语言中程序员接触的第一个程序 
* Hello World 一样,所以这个例子就从跑马灯开始。创建一个线程,让它定时地对 
* LED 进行更新(亮或灭) 
*/ 

int led(void) 
 
    rt_uint8_t count; 
    
    rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT); 
    
    for(count = 0 ; count < 10 ;count++) 
     
        rt_pin_write(LED_PIN, PIN_HIGH); 
        rt_kprintf("led on, count : %d\\r\\n", count); 
        rt_thread_mdelay(500); 
        
        rt_pin_write(LED_PIN, PIN_LOW); 
        rt_kprintf("led off\\r\\n"); 
        rt_thread_mdelay(500); 
     
    return 0; 
 
MSH_CMD_EXPORT(led, RT-Thread first led sample);

其它例子

其他更多的内核示例可以从 kernel-sample-0.1.0 目录下找到。


总结

       RT-Thread 是一款完全由国内团队开发维护的嵌入式实时操作系统(RTOS),具有完全的自主知识产权。经过近 15 个年头的沉淀,伴随着物联网的兴起,它正演变成一个功能强大、组件丰富的物联网操作系统。


RT_Thread官方网站
RT-Thread文档中心
API 参考手册

以上是关于强烈推荐一款国产物联网实时操作系统RT-Thread的主要内容,如果未能解决你的问题,请参考以下文章

一款基于SpringBoot+SpringSecurity的后台管理系统,强烈推荐

国产嵌入式操作系统发展思考

当推荐系统遇到物联网...

推荐一款开源物联网云平台

一款基于SpringBoot + Spring Security的后台管理系统,强烈推荐,直接用

开源项目|软件包应用作品:通用物联网系统平台