RT-Thread RTOS的RT-Thread 开发者自述
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RT-Thread RTOS的RT-Thread 开发者自述相关的知识,希望对你有一定的参考价值。
参考技术A1、诞生
一切东西还得从头谈起。 RT-Thread RTOS,Kernel部分完成于2006年上半年,其IPC部分甚至是年中时才具备相应的雏形。最开始时是因为要为朋友做一个小型的手持设备,而我本人起初又是另一国内老牌RTOS:DOOLOO RTOS开发人员,但这个团队在2005年底已经解散。但朋友的系统要上,用ucos吗,一不熟悉,二看不上。答应朋友的事,总得有解决方法吧,即使是原来的DOOLOO RTOS,因为其仿VxWorks结构,导致它的核心太大,包括太多不必要的东西(一套完整的libc库),这些方案都否决了。怎么办?当时朋友那边也不算太急,先自己写一套内核吧。这个就是源头!(后来虽然朋友的项目夭折了,但这套OS则保留下来了,并开源了,万幸) 当然RT-Thread和原来的DOOLOO RTOS差别还是很大的。DOOLOO RTOS是一种类VxWorks风格的,而RT-Thread则是一种类NucluesPlus风格的,小型、实时、可剪裁。这三个方面RT-Thread可以骄傲的说做得比DOOLOO RTOS都要好很多,小型:RT-Thread核心能够小到4K ROM,1K RAM;实时:线程调度核心是完全bitmap方式,计算时间是完全固定的;可剪裁性,配置文件rtconfig.h包含多种选项,对Kernel细节进行精细调整,对各种组件(文件系统,使用EFSL、ELM FatFs;网络协议栈,finsh shell)进行可选配置。 2、艰难的发展期 在第一个公开板发布后(0.1),RT-Thread意识到了一个问题,光有核心不行。别人如何使用:虽然采用了doxygen风格的注释,并自动产生相应的API文档,但能够使用的人寥寥,有这个功底的人不见得认可你的系统,没相应功底的人也玩不转你的系统。所以下一个系列,考虑如何让系统能够支持更多的平台。首选ARM,为什么?应为ARM正处于发展的前期,使用的人也广泛,而RT-Thread第一个支持的平台就是s3c4510,这个是lumit开源项目赠送的平台。在其后,支持了包括s3c44b0,AT91SAM7S64,AT91SAM7X256,s3c2410,AT91SAM9200,coldfire,x86等一系列平台,编译器统一使用GCC,这个时期无疑是最艰难的时期(真的艰难吗?呵呵,但肯定是迷茫的),这个就是0.2.0、0.2.1、0.2.3、0.2.4版本等,不同的版本支持不同的平台。 猜猜我这段时间是干什么工作的?不知道大家对这个领域是否熟悉,手机2G,3G协议栈开发。每天都和协议栈打交道,而且最痛苦的是上千页的25.331 RRC协议,都是英文的,所以RT-Thread算做是工作之外的苦中作乐吧。而也正是这个时候,shaolin同学出现了,帮助完成了RT-Thread/x86的移植,他当时还是学生。 这其中还有一件郁闷的事,当时RT-Thread团队还有几个人,只不过主要是shaolin和我。当0.2.3发布时,我建议开始微内核的道路,嗯,可能很多人还比较困惑,RT-Thread后面跟着的为什么是“启动下一代RTOS演化”,当时就是因它而感慨:把微内核引入进来,把内核态和用户态分开来,并且建立一个类似于L4的微内核。当然最重要的是,其中有一个强实时核心。而且L4实际上是把页表操作放到内核之外的,如果内核是一个强实时内核将对整个系统的实时性提升很大,而因为微内核的缘故,也能够运行linux的应用程序,并且当时RT-Thread也提出了一种,线程即IPC的概念。。。只是,最后的提案被大家否决了。团队开始有数人,只是能够坚持的没几个。 3、一年增加0.0.1 本人很早就接触了Linux,算是国内资深的Linux接触者(早期也算一个Linux开发人员吧),KDE 1.0几乎是看着发展起来的(大家有谁用过RedHat 5.1?)。个人算是很多方面有一些自由软件的习惯:软件的版本号是非常重要的一个标志,宁愿增加一个细微的版本号也不轻易的增加一个大的版本号,因为大的版本号是需要对用户负责的。1.0版本更代表了系统的稳定性,健全性。例如mplayer到1.0版本就经历众多小版本,0.99的beta版本亦无数。 RT-Thread也把这点体现得淋漓尽致,0.2.2到0.2.3一个版本的增加,整整花了一年多的时间。但这个小版本号的增加,却带来了开源社区嵌入式环境中最完善的TCP/IP协议栈:LwIP。当然,开始时并不算稳定。在这几个版本中,RT-Thread也终于从迷茫中走出来,RT-Thread需要自己的特色,一个单独的RTOS Kernel没太大的用处,因为你并没有上层应用代码的积累,并且一些基础组件也非常重要,有这些基础组件基本上意味着,在这个平台上写代码,这些代码就是你的,甚至是你哪天也可以把它放到另外一个硬件平台上运行。 同样,0.2到0.3版本号的变更,花费的时间会更长^-^ 版本号的长短,是和计划的feature实现是密切相关的,没到设定的目标如何可能进行发布呢? 4、Cortex-M3的变革 RT-Thread的变革因为Cortex-M3而来,因为ST的STM32使用的人太广了,当然还有非常重要的一点。RT-Thread已经开始支持Keil MDK,armcc了。GNU GCC确实好,并且也由衷的推崇它,使用它,只是调试确实麻烦,阻碍了更多人使用它(ARM平台上)。当RT-Thread + Cortex-M3 + Keil MDK碰撞在一起的时候,火花因它而生,越来越多人使用RT-Thread了,当然这和RT-Thread厚积薄发是离不开的,因为这个时候,RT-Thread已经有一个稳定的内核,shell方式的调试利器finsh,DFS虚拟设备文件系统,以及LwIP协议栈。而RT-Thread/GUI则在密集的移植到CM3上,RT-Thread/GUI成型于2008年底,但为了Cortex-M3分支,这个组件停下来很多,但这种停留是值得的。另外就是特别感谢UET赠送的STM32开发板了,RT-Thread/STM32的分支都是在UET赠送的STM32开发板上验证的。 5、RT-Thread为什么是对象化的设计方法 可能这个话题太偏技术化了,说说其他,呵呵。 面向对象编程有它的好处,例如继承。可以让具备相同父类的子类共享使用父类的方法,基本可以说是不用写代码就凭空多出了很多函数,何乐而不为呢。另外,对象的好处在于封装。当一个对象封装好了以后,并测试完成后,基本上就代表这个类是健全的,从这个类派生的子类不需要过多考虑父类的不稳定性。 这里着重提提另外一个人,我工作后的第三年,曾向当时的同事也是好友,L.Huray学习面向对象的实时设计方法:Octpus II。深刻体会到了面向对象设计的好处(需求分析,体系结构设计,子系统分析,子系统设计,测试,实时性分析),但鉴于嵌入式系统中C++的不确定性,所以个人更偏向于使用C来实现。所以,L.Huray算是我的老师了,一直希望能够有时间把他老人家的思想更进一步的发扬光大,希望以后有这个机会。(Octpus I最初起源于Nokia,然后由M.Award, L.Huray发展成Octpus II,现在几乎见不到踪影了,唉)。
(作者原文:实时线程操作系统(RT-Thread)4年开发历程 乐与苦)
RT-Thread快速入门-初探RT-Thread
前言
要学习一项新知识或新的技能,首先要对其有个初步了解,然后再逐步学习如何运用它。
本文作为快速入门 RT-Thread 系列文章的第一篇,首先介绍一下,我当时是如何学习 RT-Thread 的,以及参与官方组织的活动的情况,希望给读者参考,并有所启发。
然后先介绍一下这款国产 RTOS 的大概内容,做到对 RT-Thread 有个初步的了解。
我的 RT-Thread 学习之路
1. 初识 RT-Thread
记得在 2017 年看到公众号一篇文章介绍 RT-Thread,文章结尾留有联系方式,可以拉入官方群,本着学习的目的,果断加微信入群。
那时还不了解 RT-Thread,但是对于 RTOS 已经不陌生。已经学习过 uCos 和 FreeRTOS 两款 RTOS 系统。
国产 RTOS 还是第一次接触,并且能进官方技术交流群,当然要进群去学习了。
在网上搜了一下 RT-Thread 相关资料,简单了解了这款国产的 RTOS。
RT-Thread 内核的第一个版本是熊谱翔先生在 2006 年年初发布的 0.1 版本。发展到现在,已经有十多年的历史了。
因为 RTOS 中的任务更类似于通用操作系统中的线程,并且这个系统支持基于优先级的抢占式任务调度算法。所以把它命名为 RT-Thread,即实时线程。
后来又加了好多官方群,算得上 RT-Thread 的忠实粉丝了。
2. 入门 RT-Thread
由于时间原因,一直没有真正开始学习 RT-Thread。直到 2018 年官方组织 15 天入门 RT-Thread 培训,才开始真正地学习 RT-Thread。每天中午抽时间看当天的视频,然后再实际动手实验,复习课程学习的内容。
当初学习的时候,每天还组织抽奖,既学习了知识,还能获得奖品。除了点赞还能说啥。当然,我运气不错,中了一个开发板(备注:此处不是炫耀)。
感谢 RT-Thread 官方组织的学习活动。课程学习完毕,自我感觉已经入门了。
现在官方视频学习网址如下:
https://www.rt-thread.org/page/video.html
3. 读内核源码
入门学习结束后,觉得不能止于此。当时的想法是要读一读源码,深入到 RTOS 内部机制的实现。
然后,开始每天抽一部分时间研究 RT-Thread 内核源代码。逐渐地把内核源码研究了一遍,弄懂了其设计思想和实现方法。不得不说,代码写的非常棒
基于此,较深入地理解了 RTOS 内核工作原理。感觉功力又上升了一个层次。
4. 参加网络编程学习
后来参加官方组织的 RT-Thread 网络编程学习营。每周一个任务,一共四周。完成后将实现过程形成笔记发布到官方论坛。
那时候学习劲头足,白天上班,晚上回家研究学习任务。有时候为了解决问题,完成任务,甚至熬夜调试代码。当然对于最后的收获,却是值得的。
这期间,不仅对网络通信有深入了解,还接触到了设备与云端通信,还认识了不少小伙伴。
完成网络编程学习营任务发布的文章,如下图
5. 新书提前阅读
同年(2018年)官方组织新书提前阅读评审书籍《嵌入式实时操作系统:RT-Thread设计与实现》,当然要参加啦。
每天阅读一个章节,给出修改意见。在阅读过程中,结合之前学习 RT-Thread 的知识,算是把 RT-Thread 又系统地学习了一遍。
通过对 RT-Thread 的学习,对 RTOS 的原理有了较深入的理解。自认为把 RTOS 相关的基础知识夯实了。
新书出版,官方给送了一本,还有熊大的亲笔签名。
感谢熊大,感谢 RT-Thread 的各位小伙伴,提供了这么好的学习平台。祝愿 RT-Thread 发展得越来越好。
了解 RT-Thread
RT-Thread 是一款完全由国内团队开发维护的嵌入式实时操作系统(RTOS),具有完全的自主知识产权 。
RT-Thread,全称是 Real Time-Thread,它是一个嵌入式实时多线程操作系统,基本属性之一是支持多任务。在 RT-Thread 系统中,任务是通过线程实现的。
RT-Thread 主要采用 C 语言编写,浅显易懂,方便移植。它把面向对象的设计方法应用到实时系统设计中,使得代码风格优雅、架构清晰、系统模块化并且可裁剪性非常好。
RT-Thread 系统完全开源, 3.1.0 及以前的版本遵循 GPL V2 + 开源许可协议。从 3.1.0 以后的版本遵循 Apache License 2.0 开源许可协议,可以免费在商业产品中使用,并且不需要公开私有代码。
RT-Thread 目前分为三个版本:标准版本、Nano 版本、Smart 版本。
详细了解 RT-Thread,可以访问官方网站:
https://www.rt-thread.org
RT-Thread 在线文档网址为:
https://www.rt-thread.org/document/site/#/
1. 标准版
标准版 RT-Thread 与其他很多 RTOS 如 FreeRTOS、uC/OS 的主要区别之一是,它不仅仅是一个实时内核,还具备丰富的中间层组件。
详细介绍可参考官方网站:
https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/README
标准版软件架构如下图所示。
物联网操作系统是指以操作系统内核(可以是 RTOS、Linux 等)为基础,包括如文件系统、图形库等较为完整的中间件组件,具备低功耗、安全、通信协议支持和云端连接能力的软件平台,RT-Thread 就是一个 IoT OS。
2. Nano版本
RT-Thread Nano 是一个极简版的硬实时内核,是一款可裁剪的、抢占式实时多任务的 RTOS。
其内存资源占用极小,功能包括任务处理、软件定时器、信号量、邮箱和实时调度等相对完整的实时操作系统特性。
详细内容可参考官方在线文档网站:
https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-nano/an0038-nano-introduction
Nano 版软件框图如下,包含支持的 CPU 架构与内核源码,还有可拆卸的 FinSH 组件:
3. Smart 版本
RT-Thread Smart 是基于 RT-Thread 操作系统上的混合操作系统,简称为 rt-smart,它把应用从内核中独立出来,形成独立的用户态应用程序,并具备独立的地址空间(32 位系统上是 4G 的独立地址空间)。
详细了解可以访问官方资料网站:
https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/README
rt-smart 的整体结构框图如下,在硬件平台的基础上通过 MMU、系统调用的方式把整个系统分成了内核态及用户态。
RT-Thread 内核
内核是操作系统最基础也是最重要的部分。下图为 RT-Thread 内核架构图,内核处于硬件层之上,内核部分包括内核库、实时内核实现。
内核库是为了保证内核能够独立运行的一套小型的类似 C 库的函数实现子集。这部分根据编译器的不同自带 C 库的情况也会有些不同,当使用 GNU GCC 编译器时,会携带更多的标准 C 库实现。
实时内核的实现包括:对象管理、线程管理及调度器、线程间通信管理、时钟管理及内存管理等等。
内核最小的资源占用情况是 3KB ROM,1.2KB RAM。
线程调度
线程是 RT-Thread 操作系统中最小的调度单位,线程调度算法是基于优先级的全抢占式多线程调度算法。
在系统中除了中断处理函数、调度器上锁部分的代码和禁止中断的代码是不可抢占的之外,系统的其他部分都是可以抢占的,包括线程调度器自身。
支持 256 个线程优先级(也可通过配置文件更改为最大支持 32 个或 8 个线程优先级),0 优先级代表最高优先级,最低优先级留给空闲线程使用。
时钟管理
RT-Thread 的时钟管理以时钟节拍为基础,时钟节拍是 RT-Thread 操作系统中最小的时钟单位。
RT-Thread 的定时器提供两类定时器机制:单次触发定时器、周期触发定时器。
通常使用定时器定时回调函数(即超时函数),完成定时服务。用户根据自己对定时处理的实时性要求选择合适类型的定时器。
线程同步
RT-Thread 采用信号量、互斥量与事件集实现线程间同步。
线程通过对信号量、互斥量的获取与释放进行同步;互斥量采用优先级继承的方式解决了实时系统常见的优先级翻转问题。
线程通过对事件的发送与接收进行同步;事件集支持多事件的 “或触发” 和“与触发”,适合于线程等待多个事件的情况。
线程通信
RT-Thread 支持邮箱和消息队列等通信机制。
邮箱中一封邮件的长度固定为 4 字节大小;消息队列能够接收不固定长度的消息,并把消息缓存在自己的内存空间中。
内存管理
RT-Thread 支持静态内存池管理及动态内存堆管理。
动态内存堆管理模块在系统资源不同的情况下,分别提供了面向小内存系统的内存管理算法及面向大内存系统的 SLAB 内存管理算法。
还有一种动态内存堆管理叫做 memheap,适用于系统含有多个地址且不连续的内存堆。使用 memheap 可以将多个内存堆 “粘贴” 在一起,让用户操作起来像是在操作一个内存堆。
I/O 设备管理
RT-Thread 将 PIN、I2C、SPI、USB、UART 等作为外设设备,统一通过设备注册完成。实现了按名称访问的设备管理子系统,可按照统一的 API 界面访问硬件设备。
在设备驱动接口上,根据嵌入式系统的特点,对不同的设备可以挂接相应的事件。当设备事件触发时,由驱动程序通知给上层的应用程序。
后续计划
作为 RT-Thread 的学习者和受益者,以及对国产 RTOS 的支持。愿意付出自己的绵薄之力,把自己学到的知识形成笔记文章分享出来,供有需要的小伙伴作为学习参考。
首先,会尽量以简单的方式,介绍 RT-Thread 提供的资源如何使用,理论结合实践,达到快速入门的效果。
然后,再以专题的形式,介绍内核源码实现的内部机制。争取做到,知其然,知其所以然。
在写作过程中,难免出现纰漏或者理解偏差的地方,欢迎指正,一起探讨交流。
一起学习、一起进步。加油~
以上是关于RT-Thread RTOS的RT-Thread 开发者自述的主要内容,如果未能解决你的问题,请参考以下文章
RT-Thread RTOS的RT-Thread 开发者自述
RT-Thread RTOS的RT-Thread v2.0.0 RC & v1.2.3版本发布
The Applications of RT-Thread RTOS