RT-Thread操作系統

一、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 燈以同樣的節奏閃爍,同時串口也打 印出瞭如下的運行信息:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章