RT-Thread是一款完全由国内团队开发维护的嵌入式实时操作系统(RTOS),具有完全的自主知识产权。
经过16个年头的沉淀,伴随着物联网的兴起,它正演变成一个功能强大、组件丰富的物联网操作系统。
RT-Thread,全称是Real Time-Thread,顾名思义,它是一个嵌入式实时多线程操作系统,基本属性之一是支持多任务,允许多个任务同时运行并不意味着处理器在同一时刻真地执行了多个任务。
事实上,一个处理器核心在某一时刻只能运行一个任务,由于每次对一个任务的执行时间很短、任务与任务之间通过任务调度器进行非常快速地切换(调度器根据优先级决定此刻该执行的任务),给人造成多个任务在一个时刻同时运行的错觉。
在RT-Thread系统中,任务通过线程实现的,RT-Thread中的线程调度器也就是以上提到的任务调度器。
RT-Thread主要采用C语言编写,浅显易懂,方便移植。
它把面向对象的设计方法应用到实时系统设计中,使得代码风格优雅、架构清晰、系统模块化并且可裁剪性非常好。
针对资源受限的微控制器(MCU)系统,可通过方便易用的工具,裁剪出仅需要3KB Flash、1.2KB RAM内存资源的NANO版本。
而对于资源丰富的物联网设备,RT-Thread又能使用在线的软件包管理工具,配合系统配置工具实现直观快速的模块化裁剪,无缝地导入丰富的软件功能包,实现类似Android的图像界面及触摸滑动效果,智能语音交互效果等复杂功能。
相较于Linux操作系统,RT-Thread体积小,成本低、功耗低、启动快速,实时性高、占用资源小,非常适用于各种资源受限(如成本、功耗限制等)的场合。
虽然32位MCU是它的主要运行平台,实际上很多带有MMU,基于ARM9、ARM11甚至Cortex-A系列级别CPU的应用处理器在特定应用场合也适合使用RT-Thread。
近年来,物联网(Internet Of Things, IoT)概念广为普及,物联网市场发展迅猛,嵌入式设备的联网已是大势所趋。
终端联网使得软件复杂性大幅增加,传统的RTOS内核已经越来越难满足市场的需求,在这种情况下,物联网操作系统(IoT OS)的概念应运而生。
物联网操作系统是指以操作系统内核(可以是RTOS、Linux等)为基础,包括如文件系统、图形库等较为完整的中间件组件,具备低功耗、安全、通信协议支持和云端连接能力的软件平台,RT-Thread就是一个IoT OS。
RT-Thread与其他很多RTOS,如FreeRTOS、UC/OS的主要区别之一是,还具备丰富的中间层组件,如下图所示。
它具体包括以下部分:
RT-Thread已经支持的软件包数量已经达到400+,如下举例:
物联网相关的软件包:Paho MQTT、WebClient、mongoose、WebTerminal 等等。
脚本语言相关的软件包:目前支持 Lua、JerryScript、MicroPython、PikaScript。
多媒体相关的软件包:Openmv、mupdf。
工具类软件包:CmBacktrace、EasyFlash、EasyLogger、SystemView。
系统相关的软件包:RTGUI、Persimmon UI、lwext4、partition、SQLite 等等。
外设库与驱动类软件包:RealTek RTL8710BN SDK。
其他。
一般嵌入式操作系统因为它的特殊性,往往和硬件平台密切相关连,具体的嵌入式操作系统往往只能在特定的硬件上运行。
对于刚接触RT-Thread操作系统的读者并不容易马上就获得一个和RT-Thread操作系统相配套的硬件模块,但随着计算机技术的发展,我们可以采用软件方式来模拟一个能够运行RT-Thread操作系统的硬件模块,这就是ARM公司的MDK-ARM仿真模拟环境。
内核是一个操作系统的核心,是操作系统最基础也最重要的部分。
它负责管理系统的线程、线程间通信、系统时钟、中断及内存等。
内核处于硬件层之上,内核部分包括内核库、实时内核实现。
内核库是为了保证内核能够独立运行的一套小型的类似C库的函数实现子集。
这部分根据编译器的不同自带C库的情况也会有些不同,当使用GNU GCC编译器时,会携带更多的标准C库实现。
C库:也叫C运行库(C Runtime Library),它提供了类似“strcpy”等函数的实现,RT-Thread Kernel Service Library仅提供内核用到的一小部分C库函数实现,为了避免与标准C库重名,在这些函数前都会添加上rt_前缀。
实时内核的实现包括:对象管理、线程管理及调度器、线程间通信管理、时钟管理及内存管理等等,内核最小的资源占用情况是 3KB ROM,1.2KB RAM。
线程是RT-Thread操作系统中最小的调度单位,线程调度算法是基于优先级的全抢占式多线程调度算法,即在系统中除了中断处理函数、调度器上锁部分的代码和紧张中断的代码是不可抢占的之外,系统其它部分都是可以抢占的,包括线程调度器自身。
支持256个线程优先级(也可通过配置文件更改为最大支持 32 个或 8 个线程优先级,针对 STM32 默认配置是 32 个线程优先级)。
0优先级代表最高优先级,最低优先级留给空闲线程使用。
同时它也支持创建多个具有相同优先级的线程,相同优先级的线程间采用时间片的轮转调度算法进行调度,使每个线程运行相应时间。
调度器在寻找那些处于就绪状态的具有最高优先级的线程时,所经历的时间是恒定的,系统也不限制线程数量的多少,线程数目只和硬件平台的具体内存相关。
RT-Thread的时钟管理以时钟节拍为基础,时钟节拍是RT-Thread操作系统中最小的时钟单位。
RT-Thread的定时器提供两类定时器机制:第一类是单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动停止。
第二类是周期触发定时器,这类定时器会周期性触发定时器事件,直到用户手动的停止定时器,否则将永远持续执行下去。
另外,根据超时函数执行时所处的上下文环境,RT-Thread的定时器可以设置为HARD_TIMER模式或者SOFT_TIMER模式。
通常使用定时器定时回调函数(即超时函数),完成定时服务。
RT-Thread采用信号量、互斥量与事件集实现线程间同步。
线程通过对信号量、互斥量的获取与释放进行同步;
互斥量采用优先级继承的方式解决了实时系统常见的优先级翻转问题。
线程同步机制支持线程按优先级等待方式获取信号量或互斥量。
线程通过对事件的发送与接收进行同步。
事件集支持多事件的“或触发”和“与触发”,适合于线程等待多个事件的情况。
RT-Thread支持邮箱和消息队列等通信机制。
邮箱中一封邮件的长度固定为4字节大小。
消息队列能够接收不固定长度的消息,并把消息缓存在自己的内存空间中。
邮箱效率较消息队列更为高效。
邮箱和消息队列的发送动作可安全用于中断服务例程中。
通信机制支持线程按优先级等待方式获取。
RT-Thread支持静态内存池管理及动态内存堆管理。当静态内存池具有可用内存时,系统对内存块分配的时间将是恒定的;当静态内存池为空时,系统将申请内存块的线程挂起或阻塞掉(即线程等待一段时间后仍未获得内存块就放弃申请并返回,或者立刻返回。等待的事件取决于申请内存块时设置的等待时间参数),当其它线程释放内存块到内存池时,如果有挂起的待分配内存块的线程存在的话,则系统会将这个线程唤醒。
动态内存堆管理模块在系统资源不同的情况下,分别提供了面向小内存系统的内存管理算法、面向大内存系统的SLAB内存管理算法。
还有一种动态内存堆管理叫做memheap,适用于系统含有多个地址且不连续的内存堆。
使用memheap可以将多个内存堆“粘贴”在一起,让用户操作起来像是在操作一个内存堆。
RT-Thread将PIN、I2C、SPI、USB、UART等作为外设设备,统一通过设备注册完成。
实现了按名称访问的设备管理子系统,可按照统一的API界面访问硬件设备。
在设备驱动接口上,根据嵌入式系统的特点,对不同的设备可以挂接相应的事件。当设备事件触发时,由驱动程序通知给上层的应用程序。