RT-Thread操作系统

  • Post author:
  • Post category:其他


一、

RT-Thread与UCOS的简单比较



任务或线程调度


RT-Thread可选优先级抢占式调度,256/32/8个优先级,线程数不限。相同优先级线程时间片轮转调度。支持动态创建/销毁线程。

Ucos优先级抢占式调度。不允许相同优先级任务存在。256个优先级,最大256个任务。

FreeRTOS优先级抢占式调度,允许存在相同优先级线程。任务数不受限制。


同步/通信机制:


RT-Thread支持semaphore、mutex、mailbox、message queue、event。mailbox可存储多条消息,任务等待可按照优先级进行排队。

UCOS信号量、互斥量、事件集、邮箱(邮箱最多只能存放一条消息),消息队列。

FreeRTOS信号量、互斥量、消息队列。


内存管理:


RT-Thread固定分区内存管理,小内存系统动态内存管理,大内存系统SLAB内存管理。

FreeRTOS动态内存。

UCOS固定大小内存管理。


定时器:


RT-Thread挂接到系统OS定时器的硬件定时器。

FreeRTOS依赖vTaskDelat()进行时间间隔处理。

UCOS只能使用OSTimeDly进行时间间隔处理。


中断嵌套:


RT-Thread–允许

FreeRTOS-允许

UCOS –不允许


二、RT-Thread的优点


RT-Thread是由中国开源社区主导开发的开源实时操作系统。它的优点是精巧、高效、稳定的实时内核。


三、使用RT-Thread开发的理由


免费开源

精巧、稳定、高效的实时内核,同时也是经过产品考核的实时内核。

由国内一批技术功底深厚的开发者进行维护

该系统支持ARM Cortex-M3系统移植分支尤其对STM32提供了功能齐全的BSP开发包。实现驱动包括:串口、网络、SD卡、USB接口等;支持所有系统组件:基本系统、TCP/IP协议栈。文件系统、图形界面。

开发周期短,采用STM32芯片、稳定性高、实时性高。健壮、高效、可靠性高、实时性强。提供丰富的驱动。


四、使用多线程平台进行开发的要点


1、“多线程”:RT-Thread操作系统是基于多线程的实时操作系统。线程是RT-Thread的线程管理是进行下一步开发的基础。

2、以对象的编程思想使用C语言:RT-Thread实时操作系统中包含一个小型的、非常紧凑的对象系统。这个对象系统完全采用C语言。

3、熟练使用RealView MDK420编译调试平台、不同容量的STM32处理器需要进行一些相应的配置的改动。


五、RT-Thread结构组成


在运行RT-Thread之前,我们需要安装RealView MDK(正式版或评估版)4.2+,它不仅是软件仿真工具也是编译器连接工具。

/*************************************************************************************************************************/

文章将采用连载的形式,从内核线程、线程间各种通信机制、各种组件的使用等方面一 一做介绍。另外文章主要讲解 RT-thread 的相关使用方法,即如何应用,而不是分析RT-thread 的内部具体实现机制。

 硬件平台

后续例子中所牵扯到的软硬件实验环境如下: 操作系统:Windows XP SP3 开发编译环境:Keil MDK 4.54 版

对应硬件平台: stm32 RT_thread 综合实验平台 仿真器:STlink

RT-thread 版本:1.1.0 版 如果读者使用别的硬件平台,请稍改下里面的源码,使之与自己的目标板对应。

第一篇:认识 RT-thread

日期:2013-03-02

 RT-thread 简介

RT-Thread(实时线程操作系统)是国内 RT-Thread 工作室精心打造的稳定的开源实时 操作系统,“她”是 RTT 核心成员历时 4 年,呕心沥血研发,力图突破国内没有小型稳定的 开源实时操作系统局面的开山之作,曾获得“第六届中日韩开源软件竞赛”技术优胜奖(其 他两个技术优胜奖获得者为淘宝的 OceanBase 和红旗的 Qomo Linux)

它不仅仅是一款开源 意义的硬实时操作系统

(不是软的哦),也是一款产品级别的实时操作系统,目前已经被国 内十多家企业采用,被证明是一款能够稳定持续运行的操作系统。

RT-Thread 实时操作系统核心是一个高效的硬实时核心,它具备非常优异的实时性、稳 定性、可剪裁性,当进行最小配置时,内核体积可以到 3k ROM 占用、1k RAM 占用。目前 RT-thread 支持的分支和包含的组件如下:

分支:

  • ARM Cortex-M3: STM32F1, STM32F2, LPC176xx, LPC18xx, LM3S, EFM32, MB9BF

  • ARM Cortex-M4: STM32F4, LM4S, LPC4300

  • ARM7TDMI: LPC2478, LPC2148, AT91SAM7S, AT91SAM7X, S3C44B0

  • ARM720T: SEP4020

  • ARM9: AT91SAM9260, S3C2440

  • NIOS-II

  • XILINX MicroBlaze

  • AVR32

  • Blackfin 533

  • MIPS: PIC32, Jz47xx

  • PPC450: taihu

  • x86

  • windows simulator (VC++)

组件

  • CMSIS, CMSIS-RTOS

  • RT-Thread DFS 文件系统:devfs, ELM FatFs, JFFS2, NFS, romfs, UFFS, YAFFS2

  • finsh shell (类似命令行的组件,RTT 的亮点哦)

  • libc: armlibc(针对 Keil MDK), newlib

  • POSIX: pthreads, libdl

  • 网络:lwIP 1.4.0

  • RT-Thread GUI

  • lua

  • Device Drivers: IIC, MTD NOR/NAND, RTC, SDIO, serial, SPI Bus/Device, USB device/host

 RT-thread 授权

我们使用操作系统,应该都会考虑一个收费问题,使用 RT-thread,我们就不用担心这 个问题了。RT-Thread 采用 GPL-V2 发布,并且承诺永久不会针对使用 RT-Thread 收费,用 户只需要保留 RT-Thread 的 LOGO 既可以免费使用。

 下载 RT-thread 源码、资料

RT-thread 最新稳定版是 1.1.0 版,我们可登陆 RT-thread 官方网站


http://www.rt-thread.org

,点击如下图中红色框中的超链接进行下载,同时也可以下载到其 编程指南。

RT-thread 工作室人员除了进行 RT-thread 操作系统及其组件的开发维护外,还主导了 一些较大开源的软硬件项目,这些项目在其论坛中都可以找得到,也可以跟着这些开源项目 去深入学习 RT-thread 的使用。

第二篇 感受 RT-thread

日期:2013-03-12

 RT-thread 源码目录结构介绍 解压源码后,会看到如下的文件和文件夹:

接下来简单说说各文件夹、文件的作用。 Bsp — 包含 RT-thread 的各个移植分支;

components — 包含 RT-thread 的各中组件:finsh、文件系统、网路协议栈等;

documentation — 一些介绍性的文档,包括其代码风格的要求;

examples — 各种示例代码,是很好的学习素材;

include — 一些头文件;

libcpu — 各种 CPU 体系结构下的相关移植; src — RT-thread 内核核心代码;

tools — 使用 scon 工具编译时的一些相关文件;

AUTHORS — RT-thread 开发者列表

COPYING — 权限说明

 第一次运行 RT-thread

RT-thread 成员已经为我们做好了各种平台下的移植,我们打开 bsp 目录下,stm32f10X 系列的对应分支,双击 MDK 下工程 project.Uv2,打开工程。

这个示例工程包含了 RT-thread 的内核、finsh 组件这两个最基本的部分,主代码完成 了从 RT-thread 的启动到创建一个闪灯线程的过程,程序运行时会通过串口打印运行信息。 我们根据目标板上的 LED 和串口引脚对应关系修改一下程序。

目标板 LED、串口电路如下:

led.c 中我们用 GPIOF8、GPIOF9 来替换原来的 GPIOE2、GPIOE3:

程序中默认使用串口 1 作为终端,针对我的目标板就无需改了,如果你的板子串口不是 串口 1,则改动下面两处:

board.h 中:

rt_config.h 中:

编译后下载到目标板运行,我们会看到 D5 LED 灯以 1Hz 的频率闪烁,同时串口输出了 系统启动信息:

OK,到这里,RT-Thread 就算是在我们的目标板上正常的运行起来了,是不是很简单呢? 赶紧试试吧,心动不如行动!

第三篇 搭建 RTT 最小系统工程

日期:2013-03-24

 建立自己的 RT-Thread 工程

为了后续增加例程方便,我重新生成了一个工程,见《篇 3-例程 1-重构 RTT 最小系统》, 这个工程提取了官方 bsp 包中 stm32 分支中的相 关文件,重新组织文件结构,按照下图中 的文件分配,重新生成了工程。

project ——存放 MDK 工程文件;

RT-thread ——存放 rtt 源码包(放在最外层);

apps ——存放我们自己(用户)写的一些应用代码; drivers ——存放硬件外设驱动;

third_part ——存放第三方程序源码,比如 stm32 固件库、解码库等; obj ——目标文件;

这么一来,各类代码分类一清二楚,后续的例程都会按照这种格式去处理。 例程将闪灯功能换成了流水灯功能,MDK 下文件目录如下图:

 RT-Thread 启动过程

我们分析一个系统的启动过程,一般都从 main 函数开始,我们点开 startup.c 找到 main 函数,main 函数就下面 3 行:

第一行是关中断的操作,第三行是返回退出(永远都执行不到),那么看来 Rt-Thread 的启动就在第二行中进行的,我们贴上 rtthread_startup()的内容来大致浏览一下其启动过 程:

上面的函数完成了系统启动前的所有初始化动作,包括必要的硬件初始化、堆栈初始化、 系统相关组件初始化、用户应用程序初始化,然后启动调度机制。其中和用户密切想关的就 是 rt_application_init()函数,用户线程的创建入口就在这个函数中(此函数函数名用户可 自定义)。

 RT-Thread 的裁剪

我们在上面的启动函数中看到了如下的一些宏定义:

这些宏定义就是为了 RT-Thread 的可裁剪性而做的,对于其裁剪配置,我们在 rt_config.h 中进行,每个配置项的详细解释,请参考配置项上的英文解释和《RT-Thread 编 程指南》。我们在应用过程中,要根据实际的使用情况来选择打开或屏蔽掉某些功能。

第四篇 线程基本知识

日期:2013-03-24

 什么叫线程?

人们在生活中处理复杂问题时,惯用的方法就是“分而治之”,即把一个大问题分解成 多个相对简单、比较容易解决的小问题,小问题逐个被解决了,大问题也就随之解决了。同 样,在设计一个较为复杂的应用程序时,也通常把一个大型任务分解成多个小任务,然后通 过运行这些小任务,最终达到完成大任务的目的。

在 RT-Thread 中,与上述小任务对应的程序实体就叫做“线程”(或任务),RT-Thread 就是一个能对这些小“线程”进行管理和调度的多“线程”操作系统。

 线程的组成

RT-Thread 中的“线程”一般由三部分组成:线程代码(函数)、线程控制块、线程堆栈,我们来看看《篇 3-例程 1-重构 RTT 最小系统》中的流水灯线程是如何构造的。

 线程代码:

上面即是一个典型的线程代码结构—无限死循环,当然还有一种线程结构是顺序执行的, 比如初始化线程,它执行到 return(),就会返回,当其返回后,系统会在 idle 线程中将 其删除,从而使其退出调度队列。一般情况下用户线程都将是一个无限循环结构。

 线程控制块:

static struct rt_thread led_thread;

其中线程控制块 rt_thread 结构体具体内容如下:

struct rt_thread

{


/* rt object */

char name[RT_NAME_MAX]; /

< the name of thread */

rt_uint8_t type; /

< type of object */

rt_uint8_t flags; /**< thread’s flags */

#ifdef RT_USING_MODULE

void *module_id; /**< id of application module */

#endif

rt_list_t list; /

< the object list */

rt_list_t tlist; /

< the thread list */

/* stack point and entry */

void *sp; /

< stack point */

void *entry; /

< entry */

void *parameter; /

< parameter */

void *stack_addr; /

< stack address */

rt_uint16_t stack_size; /**< stack size */

/* error code */

rt_err_t error; /**< error code */

rt_uint8_t stat; /**< thread stat */

/* priority */

rt_uint8_t current_priority; /

< current priority */

rt_uint8_t init_priority; /

< initialized priority */

#if RT_THREAD_PRIORITY_MAX > 32

rt_uint8_t number; rt_uint8_t high_mask;

#endif

rt_uint32_t number_mask;

#if defined(RT_USING_EVENT)

/* thread event */ rt_uint32_t event_set; rt_uint8_t event_info;

#endif

rt_ubase_t init_tick; /**< thread’s initialized tick */

UP MCU 工作室 14 / 17

http://shop73275611.taobao.com/

它记录了线程的各个属性,系统用线程控制块链表对其进行管理

 线程堆栈:

static rt_uint8_t led_stack[ 512];

线程堆栈是一段连续的内存块,当线程切换后,为了满足线程切换和响应中断时保存 cpu 寄存器中的内容及任务调用其它函数时的准备,每个线程都要配有自己的堆栈

 创建一个我们自己的线程 前面说了这么多,我们还是来自己建立一个线程,这样的话印象更深刻。

RT-Thread 中的线程分为静态线程(线程堆栈由编译器静态分配)和动态线程(线程堆 栈由系统动态分配),在例程《篇 4-例程 1-自己创建静态、动态线程》中我们分别建立一 个静态线程和动态线程,这两个线程的任务都是使板上的 LED 灯以 1Hz 频率闪烁。

编译此例程下载到板子中运行,我们看到 D3、D4 灯以同样的节奏闪烁,同时串口也打 印出了如下的运行信息:



版权声明:本文为mycsdn_liruilin原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。