日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

RT-Thread1

 Jessica小館子 2014-03-17
[
你可以任意轉(zhuǎn)載本文,但轉(zhuǎn)載請保留本段聲明。
作者將盡量追求內(nèi)容的正確,但不對正確性作出保證。
未經(jīng)作者許可,不得用于商業(yè)目的。
作者:byeyear/告別年代
Email: byeyear@hotmail.com
]

RT-Thread是一個嵌入式實時操作系統(tǒng)核心,采用GPLv2授權(quán)。我從09年開始知道有RT-Thread這個東西,當時其功能與uc/OS類似,如今三年多過去,RT-Thread已經(jīng)成長為哥斯拉了。其支持的arch和芯片大大增加,并且其外圍組件也相當豐富,包括GUI、TCP/IP、FileSystem,支持模塊動態(tài)加載,有興趣的可以訪問其網(wǎng)址:
www.

寫在前面
在我閱讀一些代碼分析的文章時,經(jīng)常發(fā)生的情況是,代碼能看明白,知道這段代碼是做什么的,但就是不明白為什么要這么做。本文希望能做到的一點是,不僅要分析代碼“做了什么”,還要分析“為什么要這么做”。

為什么要做代碼分析的工作
學習,并在學習中更好的理解,從而能夠更好的使用。

RT-Thread官網(wǎng)已經(jīng)對RTT的內(nèi)核做了簡要介紹,參見:
http://www./dokuwiki/doku.php?id=rt-thread%E7%BC%96%E7%A8%8B%E6%8C%87%E5%8D%97
對于上述文檔已經(jīng)介紹過的內(nèi)容,本文將不再介紹。建議先看上述文檔,本文使用的一些名詞和術(shù)語直接引自上文。在上述文檔的基礎(chǔ)上,本文希望挖掘出一些更細節(jié)的東西。

分析過程盡量不涉及具體的硬件平臺。在必要時,使用AT91SAM7X 這個BSP作為例子,KEIL對該CPU實現(xiàn)了完善的軟件仿真,可以一邊分析一邊在模擬器上跑。

我假定您熟悉使用RT-Thread進行開發(fā)的基本過程,能夠使用RT-Thread完成一個簡單的應用。

開始
我們從內(nèi)核對象開始。
RT-Thread操作系統(tǒng)的所有內(nèi)核對象定義于rtdef.h。所有內(nèi)核對象有一個公共成員rt_object,定義如下:

  1. struct rt_object
  2. {
  3.   /* name of kernel object */
  4.   char       name[RT_NAME_MAX];
  5.   /* type of kernel object  */
  6.   rt_uint8_t  type;
  7.   /* flag of kernel object */
  8.   rt_uint8_t  flag;
  9.   /* list pointer of kernel object  */
  10.   rt_list_t list;
  11. };
復制代碼



為什么要給對象命名?

name保存著對象的名字。盡管就操作系統(tǒng)自身的運行而言,對象名稱并不是必須的,但為其命名可以使我們在調(diào)試時區(qū)分各個對象。FinSH組件可以打印出對象名稱。


建議的命名規(guī)則

以下是我在使用RTT和其他一些RTOS(如uc/OS)的過程中自己使用的一套對象命名規(guī)則:

對象類型+對象名稱

對象類型使用兩個字符表示。例如,td表示thread,mx表示mutex。

假如我有一個Thread,函數(shù)名為PollUserInput,那么我給這個thread命名為tdPUI。這樣,一方面防止對象名重復,另一方面,在使用FinSH調(diào)試時,可以根據(jù)對象名知道該對象的用途。



flag有什么用?

例如,flag中有一位表示該對象是系統(tǒng)對象(靜態(tài)分配)還是動態(tài)對象。當一個對象不再使用時,將根據(jù)這一位決定是否釋放對象所占據(jù)的內(nèi)存。



list

有了這個成員,各個相同類型的對象就可以形成鏈表,以便管理。



rt_object成員一般放置于各對象的開頭。例如:

  1. struct rt_ipc_object
  2. {
  3.   struct rt_object parent;
  4.   rt_list_t suspend_thread;
  5. };
復制代碼


為什么要把rt_object放在開頭?

這就保證了各對象的起始地址同樣就是嵌入在該對象頭部的rt_object的起始地址。這樣我們就可以方便的使用指針統(tǒng)一訪問各對象,而不管該對象是什么類型。


下面這條語句訪問某內(nèi)核對象內(nèi)嵌的rt_object對象中的list成員,而不管該對象是什么類型:

((struct rt_object *)(&some_kernel_obj))->list;



初步了解內(nèi)核對象后,我們來看一個操作系統(tǒng)最基礎(chǔ)的設(shè)施:線程和線程調(diào)度。

線程對象由struct rt_thread描述,定義于rtdef.h中。這里就不再將該結(jié)構(gòu)體列出,直接分析其成員。作用比較明顯的成員不再一一分析,僅分析比較關(guān)鍵的幾個成員。



開頭的4個成員(name, type, flags, list)實際上就是rt_object結(jié)構(gòu)的成員。絕大多數(shù)內(nèi)核對象(rt_sem)在其頭部嵌入一個公共的rt_object結(jié)構(gòu),唯有rt_thread將這四個成員復制過來,應該是出于效率方面的考慮。



接下來的tlist成員也是一個鏈表項,根據(jù)線程狀態(tài)的不同,將利用該表項將線程對象掛到不同的鏈表中去。例如,如果線程處于ready狀態(tài),就將

通過tlist將該線程掛到ready線程鏈表;如果線程處于suspend狀態(tài),就通過tlist將線程掛到suspend線程鏈表。



current_priorityinit_priority

init_priority就是你創(chuàng)建線程時為其指定的優(yōu)先級。一般情況下這兩個值相等。但RTT允許你動態(tài)改變線程的優(yōu)先級,如果你這么做了,那么這兩個值是不相等的。



numberhigh_masknumber_mask

這三個成員用于快速查找當前最高優(yōu)先級的線程。后面我們分析線程調(diào)度時再回到這三個成員上來。



event_setevent_info

用于進程間的IPC。在IPC相關(guān)代碼中再詳細分析其作用。



init_tickremaining_tick

RTT允許多個線程使用同一優(yōu)先級,在同一優(yōu)先級下的線程使用時間片調(diào)度。init_tick就是分配給該線程的時間片。當某個優(yōu)先級的線程剛被選中進入運行態(tài)時,remaining_tick將被賦予init_tick的值,并隨著線程的執(zhí)行而遞減。當remaining_tick遞減到0,表明該線程的時間片用完,同一優(yōu)先級的下一個就緒線程將被選中進入運行態(tài)。



thread_timer

如果你在線程內(nèi)調(diào)用sleep,或者在等待資源時指定了超時,RTT將使用thread_timer計算超時時間。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多