紙飛機(jī)四軸網(wǎng)盤(pán)-飛控pid相關(guān)飛行器rtthread manual_第1頁(yè)
紙飛機(jī)四軸網(wǎng)盤(pán)-飛控pid相關(guān)飛行器rtthread manual_第2頁(yè)
紙飛機(jī)四軸網(wǎng)盤(pán)-飛控pid相關(guān)飛行器rtthread manual_第3頁(yè)
紙飛機(jī)四軸網(wǎng)盤(pán)-飛控pid相關(guān)飛行器rtthread manual_第4頁(yè)
紙飛機(jī)四軸網(wǎng)盤(pán)-飛控pid相關(guān)飛行器rtthread manual_第5頁(yè)
已閱讀5頁(yè),還剩288頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

前本書(shū)是RT-Thread的編手冊(cè),用于指導(dǎo)在RT-Thread實(shí)時(shí)操作系統(tǒng)環(huán)境下如何進(jìn)行適合讀變?nèi)招薷娜思尤氡砀裣嚓P(guān)的內(nèi)容;加入API致@larrycaiyu提供本書(shū)的初始模板@grissiom解決本書(shū)的代碼語(yǔ)法高亮問(wèn)題@aozima提示pandoc1.11.1版本已經(jīng)開(kāi)始支持表格操作;后續(xù)開(kāi)始在文檔中加入表格@reynoldxu補(bǔ)足了文檔中的即API說(shuō)明前i1簡(jiǎn)介1RT-Thread的軟件結(jié)構(gòu)................................1開(kāi)發(fā)、.....................................2232.1實(shí)時(shí)系統(tǒng)的需求...................................32.2線調(diào)度器.....................................32.3線控制塊.....................................52.4線狀態(tài)......................................62.5空閑線......................................72.6調(diào)度器相關(guān)接口...................................8 調(diào)度器初始化.................................8 啟動(dòng)調(diào)度器..................................8 執(zhí)行調(diào)度...................................8 設(shè)置調(diào)度器鉤子...............................92.7線相關(guān)接口.................................... 線創(chuàng)建.................................. 線刪除.................................. 線初始化................................. 線脫離.................................. 線啟動(dòng).................................. 當(dāng)前線.................................. 線讓出處理器.............................. 線睡眠.................................. 線掛起..................................2.7.10線恢復(fù)..................................2.7.11線控制..................................2.7.12初始化空閑線..............................2.7.13設(shè)置空閑線鉤子.............................2.8線設(shè)計(jì)...................................... 序的運(yùn)行上下文............................. 線設(shè)計(jì)要 33.1定時(shí)器管理......................................3.2定時(shí)器超時(shí)函數(shù)...................................3.3定時(shí)器管理控制塊..................................3.4定時(shí)器管理接口................................... 定時(shí)器管理系統(tǒng)初始化........................... 創(chuàng)建定時(shí)器.................................. 刪除定時(shí)器.................................. 初始化定時(shí)器................................. 脫離定時(shí)器.................................. 啟動(dòng)定時(shí)器.................................. 停止定時(shí)器.................................. 控制定時(shí)器.................................. 定時(shí)器執(zhí)行上下 44.1關(guān)閉中斷....................................... 使用場(chǎng)合...................................4.2調(diào)度器鎖....................................... 使用場(chǎng)合...................................4.3信號(hào)量.........................................信號(hào)量控制塊.................................信號(hào)量相關(guān)接口...............................刪除信號(hào)量..................................初始化信號(hào)量.................................脫離信號(hào)量..................................獲取信號(hào)量..................................無(wú)等待獲取信號(hào)量..............................釋放信號(hào)量..................................使用場(chǎng)合...................................線同步..................................鎖.......................................中斷與線的同步.............................資源計(jì)數(shù)...........................................................................互斥量控制塊.................................互斥量相關(guān)接口...............................創(chuàng)建互斥量..................................刪除互斥量..................................初始化互斥量.................................脫離互斥量..................................獲取互斥量..................................釋放互斥量.................................. 使用場(chǎng)合............................................................................ 事件控制塊.................................. 事件相關(guān)接口.................................創(chuàng)建事件...................................刪除事件...................................初始化事件..................................脫離事件...................................接收事件...................................發(fā)送事件................................... 使用場(chǎng)合...................................郵箱.......................................... 郵箱控制塊.................................. 郵箱相關(guān)接口.................................創(chuàng)建郵箱...................................刪除郵箱...................................初始化郵箱..................................脫離郵箱...................................發(fā)送郵件...................................等待方式發(fā)送郵件..............................接收郵件................................... 使用場(chǎng)合...................................消息隊(duì)列....................................... 消息隊(duì)列控制塊............................... 消息隊(duì)列相關(guān)接口..............................創(chuàng)建消息隊(duì)列.................................刪除消息隊(duì)列.................................初始化消息隊(duì)列...............................脫離消息隊(duì)列................................. 發(fā)送消息...................................發(fā)送緊急消息.................................接收消息................................... 使用場(chǎng)合...................................典型使用...................................同步消息...................................5內(nèi)存管理靜態(tài)內(nèi)存池管 靜態(tài)內(nèi)存池工作原 靜態(tài)內(nèi)存池控制 靜態(tài)內(nèi)存池接 創(chuàng)建內(nèi)存 刪除內(nèi)存 初始化內(nèi)存 脫離內(nèi)存 分配內(nèi)存 動(dòng)態(tài)內(nèi)存管 小內(nèi)存管理模 SLAB內(nèi)存管理模 動(dòng)態(tài)內(nèi)存接 初始化系統(tǒng)堆空 分配內(nèi)存 重分配內(nèi)存 分配多內(nèi)存 釋放內(nèi)存 設(shè)置分配鉤子函 設(shè)置內(nèi)存釋放鉤子函 更改情 塊設(shè) 設(shè) 卸載設(shè) 初始化所有設(shè) 查找設(shè) 打開(kāi)設(shè) 關(guān)閉設(shè) 讀設(shè) 寫(xiě)設(shè) 控制設(shè) 設(shè)置數(shù)據(jù)接收指 設(shè)置發(fā)送完成指 設(shè)備驅(qū) 設(shè)備驅(qū)動(dòng)必須實(shí)現(xiàn)的接 設(shè)備驅(qū)動(dòng)實(shí)現(xiàn)的步 異常與中 中斷處理過(guò)中斷 中斷的底半處 底半處理實(shí)現(xiàn)范 中斷相關(guān)接 裝載中斷服務(wù)例 中斷 打開(kāi)被的中斷 關(guān)閉中 打開(kāi)中 ARMCortex-M中的中斷與異 外設(shè)中的中斷模式與輪詢(xún)模 應(yīng)用模 功能和限 使用應(yīng)用模 編譯主 使用應(yīng)用模 移植前的準(zhǔn) 建立RealViewMDK工......................... .添加源文 生成MDK工模 添加其他相關(guān)文 配置編譯 scons- scons- scons–target=XXX- scons 修改編譯器選 內(nèi)置函 添加 RT-Thread finsh 195簡(jiǎn) 工作模 初識(shí) 宏方 函數(shù)方 添加內(nèi)置命 finsh(msh)內(nèi)置命 移 宏選 文件系 簡(jiǎn) 文件系統(tǒng)、文件與文件 文件系統(tǒng)接 打開(kāi)文 關(guān)閉文 數(shù) 寫(xiě)入數(shù) 更改名 取得狀 操作接 創(chuàng) 打 220取 流的位 設(shè)置下次的位 重設(shè)的位置為開(kāi)頭位 關(guān) 刪 格式化文件系 底層驅(qū)動(dòng)接 文件系統(tǒng)初始化...............................12.6FatFs........................................FatFs.................................12.7NFS........................................RT-Thread中使用NFS............................主機(jī)配置...................................開(kāi)發(fā)板配置..................................12.8UFFS........................................UFFS配置...................................UFFS................................MTDNAND驅(qū)動(dòng)...............................讀寫(xiě)頁(yè)....................................擦除塊....................................塊狀態(tài)檢查..................................標(biāo)記壞塊...................................移動(dòng)頁(yè)....................................MTDNAND設(shè)備.............................UFFS示例驅(qū)動(dòng)................................12.9 lwIP-輕型TCP/IP協(xié)議 簡(jiǎn) 協(xié)議分 進(jìn)模型(process 操作系統(tǒng)模擬層(OSemulation RT-Thread網(wǎng)絡(luò)設(shè)備管 RT-ThreadlwIP有哪些變 RT-ThreadlwIP相關(guān)代碼補(bǔ)充說(shuō) TCP編指 TCP原理,TCP的狀 TCP編示 擴(kuò)展:: 網(wǎng)絡(luò)編示 TCP使用示 lwIP-IPv6支 lwIP-IPV6概 鄰居發(fā)現(xiàn)協(xié) 僅使用 對(duì)開(kāi)發(fā)板進(jìn)行測(cè) IPv6SocketAPI實(shí) IPv4/v6Socket編異 TCPClient例 UDPServer例 POSIX接 簡(jiǎn) 附錄 標(biāo)題、段落、區(qū)塊代 修辭和強(qiáng) 列 278279代 API說(shuō) 注意事 簡(jiǎn)RT-hread是一款由中國(guó)開(kāi)源社區(qū)主導(dǎo)開(kāi)發(fā)的開(kāi)源嵌入式實(shí)時(shí)操作系統(tǒng)(遵循Gv2許可協(xié)議),它包含實(shí)時(shí)嵌入式系統(tǒng)相關(guān)的各個(gè)組件:實(shí)時(shí)操作系統(tǒng)內(nèi)核,C/IP協(xié)議棧、文件系統(tǒng)、icRT-Thread的軟件圖1.1:RT-Thread軟件組件層,這些是基于RT-Thread基礎(chǔ)上的組件,例如文件系統(tǒng),命令行小巧的內(nèi)核及周邊組件;面向?qū)ο螅?lèi)UNIX的編風(fēng)格開(kāi)發(fā)、RT-hread的主要開(kāi)發(fā)團(tuán)隊(duì)在或者說(shuō)中國(guó)的長(zhǎng)三角地區(qū),大家主要利用業(yè)余時(shí)間進(jìn)行RT-Thread的開(kāi)發(fā)和,同時(shí)也接受開(kāi)發(fā)者,者,以及專(zhuān)業(yè)嵌入式領(lǐng)域公司RT-Thread捐贈(zèng)代碼。RT-hread以一年為開(kāi)發(fā)、發(fā)布周期。-hread的每一個(gè)版本都會(huì)設(shè)定一個(gè)目標(biāo),而后的一年開(kāi)發(fā)周期以這個(gè)為目標(biāo)進(jìn)行開(kāi)發(fā)、演化改進(jìn),同時(shí)按照每個(gè)季度一個(gè)測(cè)試版本的形式進(jìn)行推進(jìn)。發(fā)布的版本包括兩種:一種是正式版本(或者說(shuō)穩(wěn)定版本,版本),例如當(dāng)前的1.1.x正式版本,它1.1.0正式版本的bugfix版本。在功能上并不添加新的功能,而著重于已有bug的修正一種是測(cè)試版本(或者說(shuō)開(kāi)發(fā)版本),例如當(dāng)前的1.2.0beta版本。它是以一年期設(shè)定每個(gè)開(kāi)發(fā)版本會(huì)提前設(shè)定出開(kāi)發(fā)目標(biāo),一般是通過(guò)郵件、后進(jìn)行;同時(shí)每年在也會(huì)有一到兩次的開(kāi)發(fā)者會(huì)議,會(huì)議上會(huì)討論新版本的目標(biāo),或者大版本新的方向。組件(component),基于之上,把一些功能模塊劃分成獨(dú)立的一個(gè)個(gè)組件模塊,做到組件與組件之間的低耦合,組件的高內(nèi)聚;這三部分每部分都有人,人應(yīng)切實(shí)地保證相關(guān)部分的正常運(yùn)行。當(dāng)前的RT-Thread開(kāi)發(fā)版本放在 上,歡迎每個(gè)開(kāi)發(fā)者、者向RT-Thread提交pullrequest。每個(gè)組件、分支的人在收到pullrequest后,會(huì)決定是否合并到開(kāi)發(fā)分支中。開(kāi)發(fā)者、者提交的代碼應(yīng)該符合RT-Thread的編規(guī)范。線調(diào)度與管一個(gè)典型的簡(jiǎn)單序會(huì)設(shè)計(jì)成一個(gè)串行的系統(tǒng)運(yùn)行:按照準(zhǔn)確的指令步驟一次一個(gè)指令的運(yùn)行。但是這種方法對(duì)于復(fù)雜一些的實(shí)時(shí)應(yīng)用是不可行的,因?yàn)樗鼈兺ǔP枰诠潭ǖ臅r(shí)間內(nèi)“同時(shí)”處理多個(gè)輸入輸出,實(shí)時(shí)軟件應(yīng)用序應(yīng)該設(shè)計(jì)成一個(gè)并行的系統(tǒng)。并行設(shè)計(jì)需要開(kāi)發(fā)把一個(gè)應(yīng)用分解成一個(gè)個(gè)小的,可調(diào)度的,序列化的序單元。當(dāng)合理的劃分任務(wù),正確的并行執(zhí)行時(shí),這種設(shè)計(jì)能夠讓系統(tǒng)滿足實(shí)時(shí)系統(tǒng)的性間的要求。實(shí)時(shí)系這個(gè)“時(shí)間內(nèi)”(英文叫做deadline、有時(shí)中文也翻譯成時(shí)間約束),系統(tǒng)會(huì)做一些處例如輸入數(shù)據(jù)的分析計(jì)算,加工處理等。而在這段時(shí)間之系統(tǒng)可能會(huì)空閑下來(lái),例如一個(gè)終端,當(dāng)一個(gè)撥入的時(shí)候,系統(tǒng)應(yīng)當(dāng)及時(shí)發(fā)出振鈴、聲音提示以通知主人有來(lái)電,詢(xún)問(wèn)是否進(jìn)行接聽(tīng)。而在非撥入的時(shí)候,人們可以用它進(jìn)行一些其它工作,例如聽(tīng)音樂(lè),玩游戲等。從上面的例子我們可以看出,實(shí)時(shí)系統(tǒng)是一種需求傾向性的系統(tǒng),對(duì)于實(shí)時(shí)的事件需要在第一時(shí)間內(nèi)做出回應(yīng),而對(duì)非實(shí)時(shí)任務(wù)則可以在實(shí)件到達(dá)時(shí)為之讓路——被搶占。所以實(shí)時(shí)系統(tǒng)也可以看成是一個(gè)等級(jí)系統(tǒng),不同重要性的任務(wù)具有不同的優(yōu)先等級(jí):重要的事件能夠優(yōu)先被響應(yīng)執(zhí)行,非重要的事件可以適當(dāng)往后推遲。在RT-hread實(shí)時(shí)操作系統(tǒng)中,任務(wù)采用了線來(lái)實(shí)現(xiàn),線是R-Thread中最基本的調(diào)度單位,它描述了一個(gè)任務(wù)執(zhí)行的上下文關(guān)系,也描述了這個(gè)任務(wù)所處的優(yōu)先等級(jí)。重要的任務(wù)能擁有相對(duì)較高的優(yōu)先級(jí),非重要的任務(wù)優(yōu)先級(jí)可以放低,并且可以類(lèi)似inux一樣具備分時(shí)的效果。線調(diào)度RT-hread中提供的線調(diào)度器是基于優(yōu)先級(jí)的全搶占式調(diào)度:在系統(tǒng)中除了中斷處理函數(shù)、調(diào)度器上鎖部分的代碼和中斷的代碼是不可搶占的之外,系統(tǒng)的其他部分都是可以搶占的,包括線調(diào)度器自身。系統(tǒng)總共支持256個(gè)優(yōu)先級(jí)(0~255,數(shù)值越小的優(yōu)先級(jí)越高,0為最高優(yōu)先級(jí),255分配給空閑線使用,一般用戶不使用。在一些資源比較緊張的系統(tǒng)中,可以根據(jù)實(shí)際情況選擇只支持8個(gè)或32個(gè)優(yōu)先級(jí)的系統(tǒng)配置)。當(dāng)系統(tǒng)中,當(dāng)有比當(dāng)前線優(yōu)先級(jí)更高的線就緒時(shí),當(dāng)前線立刻被換出,高優(yōu)先級(jí)線搶占處理器運(yùn)行。如圖線就緒優(yōu)先級(jí)隊(duì)列所示,在R-head調(diào)度器的實(shí)現(xiàn)中,包含了個(gè)共256個(gè)優(yōu)先級(jí)隊(duì)列的數(shù)組(如果系統(tǒng)最大支持32個(gè)優(yōu)先級(jí),那么這里將是一個(gè)包含了32個(gè)優(yōu)先級(jí)隊(duì)列的數(shù)組),每個(gè)數(shù)組元素中放置相同優(yōu)先級(jí)鏈表的表頭。這些相同優(yōu)先級(jí)的列表形成一個(gè)雙向環(huán)形鏈表,最低優(yōu)先級(jí)鏈表一般只包一個(gè)idle線圖2.1:線就緒優(yōu)先級(jí)隊(duì)在優(yōu)先級(jí)隊(duì)列1#和2#中,可以看到三個(gè)線線A、線B和線C。由于線A、B的優(yōu)先級(jí)比線C的高,所以此時(shí)線C得不到運(yùn)行,必須要等待優(yōu)先級(jí)隊(duì)列1#的中所有線因?yàn)樽枞┒甲尦鎏幚砥骱蟛拍艿玫綀?zhí)行。一個(gè)操作系統(tǒng)如果只是具備了高優(yōu)先級(jí)任務(wù)能夠“立即”獲得處理器并得到執(zhí)行的特點(diǎn),那么它仍然不算是實(shí)時(shí)操作系統(tǒng)。因?yàn)檫@個(gè)查找最高優(yōu)先級(jí)線的過(guò)決定了調(diào)度時(shí)間是否具有確定性,例如一個(gè)包含n個(gè)就緒任務(wù)的系統(tǒng)中,如果僅僅從頭找到尾,那么這個(gè)時(shí)間將直接和n相關(guān),而下一個(gè)就緒線抉擇時(shí)間的長(zhǎng)短將會(huì)極大的影響系統(tǒng)的實(shí)時(shí)性。當(dāng)所有就緒線都在它們對(duì)應(yīng)的優(yōu)先級(jí)隊(duì)列中時(shí),抉擇過(guò)就將演變?yōu)樵趦?yōu)先級(jí)數(shù)組中尋找具有最高優(yōu)先級(jí)線的非空鏈表。-hread內(nèi)核中采用了基于位圖的優(yōu)先級(jí)算法(時(shí)間復(fù)雜度O(1),即與就緒線的多少無(wú)關(guān)),通過(guò)位圖的定位快速的獲得優(yōu)先級(jí)最高的線RT-hread內(nèi)核中也允許創(chuàng)建相同優(yōu)先級(jí)的線相同優(yōu)先級(jí)的線采用時(shí)間片輪轉(zhuǎn)方式進(jìn)行調(diào)度(也就是通常說(shuō)的分時(shí)調(diào)度器),時(shí)間片輪轉(zhuǎn)調(diào)度僅在當(dāng)前系統(tǒng)中無(wú)更高優(yōu)先級(jí)就緒線存在的情況下才有效。例如 就緒優(yōu)先級(jí)隊(duì)列圖中,我們假設(shè)線A和線B一次最大允許運(yùn)行的時(shí)間片分別是10個(gè)時(shí)鐘節(jié)拍和7個(gè)時(shí)鐘節(jié)拍。那么線B將 A的間片結(jié)束(10個(gè)時(shí)鐘節(jié)拍)后才能運(yùn)行,但如果中途線A被掛起了,即線A在運(yùn)行的途中,因?yàn)樵噲D去持有不可用的資源,而導(dǎo)致線狀態(tài)從就緒狀態(tài)更改為阻塞狀態(tài),那么線B會(huì)因?yàn)槠鋬?yōu)先級(jí)成為系統(tǒng)中就緒線中最高的而馬上運(yùn)行。每個(gè)線的時(shí)間片大小都可以在初始化或創(chuàng)建這個(gè)線時(shí)指定。因?yàn)镽T-hread調(diào)度器的實(shí)現(xiàn)是采用優(yōu)先級(jí)鏈表的方式,所以系統(tǒng)中的總線數(shù)不受限制,只和系統(tǒng)所能提供的內(nèi)存資源相關(guān)。為了保證系統(tǒng)的實(shí)時(shí)性,系統(tǒng)盡最大可能地保證高優(yōu)先級(jí)的線得以運(yùn)行。線調(diào)度的原則是一旦任務(wù)狀態(tài)發(fā)生了改變,并且當(dāng)前運(yùn)行的線優(yōu)先級(jí)小于優(yōu)先級(jí)隊(duì)列組中線最高優(yōu)先級(jí)時(shí),立刻進(jìn)行線切換(除非當(dāng)前系統(tǒng)處于中斷處理序中或線切換的狀態(tài))。線控制線控制塊是操作系統(tǒng)用于控制線的一個(gè)數(shù)據(jù)結(jié)構(gòu),它會(huì)存放線的一些信息,例如優(yōu)先級(jí),線名稱(chēng)等,也包含線與線之間連接用的鏈表結(jié)構(gòu),線等待事件集合等。在RT-Thread實(shí)時(shí)操作系統(tǒng)中,線控制塊由結(jié)構(gòu)體structt_thead表示。另外一種C表達(dá)方式t_thead_t,表示的是線的句柄,在C語(yǔ)言中的實(shí)現(xiàn)是指向線控制塊的指針,詳細(xì)定義情況見(jiàn)以下代碼:線控制塊結(jié)構(gòu)如下所/*rtthreadt線句柄,指向線控制塊的指針*/typedefstructrtthread*rtthreadt;*線控制structrt{/*RT-Thread根對(duì)象定義charname[RTNAMEMAX]; /*對(duì)象的名稱(chēng)*/rtuint8t /*對(duì)象的類(lèi)型rtuint8tflags; /*對(duì)象的參數(shù)*/#ifdefRTUSINGMODULEvoid*moduleid; /*線所在的模塊ID*/rtlistt /*對(duì)象鏈表rtlistt /*線鏈表/*棧指針及void* /* void* /* void* void*stack /*線棧地址rtuint16tstack /*線棧大小rterrt /*線錯(cuò)誤號(hào)rtuint8t /*線狀態(tài)/*優(yōu)先級(jí)相關(guān)域rtuint8tcurrent /*當(dāng)前優(yōu)先級(jí)rtuint8tinitpriority; /*初始線優(yōu)先級(jí)*/#ifRTTHREADPRIORITYMAX32rtuint8tnumber;rtuint8thighmask;rtuint32tnumber#ifdefined(RTUSING/*事件相關(guān)域rtuint32teventset;rtuint8teventrtubasetinit /*線初始rtubasetremainingtick; /*線當(dāng)次運(yùn)行剩余tick*/structrttimerthreadtimer; /*線定時(shí)器*//*當(dāng)線退出時(shí),需要執(zhí)行的清理函數(shù)*/void(*cleanup)(structrtthread*tid);rtuint32tuser /*用戶數(shù)據(jù)(除非用戶執(zhí)行線控制函數(shù)進(jìn)行手動(dòng)調(diào)整線優(yōu)先級(jí))。canup成員是RT-Thread100中新引入的成員,它會(huì) 退出時(shí),被idle線回調(diào)一次以執(zhí)行用戶設(shè)置的清理現(xiàn)場(chǎng)等工作。最后的一個(gè)成員ue_data可由用戶掛接一些數(shù)據(jù)信息到線控制塊中,以提供類(lèi)似線私有數(shù)據(jù)的實(shí)現(xiàn),例如LwIP線中用于放置定時(shí)器鏈表的表頭。線狀線運(yùn)行的過(guò)中,一個(gè)時(shí)間內(nèi)只允許一個(gè)線在處理器中運(yùn)行,從運(yùn)行的過(guò)上劃分,線有多種不同的運(yùn)行狀態(tài),如運(yùn)行態(tài),非運(yùn)行態(tài)等。在RT-hread實(shí)時(shí)操作系統(tǒng)中,線包含五種狀態(tài),操作系統(tǒng)會(huì)自動(dòng)根據(jù)它運(yùn)行的情況而動(dòng)態(tài)調(diào)整它的狀態(tài)。RT-hread中的五種線狀態(tài)如下所示:狀 描 線初始狀態(tài)。當(dāng)線剛開(kāi)始創(chuàng)建還沒(méi)開(kāi)始運(yùn)行時(shí)就處于 掛起態(tài)、阻塞態(tài)。線此時(shí)被掛起:它可能因?yàn)橘Y源不可而 掛起等待;或線主動(dòng)延時(shí)一段時(shí)間而被掛起。在這個(gè)狀態(tài)下,線不參與調(diào)度 就緒態(tài)。線正在運(yùn)行;或當(dāng)前線運(yùn)行完讓出處理器后 中則不受這個(gè)限制。_E 線結(jié)束態(tài)。當(dāng)線運(yùn)行結(jié)束時(shí)將處于這個(gè)狀態(tài)。這個(gè)狀態(tài)的線不參與線的調(diào)度。RT-hread實(shí)時(shí)操作系統(tǒng)提供一系列的操作系統(tǒng)調(diào)用接口,使得線的狀態(tài)在這五個(gè)狀態(tài)之間來(lái)回的變換。例如一個(gè)就緒態(tài)的線由于申請(qǐng)一個(gè)資源(例如使用t_ea),而可能進(jìn)入掛起態(tài)。又例如因?yàn)橐粋€(gè)外部中斷發(fā)生了,系統(tǒng)轉(zhuǎn)入中斷服務(wù)例在中斷服務(wù)例中釋放了相應(yīng)的資源,導(dǎo)致把等待在這個(gè)資源上的高優(yōu)先級(jí)線喚醒,改變其狀態(tài)為就緒態(tài),導(dǎo)致當(dāng)前運(yùn)行線切換等等。幾種狀態(tài)間的轉(zhuǎn)換關(guān)系如線轉(zhuǎn)換圖所示圖2.2:線轉(zhuǎn)換線通過(guò)調(diào)用函數(shù)t_thead_ceate/nt進(jìn)入到初始狀態(tài)(RT_HRAD_NT);再通過(guò)調(diào)用函數(shù)t_thead_tatup進(jìn)入到就緒狀態(tài)(RT_THREAD_READY);當(dāng)處于就緒狀態(tài)的線調(diào)用t_thead_delay,t_em_take,t_mb_ecv等函數(shù)或由于獲取不到資源時(shí),將進(jìn)入到掛起狀態(tài)(RT_HRED_UPND);處于掛起狀態(tài)的線如果等待超時(shí)依然未能獲得資源或由于其他線釋放了資源,那么它將返回到就緒狀態(tài)。掛起狀態(tài)的線如果調(diào)用t_thead_delee/detach將更改為關(guān)閉狀態(tài)(RT_THREAD_CLOSE);而運(yùn)行狀態(tài)的線如果運(yùn)行結(jié)束會(huì) 最后部分執(zhí)行t_ha_exit函數(shù)而更改為關(guān)閉狀態(tài)(RT_THREAD_CLOSE)空閑線空閑線是系統(tǒng)線中一個(gè)比較特殊的線它具有最低的優(yōu)先級(jí),當(dāng)系統(tǒng)中無(wú)其他線運(yùn)行時(shí),調(diào)度器將調(diào)度到空閑線空閑線通常是一個(gè)死循環(huán),不被掛起。RT-Thread實(shí)時(shí)操作系統(tǒng)為空閑線提供了鉤子函數(shù)(鉤子函數(shù):用戶提供的一段代碼,在系統(tǒng)運(yùn)行的某一路徑上設(shè)置一個(gè)鉤子,當(dāng)系統(tǒng)經(jīng)過(guò)這個(gè)位置時(shí),轉(zhuǎn)而執(zhí)行這個(gè)鉤子函數(shù),然后再返回到它的正常路徑上)可以讓系統(tǒng)在空閑的時(shí)候執(zhí)行一些特定的任務(wù),例如系統(tǒng)運(yùn)行指示燈閃爍,電源管理等。除了調(diào)用鉤子函數(shù),RT-Thread也把線清理(rt_thread->cleanup回調(diào)函數(shù))函數(shù)、真正的線刪除動(dòng)作放到了空閑線中(在刪除線時(shí),僅改變線的狀態(tài)為關(guān)閉狀態(tài)不再參與系統(tǒng)調(diào)度)。調(diào)度器調(diào)度器初始化在系統(tǒng)啟動(dòng)時(shí)需要執(zhí)行調(diào)度器的初始化,以初始化系統(tǒng)調(diào)度器用到的一些全局變量。調(diào)度器初始化可以調(diào)用下面的函數(shù)接口。voidvoidrtsystemscheduler在系統(tǒng)完成初始化后切換到第一個(gè)線以調(diào)用下面的函數(shù)接口voidvoidrtsystemscheduler在調(diào)用這個(gè)函數(shù)時(shí),它會(huì)查找系統(tǒng)中優(yōu)先級(jí)最高的就緒態(tài)線然后切換過(guò)去執(zhí)行。另外在調(diào)用這個(gè)函數(shù)前,必須先做idle線的初始化,即保證系統(tǒng)至少能夠找到一個(gè)就緒狀態(tài)的線執(zhí)行。此函數(shù)是不會(huì)返回的。執(zhí)行調(diào)度讓調(diào)度器執(zhí)行一次線的調(diào)度可通過(guò)下面的函數(shù)接口voidvoidrt調(diào)用這個(gè)函數(shù)后,系統(tǒng)會(huì)計(jì)算一次系統(tǒng)中就緒態(tài)的線如果存在比當(dāng)前線更高優(yōu)先級(jí)的線時(shí),系統(tǒng)將切換到高優(yōu)先級(jí)的線去。上層應(yīng)用序一般不需要調(diào)用這個(gè)函數(shù)。注:在中斷服務(wù)例中也可以調(diào)用這個(gè)函數(shù),如果滿足任務(wù)切換的條件,它會(huì)記錄下中斷前的線及需要切換到的更高優(yōu)先級(jí)線在中斷服務(wù)例處理完畢后執(zhí)行真正的線上下文切換(即中斷中的線上下文切換),最終切換到目標(biāo)線去。在整個(gè)系統(tǒng)的運(yùn)行時(shí),系統(tǒng)都處于線運(yùn)行、中斷觸發(fā)-響應(yīng)中斷、切換到其他線甚至是線間的切換過(guò)中,或者說(shuō)系統(tǒng)的上下文切換是系統(tǒng)中最普遍的事件。有時(shí)用戶可能會(huì)想知道在一個(gè)時(shí)刻發(fā)生了什么樣的線切換,可以通過(guò)調(diào)用下面的函數(shù)接口設(shè)置一個(gè)相應(yīng)的鉤子函數(shù)。在系統(tǒng)線切換時(shí),這個(gè)鉤子函數(shù)將被調(diào)用:voidvoidrtschedulersethook(void(*hook)(structrtthread*from,structrtthread*這個(gè)函數(shù)用于把用戶提供的hook函數(shù)設(shè)置到系統(tǒng)調(diào)度器鉤子中,當(dāng)系統(tǒng)進(jìn)行上下文切換時(shí),這個(gè)hook函數(shù)將會(huì)被系統(tǒng)調(diào)用。參 描 表示用戶定義的鉤子函數(shù)指針;voidvoidhook(structrtthread*from,structrtthread*參 描 表示系統(tǒng)所要切出的線的控制塊指針注:請(qǐng)仔細(xì)編寫(xiě)你的鉤子函數(shù),稍有不慎將很可能導(dǎo)致整個(gè)系統(tǒng)運(yùn)行不正常(在這個(gè)鉤子函數(shù)中,基本上不允許調(diào)用系統(tǒng)API,更不應(yīng)該導(dǎo)致當(dāng)前運(yùn)行的上下文掛起)。線相關(guān)接線創(chuàng)一個(gè)線要成為可執(zhí)行的對(duì)象就必須由操作系統(tǒng)的內(nèi)核來(lái)為它創(chuàng)建(初始化)一個(gè)線句柄??梢酝ㄟ^(guò)如下的函數(shù)接口來(lái)創(chuàng)建一個(gè)線rtrtthreadtrtthreadcreate(constchar*void(*entry)(void*parameter),void*parameter,rtuint32tstacksize,rtuint8tpriority,rtuint32t調(diào)用這個(gè)函數(shù)時(shí),系統(tǒng)會(huì)從動(dòng)態(tài)堆內(nèi)存中分配一個(gè)線句柄(即TCB,線控制塊)以及按照參數(shù)中指定的棧大小從動(dòng)態(tài)堆內(nèi)存中分配相應(yīng)的空間。分配出來(lái)的??臻g是按照參 描 pioity 線的優(yōu)先級(jí)。優(yōu)先級(jí)范圍根據(jù)系統(tǒng)配置情況(tconig.h中的RT_THREAD_PRIORITY_MX宏定義6級(jí)優(yōu)先0~255,數(shù)值越小優(yōu)先級(jí)越高,0 先級(jí) RT-Thread 創(chuàng)建成功返回線句柄;否則返回RT_NULL注:確定一個(gè)線的??臻g大小,是一件令人頭痛的事情。在RT-Thread中,可以先指定一個(gè)稍微大的??臻g,例如指定大小為1024或208,然后在nSHs中通過(guò)list_thread()命令查看線運(yùn)行的過(guò)中線所使用的棧的大小,通過(guò)此命令,能夠看到從線啟動(dòng)運(yùn)行時(shí),到當(dāng)前時(shí)刻點(diǎn),線使用的最大棧深度,從而可以確定??臻g的大小并加以修改)。下面舉例創(chuàng)建一個(gè)線加以說(shuō)明*序動(dòng)態(tài)*這個(gè)序會(huì)初始化2個(gè)動(dòng)態(tài)線它們擁有共同的函數(shù),相同的優(yōu)先但是它們的參數(shù)不相#include#defineTHREAD#defineTHREADSTACK#defineTHREAD5/*指向線控制塊的指針staticrtthreadttid1=RTNULL;staticrtthreadttid2=RTNULL;/*線staticvoidthreadentry(void*{rtuint32tcount=rtuint32tno=(rtuint32t)parameter;/*獲得正確的參數(shù)while{/*打印線計(jì)數(shù)值輸出rtkprintf("thread%dcount:%d\n",no,count/*休眠10個(gè)OSTick*/rtthreaddelay(10);}}/*用戶應(yīng)用intrtapplication{/*創(chuàng)建線1tid1=rtthreadthreadentry,(void*)1,/*線是threadentry,參數(shù)是1*/THREADSTACKSIZE,THREADPRIORITY,THREADTIMESLICE);if(tid1!=RTrtthreadreturn-/*創(chuàng)建線2tid2=rtthreadthreadentry,(void*)2,/*線是threadentry,參數(shù)是2*/THREADSTACKSIZE,THREADPRIORITY,THREADTIMESLICE);if(tid2!=RTrtthreadreturn-return}線刪對(duì)于一些使用rt_thread_create創(chuàng)建出來(lái)的線當(dāng)不需要使用,或者運(yùn)行出錯(cuò)時(shí),我們可以使用下面的函數(shù)接口來(lái)從系統(tǒng)中把線完全刪除掉:rtrterrtrtthreaddelete(rtthreadt調(diào)用該函數(shù)后,線對(duì)象將會(huì)被移出線隊(duì)列并且從內(nèi)核對(duì)象管理器中刪除,線占用的堆棧空間也會(huì)被釋放,收回的空間將重新用于其他的內(nèi)存分配。實(shí)際上,用rt_thread_delete函數(shù)刪除線接口,僅僅是把相應(yīng)的線狀態(tài)更改為RT_THREAD_CLOSE狀態(tài),然后放入到t_thead_deunct隊(duì)列中;而真正的刪除動(dòng)作(釋放線控制塊和釋放線棧)需要到下一次執(zhí)行idle線時(shí),由idle線完成最后的線刪除動(dòng)作。用t_thea_iit初始化的靜態(tài)線則不能使用此接口刪除。參 描 要?jiǎng)h除的線句柄返回注: 運(yùn)行完成,自動(dòng)結(jié)束的情況下,系統(tǒng)會(huì)自動(dòng)刪除線不需要再調(diào)用rt_thread_delete()函數(shù)接口。這個(gè)接口不應(yīng)由線本身來(lái)調(diào)用以刪除線自身,一般只能由其他線調(diào)用或在定時(shí)器超時(shí)函數(shù)中調(diào)用。這個(gè)函數(shù)僅在使能了系統(tǒng)動(dòng)態(tài)堆時(shí)才有效(即RT_USNG_HAP宏定義已經(jīng)定義了)。下面舉一個(gè)刪除線的例子,如下代碼:*序刪除**這個(gè)例子會(huì)創(chuàng)建兩個(gè)線在一個(gè)線中刪除另外一個(gè)線#include #defineTHREADSTACK 線刪除(rtthreaddelete)函數(shù)僅適合于動(dòng)態(tài)線為了在一個(gè)中另一個(gè)線的控制塊,所以把線塊指針成全局類(lèi)型以供局staticrtthreadttid1=RTNULL,tid2=RT/*線1的函數(shù)staticvoidthread1entry(void*{rtuint32tcount=while{/*線1采用低優(yōu)先級(jí)運(yùn)行,一直打印計(jì)數(shù)值*/rtkprintf("threadcount:dncount++);}}/*線2的函數(shù)staticvoidthread2entry(void*{/*線2擁有較高的優(yōu)先級(jí),以搶占線1而獲得執(zhí)行/*線2啟動(dòng)后先睡眠10個(gè)OSTick*/rtthreaddelay(10);隊(duì)rtthreaddelete(tid1);tid1=RTNULL; rtthreadtid2=RT}/*應(yīng)用intrtapplication{/*創(chuàng)建線1tid1=rtthreadcreate("t1",/*線1的名稱(chēng)是t1thread1entry,RTNULL, /*是thread1entry,參數(shù)是RTNULL*/THREADSTACKSIZE,THREADPRIORITY,THREADTIMESLICE);if(tid1!=RTNULL)/*如果獲得線控制塊,啟動(dòng)這個(gè)線*/rtthreadstartup(tid1);return-/*創(chuàng)建線1tid2=rtthreadcreate("t2",/*線1的名稱(chēng)是t2thread2entry,RTNULL, /*是thread2entry,參數(shù)是RTNULL*/THREADSTACKSIZE,THREADPRIORITY-1,THREADTIMESLICE);if(tid2!=RTNULL)/*如果獲得線控制塊,啟動(dòng)這個(gè)線*/rtthreadstartup(tid2);return-return}線初始線的初始化可以使用下面的函數(shù)接口完成rtrterrtrtthreadinit(structrtthread*constchar*void(*entry)(void*parameter),void*parameter,void*stackstart,rtuint32tstacksize,rtuint8tpriority,rtuint32tt_thea_it函數(shù)用來(lái)初始化靜態(tài)線對(duì)象。而線句柄(或者說(shuō)線控制塊指針),線棧由用戶提供。靜態(tài)線是指,線控制塊、線運(yùn)行棧一般都設(shè)置為全局變量,在編譯時(shí)就被確定、被分配處理,內(nèi)核不負(fù)責(zé)動(dòng)態(tài)分配內(nèi)存空間。需要注意的是,用戶提供的棧首地址需做系統(tǒng)對(duì)齊(例如ARM上需要做4字節(jié)對(duì)齊)。參 描 pioity 線的優(yōu)先級(jí)。優(yōu)先級(jí)范圍根據(jù)系統(tǒng)配置情況(tconig.h中的RT_THREAD_PRIORITY_MX宏定義6級(jí)優(yōu)先0~255,數(shù)值越小優(yōu)先級(jí)越高,0先級(jí)。 返回值:返回下面給出一個(gè)線初始化的例子,如下代碼*序初始化靜態(tài)**這個(gè)序會(huì)初始化2個(gè)靜態(tài)線它們擁有共同的函數(shù),但參數(shù)不相#include #defineTHREADSTACK /*線1控制塊staticstructrtthread/*線1棧*//*線2控制塊staticstructrtthread/*線2棧*//*線staticvoidthreadentry(void*{rtuint32tcount=rtuint32tno=(rtuint32t)parameter;/*獲得正確的參數(shù)while{/*打印線計(jì)數(shù)值輸出rtkprintf("thread%dcount:%d\n",no,count/*休眠10個(gè)OSTick*/rtthreaddelay(10);}}/*用戶應(yīng)用intrtapplication{rterrt/*初始化線1result=rtthreadinit(&thread1,"t1",/*線名t1threadentry,(void*)1,/*線的是threadentry,參數(shù)是1*/&thread1stack[0],sizeof(thread1stack),/*線棧是thread1stack*/THREADPRIORITY,10);if(result==RTEOK)/*如果返回正確,啟動(dòng)線1*/rtthreadstartup(&thread1);return-/*初始化線2result=rtthreadinit(&thread2,"t2",/*線名t2threadentry,(void*)2,/*線的是threadentry,參數(shù)是2*/&thread2stack[0],sizeof(thread2stack),/*線棧是thread2stack*/THREADPRIORITY110);if(result==RTEOK)/*如果返回正確,啟動(dòng)線2*/rtthreadstartup(&thread2);return-return}線脫線脫離將使線對(duì) 隊(duì)列和內(nèi)核對(duì)象管理器中被刪除。線脫離使用下面的數(shù)rtrterrtrtthreaddetach(rtthreadt參 描 返回 的對(duì)象是t_thead_ceate()創(chuàng)建的句柄,而t_thead_each()函數(shù)操作的對(duì)象是使用rt_thread_init()函數(shù)初始化的線控制塊。同樣,線本身不應(yīng)調(diào)用這個(gè)接口脫離線本身。線脫離的例子如下所示*序線脫*#include<rtthread.h>#include"tccomm.h"/*線1控制塊staticstructrtthread/*線1棧/*線2控制塊staticstructrtthread/*線2棧/*線1staticvoidthread1entry(void*{rtuint32tcount=while{/*線1采用低優(yōu)先級(jí)運(yùn)行,一直打印計(jì)數(shù)值*/rtkprintf("threadcount:dncount++);}}/*線2staticvoidthread2entry(void*{/*線2擁有較高的優(yōu)先級(jí),以搶占線1而獲得執(zhí)行/*線2啟動(dòng)后先睡眠10個(gè)OSTick*/rtthreaddelay(10); 線2喚醒后直接執(zhí)行線1脫離,線1將從就緒線隊(duì)列中刪rtthread*線2繼續(xù)休眠10個(gè)OSTick然后退rtthread 線2運(yùn)行結(jié)束后也將自動(dòng)被從就緒隊(duì)列中刪除,并脫離線隊(duì)}intrtapplication{rterrt/*初始化線1result=rtthreadinit(&thread1,"t1",/*線名 t1*/thread1entry, /*線的是thread1entr*/RTNULL, /*參數(shù)是RTNULL*/&thread1stack[0],/*線棧是thread1stack*/sizeof(thread1stack),THREADPRIORITY,if(result==RTEOK) /*如果返回正確,啟動(dòng)線1*/rtthreadstartup(&thread1);/*初始化線2result=rtthreadinit(&thread2,"t2",/*線名 t2*/thread2entry, /*線的是thread2entry*/RTNULL, /*參數(shù)是RTNULL*/&thread2stack[0],/*線棧是thread2stack*/sizeof(thread2stack),THREADPRIORITY-1,if(result==RTEOK)/*如果返回正確,啟動(dòng)線2*/rtthreadstartup(&thread2);return}線啟創(chuàng)建(初始化)的線對(duì)象的狀態(tài)處于初始態(tài),并未進(jìn)入就緒線的調(diào)度隊(duì)列,我們可以調(diào)用下面的函數(shù)接口啟動(dòng)一個(gè)線rtrterrtrtthreadstartup(rtthreadt當(dāng)調(diào)用這個(gè)函數(shù)時(shí),將把線的狀態(tài)更改為就緒狀態(tài),并放到相應(yīng)優(yōu)先級(jí)隊(duì)列中等待調(diào)度。如果新啟動(dòng)的線優(yōu)先級(jí)比當(dāng)前線優(yōu)先級(jí)高,將立刻切換到這個(gè)線參 描 線句柄返回當(dāng)前線在序的運(yùn)行過(guò)中,相同的一段代碼可能會(huì)被多個(gè)線執(zhí)行,在執(zhí)行的時(shí)候可以通過(guò)下面的函數(shù)接口獲得當(dāng)前執(zhí)行的線句柄。rtrtthreadtrtthread參 描 線句柄返回當(dāng)前運(yùn)行的線句柄。如果調(diào)度器還未啟動(dòng),將返回RT_NULL注:請(qǐng)不要在中斷服務(wù)序中調(diào)用此函數(shù),因?yàn)樗⒉荒軠?zhǔn)確獲得當(dāng)前的執(zhí)行線當(dāng)調(diào)度器未啟動(dòng)時(shí),這個(gè)接口返回RT_NUL。線讓出處理當(dāng)前線的時(shí)間片用完或者該線自動(dòng)要求讓出處理器資源時(shí),它不再占有處理器,調(diào)度器會(huì)選擇下一個(gè)最高優(yōu)先級(jí)的線執(zhí)行。這時(shí),放棄處理器資源的線仍然在就緒隊(duì)列中。線讓出處理器使用下面的函數(shù)接口:rtrterrtrtthread調(diào)用該函數(shù)后,當(dāng)前線首先把自己從它所在的隊(duì)列中刪除,然后把自己掛到與該線優(yōu)先級(jí)對(duì)應(yīng)的就緒線鏈表的尾部,然后激活調(diào)度器切換到優(yōu)先級(jí)最高的線線讓出處理器代碼的例子如下示*序線讓出處理在這個(gè)例子中,將創(chuàng)建兩個(gè)相同優(yōu)先級(jí)的線它們會(huì)通過(guò)rtthread#include<rtthread.h>#include"tccomm.h"/*指向線控制塊的指針staticrtthreadttid1=RTNULL;staticrtthreadttid2=RTNULL;/*線1staticvoidthread1entry(void*{rtuint32tcount=while{/*打印線1的輸出rtkprintf("thread1:count=%d\n",count/*執(zhí)行yield后應(yīng)該切換到thread2執(zhí)行*/rtthreadyield();}}/*線2staticvoidthread2entry(void*{rtuint32tcount=while{/*打印線2的輸出rtkprintf("thread2:count=%d\n",count/*執(zhí)行yield后應(yīng)該切換到thread1執(zhí)行*/rtthreadyield();}}intrtapplication{/*創(chuàng)建線1tid1=rtthreadthread1entry, /*線是thread1entry*/RTNULL, /*參數(shù)是RTNULL*/THRE

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論