RTLinux下的一種實(shí)時(shí)應(yīng)用通信機(jī)制解析_第1頁
RTLinux下的一種實(shí)時(shí)應(yīng)用通信機(jī)制解析_第2頁
RTLinux下的一種實(shí)時(shí)應(yīng)用通信機(jī)制解析_第3頁
RTLinux下的一種實(shí)時(shí)應(yīng)用通信機(jī)制解析_第4頁
全文預(yù)覽已結(jié)束

下載本文檔

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

文檔簡介

1、RTLinux 下的一種實(shí)時(shí)應(yīng)用通信機(jī)制RTLinux 下的一種實(shí)時(shí)應(yīng)用通信機(jī)制類別:嵌入式系統(tǒng)摘要: RTLinux 實(shí)時(shí)應(yīng)用程序的開發(fā)模式;詳細(xì)說明兩種在實(shí)時(shí)模塊 與非實(shí)時(shí)模塊之間進(jìn)行通信的主要通信接口的實(shí)現(xiàn)和使用方式;提出一種將以 上兩種接口有機(jī)結(jié)合的實(shí)時(shí)應(yīng)用內(nèi)部通信機(jī)制,并通過實(shí)驗(yàn)證該方法的可操作 性。關(guān)鍵詞: RTLinux 通信接口 實(shí)時(shí) 共享內(nèi)存 RT_FIFO 實(shí)時(shí)性是多任務(wù) 嵌入式系統(tǒng)的基本特征之一,主要表現(xiàn)為對重要性各不相同的任務(wù)進(jìn)行統(tǒng)籌兼 顧的合理調(diào)度能力。根據(jù)應(yīng)用系統(tǒng)對時(shí)限要求的嚴(yán)格程度又分為軟實(shí)時(shí)和硬實(shí) 時(shí)。 RTLinux 作為 Linux 最為通用的幾種硬實(shí)時(shí)擴(kuò)展

2、之一,表現(xiàn)了良好的硬實(shí) 時(shí)性。同時(shí),為了更有效地為各種實(shí)時(shí)應(yīng)用服務(wù),提供了多種與 Linux 中非實(shí) 時(shí)進(jìn)行通信的接口,主要有共享內(nèi)存、RT_FIFO和線程信號驅(qū)動(dòng)機(jī)制,三者的應(yīng)用重點(diǎn)各不相同。其中前兩種較為常用 1 。由于不的實(shí)現(xiàn)機(jī)理,這兩種接口 的應(yīng)用范疇各有側(cè)重。經(jīng)過實(shí)踐,筆者認(rèn)為將以上兩種接口有機(jī)地結(jié)合,利用 共享內(nèi)存?zhèn)魉痛笕萘?、對讀 / 寫時(shí)序要求不高的數(shù)據(jù)信息;同時(shí),利用 RT_FIFO 輔助實(shí)現(xiàn)對該共享內(nèi)存的同步控制,能夠綜合兩者的優(yōu)勢,是 RTLinux 下一種 十分有效的實(shí)時(shí)應(yīng)用通信模式。 1 RTLinux 的結(jié)構(gòu)和應(yīng)用程序開發(fā)模式 作為 Linux 的硬實(shí)時(shí)擴(kuò)展, RTL

3、inux 一個(gè)重要的計(jì)準(zhǔn)則在于:盡可能多地利用 Linux 內(nèi)核所能提供的功能 2 。 顯示、記錄、設(shè)備初始化、阻塞式動(dòng)態(tài)資源分配和 模塊化內(nèi)核管理等無實(shí)時(shí)要求或者與硬實(shí)時(shí)性要求相悖的服務(wù)均由 Linux 提 供。 RTLinux 內(nèi)核則主要為實(shí)時(shí)任務(wù)提供對硬件的直接訪問,使得它們具有最 小的延遲和最優(yōu)先的處理器利用權(quán)。 基于以上準(zhǔn)則, RTLinux 中的實(shí)時(shí)應(yīng)用程 序開發(fā)通常具有一個(gè)通用的模式,如圖 1 所示。按照運(yùn)行環(huán)境和對實(shí)時(shí)要求的 嚴(yán)格程度分為實(shí)時(shí)和非實(shí)時(shí)兩個(gè)模塊。非實(shí)時(shí)模塊的功能包括結(jié)果數(shù)據(jù)顯示。 用戶交互、數(shù)據(jù)存儲等;實(shí)時(shí)模塊主要負(fù)責(zé)響應(yīng)數(shù)據(jù)采集外設(shè)的中斷,結(jié)果數(shù) 據(jù)的采集。兩者

4、通過RT_FIFO或者共享內(nèi)存進(jìn)行通信,組成一個(gè)完整的實(shí)時(shí)數(shù) 據(jù)采集程序。2 RTLinux中的兩種通信接口 RTLinux提供了 RT_FIFO和共享內(nèi) 存兩種標(biāo)準(zhǔn)通信接口,用于實(shí)時(shí)任務(wù)和非實(shí)時(shí)任務(wù)之間的交互。 2.1 RT_FIFO RT_FIFO(First-In-First-Out,先進(jìn)先出)是一種提案隊(duì)列機(jī)制組織的字符設(shè)備。在 Linux 文件系統(tǒng)中,主設(shè)備號為 150。一個(gè)系統(tǒng)平臺中能夠同加載 FIFO 的模塊數(shù)RTF_NO定義在rt_fifo_new.c 中,一般為64,在文件系統(tǒng)中分別對 慶設(shè)備文件 /dev/rtf0.63。在系統(tǒng)資源允許的情況下,一個(gè)用戶進(jìn)程所能同時(shí)使用的F

5、IFO數(shù)和每個(gè)FIFO的容量是沒限制的。RT_FIFO具有如下特征:*隊(duì) 列中的數(shù)據(jù)傳送采用數(shù)據(jù)流形式,必須自行定義數(shù)據(jù)邊界監(jiān)測機(jī)制,尤其對于 不定長度數(shù)據(jù)的傳輸。*具備完善的同步阻塞機(jī)制,利用同一 FIFO進(jìn)行通信的 兩進(jìn)程間無需自行增加同步控制。 * 一種點(diǎn)對點(diǎn)的通信通道,不支持單生產(chǎn) 者、多消費(fèi)者的使用模式。作為一個(gè)完善的隊(duì)列模塊,RT_FIFO的使用簡便易 行,具體實(shí)現(xiàn)主要包括創(chuàng)建、讀 / 寫操作、釋放三個(gè)步驟。在 Linux 文件系統(tǒng)中,RT_FIFC是一個(gè)字符設(shè)備文件,所以在非實(shí)時(shí)線程中訪問RT_FIFO時(shí),使用標(biāo)準(zhǔn)的字符設(shè)備讀 / 寫函數(shù)即可( read 、 write 、ope

6、n、close , etc )。以上 函數(shù)的調(diào)用方式均為阻塞式調(diào)用:當(dāng)FIFO中有數(shù)據(jù)可讀時(shí),立即返回;否則,會陷入無限等待之中。從RT進(jìn)程中訪問RT_FIFO所涉及到的RTLAPI如下:#include 創(chuàng)建 int rtf_create(unsigned int fifo,intsize);內(nèi)核空間中,為編號fifo的RT_FIFO設(shè)備分配size字節(jié)的緩沖區(qū)。 fifo 對應(yīng)于所使用 RT_FIFO的次設(shè)備號。釋放int rtf_destroy(unsigned int fifo);釋放內(nèi)核空間中次設(shè)備號為fifo的RT_FIFO設(shè)備緩沖區(qū)。注意:以上兩個(gè)函數(shù)涉及到內(nèi)核空間的緩沖區(qū)分配,

7、必須分別在 Linux 的 init_module ()和 cleanup_module() 中調(diào)用,或者在用戶空間通過 PSC(the user-level real-time signal library,用戶級實(shí)時(shí)庫函數(shù))進(jìn)行調(diào)用。 讀/寫操作 int rtl_get(unsigned int fifo,char *buf,int count); 從 FIFO中讀出長度為 count 字節(jié)的數(shù)據(jù),存放 buf 之中。 Int rtf_put(unsignedint fifo,char * buf,int count); 將長度為 count 字節(jié)的數(shù)據(jù)寫入 FIFO中。 Int rtf_

8、create_handle(unsigned int fifo,int(&handler)(unsigned int fifo) ;創(chuàng)建一個(gè)回調(diào)函數(shù)句柄,當(dāng) FIFO被Linux進(jìn)程讀/寫時(shí),被調(diào) 用。通常與 rtl_get 結(jié)合使用,用于異步的從 Linux 進(jìn)程中接收數(shù)據(jù),從而避 免采用輪詢的方式。 2.2 共享內(nèi)存 共享內(nèi)存是指被閑置出來專用于內(nèi)核空間 和用戶空間進(jìn)行通信的內(nèi)存區(qū)域。相對于 FIFO具有如下特點(diǎn):*應(yīng)用程序必須 自己定義相應(yīng)的協(xié)議,對于寫入共享數(shù)據(jù)區(qū)域的有數(shù)據(jù)進(jìn)行保護(hù),如同步控制 等。 * 數(shù)據(jù)可以既定格式讀 /寫,各個(gè)數(shù)據(jù)域的更新十分便易。 * 不是點(diǎn)對點(diǎn)的 通信通道,

9、可以支持多生產(chǎn)者、多消費(fèi)者的使用模式,能夠同時(shí)被多個(gè)線程訪 問。在RTLinux下,共享內(nèi)存的使用可采用以下兩種方式:(1)利用RTLinux中附帶的mbuff模塊 在使用mbuff之前,要求系統(tǒng)中已經(jīng)加載了 mbuff.o 模塊。該模塊中的兩個(gè)函數(shù)被分別用于分配和釋放所需的內(nèi)存空間。 #include 分配 void * mbuff_alloc(const char * name,int size);從內(nèi)核空間中分配一塊與name相連,大小為size字節(jié)的內(nèi)存空間, 返回地址指針,設(shè)備這塊空間的引用標(biāo)識為1。如與name相連的內(nèi)存空間已經(jīng)存在,就僅僅返回指向該空間的地址指針,同時(shí)將其引用標(biāo)識

10、加 1。 釋放 void mbuff_free(const char * name,int size); 將 mbuff 的引用標(biāo)識減1。當(dāng)引用標(biāo)識被減為0時(shí),釋放mbuff。注意:mbuff_alloc使用了 vmalloc 函數(shù),由于分配內(nèi)核空間的需要,會交換出一系列的內(nèi)核空間頁面, 所以在實(shí)時(shí)線程、中斷處理線程、定時(shí)器中斷線程中調(diào)用這個(gè)函數(shù)是十分危險(xiǎn) 的。在進(jìn)程結(jié)束前,一定要調(diào)用 mbuff_free函數(shù)。Mbuff所占內(nèi)存空間不 會因?yàn)槠湟眠M(jìn)程的結(jié)束而自行釋放。(2)高地址空間物理內(nèi)存的直接隔離在系統(tǒng)啟動(dòng)時(shí),隔離出一定大小的高地址空間物理內(nèi)存,使其脫離系統(tǒng)運(yùn)行環(huán) 境,作為專用的共享內(nèi)

11、存區(qū)域。圖 4共享內(nèi)存互斥操作流程圖 在Linux啟動(dòng) 配置文件中,插入一行以appe nd關(guān)鍵字起始的命令行,即可實(shí)現(xiàn)高端內(nèi)存空間 的隔離。修改后的 /etc/lilo.conf 文件如下所示: image=/boot/zImage label=rtlinuxX.X root=/dev/hda2 read_only append=“mem=X”m 其中, mem的值對應(yīng)于被隔離空間的起始地址,可以由物理內(nèi)存總?cè)萘繙p去所需共享空間 容量得到。但是必須注意,被隔離出的共享空間的容量必須小于 /usr/include/asm/param.h 文件中定義的頁面長度。 Intel Pentium 系列

12、芯片 的頁面長度為 4MB。 對共享內(nèi)存空間的存取操作通過訪問其基址來實(shí)現(xiàn)。必須首先定義共享內(nèi)存空間的基址。#define BASE_ADDRESS(12:7 0x100000)在實(shí)時(shí)和非實(shí)時(shí)模塊中有不同的基址訪問方法。寫時(shí)模塊運(yùn)行于內(nèi)核地址空間,可 以直接將基址作為地址指針進(jìn)行存取,使用語句如下: unsigned short * sharemem; sharemem=(unsigned short *)_va(BASE_ADDRESS); 非實(shí)時(shí)模塊運(yùn) 行于用戶地址空間,必須先將該物理地址映射入該進(jìn)程虛擬地址空間后,才能 對其進(jìn)行存取。使用命令如下: #include #include #

13、include int fd ; unsigned short * sharemem ; fd=open(/dev/mem,O_RDWR); sharemem=(unsigned short *)mmap(0,buflen, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, Fd,BASE_ADDRESS注:訪問物理內(nèi)存必須打開與其對應(yīng)的設(shè)備文件 /dev/mem。注:mma命令的作用是將設(shè)備文件fd中,從當(dāng)前進(jìn)程的虛擬地 址空間,其返回值可被非實(shí)時(shí)進(jìn)程存取。 以上兩種方式在實(shí)現(xiàn)機(jī)理上的不同之 處在于, mbuff 利用 vmalloc 從內(nèi)核地址空間分配的

14、共享內(nèi)存空間僅僅在邏輯 上連續(xù),空間的大小不受實(shí)際物理內(nèi)存空間的限制;而直接隔離物理內(nèi)存所獲 取的緩沖區(qū)物理上連續(xù),但是大小受到物理內(nèi)存空間和當(dāng)前系統(tǒng)狀況的限制。 共同之處在于,所獲得的內(nèi)存均被隔離于系統(tǒng)內(nèi)核的運(yùn)行環(huán)境之外,不會在頁 面交換中被換出,所以以上兩種方法均適用于實(shí)時(shí)應(yīng)用之中。 3 兩種通信接口 的結(jié)合 以上兩種通信接口具有不同的適用范疇,為了實(shí)現(xiàn)一個(gè)完整的實(shí)時(shí)應(yīng) 用,通常需要將兩者結(jié)合,以一個(gè)實(shí)時(shí)數(shù)據(jù)采集程序?yàn)槔?,?shí)時(shí)模塊和非實(shí)時(shí) 模塊之間通常需要傳送兩種類型的數(shù)據(jù);結(jié)果數(shù)據(jù)和控制信息。 結(jié)果數(shù)據(jù):由 實(shí)時(shí)模塊周期性產(chǎn)生。非實(shí)時(shí)模塊用于顯示和存儲,對讀 /寫的時(shí)序性要求不 高,但是

15、通常需要由多個(gè)用戶共享,因此,利用共享內(nèi)存模塊傳輸比較適合。 控制信息:主要用于實(shí)現(xiàn)非實(shí)時(shí)模塊和實(shí)時(shí)模塊之間的交互控制,數(shù)據(jù)量小, 但是比較注重信號讀/寫的時(shí)序性和通信過程中實(shí)時(shí)性,采用 RT_FIFO實(shí)現(xiàn)比較 適合。圖2為通用的抽象數(shù)據(jù)流圖。3.1共享內(nèi)存的內(nèi)步控制和RT_FIFO的 使用 由于對共享內(nèi)存的存取通過直接訪問指針來實(shí)現(xiàn),操作系統(tǒng)不會為其提供 任何同步控制,應(yīng)用程序必須自行提供握手機(jī)制,來保證讀 /寫進(jìn)程之間同步。 實(shí)現(xiàn)同步的一種方式是接收方和發(fā)送方利用消息通信來實(shí)現(xiàn)握手。接收方對共 享內(nèi)存以輪詢的方式監(jiān)測新數(shù)據(jù)的到來,然后發(fā)送接收信息。為了實(shí)現(xiàn)握手, 發(fā)送方對于每條接收消息都必

16、須回復(fù)一個(gè)確認(rèn)消息,新的接收消息只有在收到 確認(rèn)消息以后才能發(fā)出。 這種方式在實(shí)時(shí)模塊和非實(shí)時(shí)模塊中均須要采用輪詢 的方式監(jiān)測新數(shù)據(jù)和消息的到來,因此會占用較多的處理器資源。所以,可以 考慮利用RT_FIFO實(shí)現(xiàn)實(shí)時(shí)模塊和非實(shí)時(shí)模塊之間對共享內(nèi)存的存取同步。禾I 用RT_FIFO所提供的句柄功能能夠避免實(shí)時(shí)模塊對接收消息的輪詢監(jiān)測,在一 定程度上提高程序運(yùn)行效率。具體實(shí)現(xiàn),可以通過利用 RT_FIFO實(shí)時(shí)傳輸當(dāng)前所寫入或被讀出的共享內(nèi)存塊序號,實(shí)現(xiàn)實(shí)時(shí)進(jìn)程和非實(shí)時(shí)進(jìn)程之間的步。因 為RT_FIFO是一種單向傳輸隊(duì)列,為了實(shí)現(xiàn)交互,需要兩個(gè)傳輸方向相反的 RT_FIFO連接于兩個(gè)模塊之間,如圖3

17、所示。圖3中,BufNo為筆者自行定 義的隊(duì)列。它的使用主要是為了避免由于RT_FIFO引起的實(shí)時(shí)部分和非實(shí)時(shí)部分之間的死鎖。 實(shí)時(shí)部分和非實(shí)時(shí)部分的各線程路之間對共享內(nèi)存的訪問為異 步進(jìn)行;同時(shí),RTLinux中對RT_FIFO的進(jìn)行讀/寫的API函數(shù),為阻塞式操 作。當(dāng)FIFO0中目前沒有可讀數(shù)據(jù)寸,對rtf_get函數(shù)的調(diào)用會使程序陷入無 限等待之中,很容易造成實(shí)時(shí)模塊和非實(shí)時(shí)模塊之間的死鎖。 為了避免這種情 況,可以將BufNo作為緩沖區(qū)與FIFO0的句柄結(jié)合使用,臨時(shí)存放 FIFO0中被非實(shí)時(shí)線程寫入的塊序號。實(shí)時(shí)模塊不再對 FIFOO進(jìn)行讀/寫,而是改由BufNo 隊(duì)列中獲取當(dāng)前有

18、效的共享內(nèi)存序號。如果當(dāng)前無可用數(shù)據(jù),則進(jìn)入周期等待 狀態(tài)。 3.2 共享內(nèi)存訪問的互斥 對共享內(nèi)存訪問的互斥操作,包括兩個(gè)方 面:實(shí)時(shí)模塊與非實(shí)時(shí)模塊之間的互斥、非實(shí)時(shí)模塊中各采集線程之間的互 斥。 (1)實(shí)時(shí)模塊與非實(shí)時(shí)模塊之間的互斥 多線程之間對共享資源訪問的互 斥,是操作系統(tǒng)中一個(gè)重要的研究分支。但是在實(shí)時(shí)模塊和非實(shí)時(shí)模塊之間, 問題變得相對簡單。因?yàn)?,在?shí)時(shí)進(jìn)程和非實(shí)時(shí)進(jìn)程之中,實(shí)時(shí)進(jìn)程和非實(shí)時(shí) 進(jìn)程運(yùn)行的環(huán)境區(qū)別很大。工作于 RTLinux 環(huán)境下的實(shí)時(shí)進(jìn)程具有最高的優(yōu)先 級,不可能被非實(shí)時(shí)進(jìn)程中斷。所以,在實(shí)現(xiàn)互斥時(shí),只須保護(hù)非實(shí)時(shí)進(jìn)程對 共享資源的訪問即可。 抽象流程如圖 4 所示。利用共享內(nèi)存區(qū)域的第一個(gè)字節(jié) 作為訪問標(biāo)識,實(shí)現(xiàn)非實(shí)時(shí)模塊對實(shí)時(shí)模塊的互斥。 非實(shí)時(shí)進(jìn)程開始訪問共享 區(qū)域時(shí),將此標(biāo)識置位;訪問結(jié)

溫馨提示

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

最新文檔

評論

0/150

提交評論