RTLinux要求將應(yīng)用程序分成實(shí)時(shí)部分和非實(shí)時(shí)部分。應(yīng)用程序的實(shí)時(shí)部分應(yīng)該是簡單的和輕負(fù)荷的,在RTLinux的實(shí)時(shí)內(nèi)核中完成;而非實(shí)時(shí)部分,在Linux的用戶空間完成。因此RTLinux提過了多種內(nèi)核實(shí)時(shí)進(jìn)程和Linux用戶空間進(jìn)程間的通訊機(jī)制,最重要的是實(shí)時(shí)FIFO和共享內(nèi)存。
實(shí)時(shí)FIFO是能夠被內(nèi)核實(shí)時(shí)進(jìn)程和Linux用戶空間進(jìn)程訪問的快進(jìn)快出隊(duì)列,是一種單向的通訊機(jī)制,可以通過兩路實(shí)時(shí)FIFO構(gòu)成雙向的數(shù)據(jù)交換方式。在使用實(shí)時(shí)FIFO前先要對實(shí)時(shí)FIFO通道初始化:
#include
int rtf_create(unsigned int fifo, int size)
使用后應(yīng)該注銷實(shí)時(shí)FIFO通道:
int rtf_destroy(unsigned int fifo)
在初始化實(shí)時(shí)FIFO通道后,RTLinux內(nèi)核的實(shí)時(shí)進(jìn)程和Linux用戶空間的進(jìn)程都可以使用標(biāo)準(zhǔn)的POSIX函數(shù)open、read、write和close等對實(shí)時(shí)FIFO通道進(jìn)行訪問。內(nèi)核實(shí)時(shí)進(jìn)程還可以使用RTLinux的專有函數(shù)rtf_put和rtf_get對實(shí)時(shí)FIFO通道進(jìn)行讀寫。
RTLinux共享內(nèi)存由mbuff.o模塊支持,可以使用下面的函數(shù)分配和釋放共享內(nèi)存塊:
#include
void *mbuff_alloc(const char *name, int size)
void mbuff_free(const char *name, void *mbuf)
函數(shù)mbuff_alloc有兩個(gè)參數(shù),共享內(nèi)存名name和共享內(nèi)存塊的大小size。如果指定的內(nèi)存共享名并不存在,分配成功時(shí)返回共享內(nèi)存指針,訪問計(jì)數(shù)置為1,分配失敗時(shí)返回空指針;如果指定的內(nèi)存共享名已經(jīng)存在,返回該塊共享內(nèi)存的指針,并將訪問計(jì)數(shù)值直接加1。函數(shù)mbuff_free將該塊共享內(nèi)存的訪問計(jì)數(shù)值減1,當(dāng)計(jì)數(shù)值為0時(shí),該共享內(nèi)存被釋放。在實(shí)時(shí)內(nèi)核模塊中使用該函數(shù)時(shí),應(yīng)該將函數(shù)mbuff_alloc和 mbuff_free分別放在init_module 和cleanup_module模塊之中。
2.2 中斷和訪問硬件
硬中斷(實(shí)時(shí)中斷)具有最低的延時(shí),在系統(tǒng)內(nèi)核中只有少數(shù)的實(shí)時(shí)進(jìn)程使用。函數(shù)rtl_request_irq和rtl_free_irq用于安裝和卸載指定硬件中斷的中斷服務(wù)程序。
#include
int rtl_request_irq(unsigned int irq, unsigned int
(*handler) (unsigned int, struct pt_regs *))
int rtl_free_irq(unsigned int irq)
中斷驅(qū)動的線程可以使用喚醒和掛起函數(shù):
int pthread_wakeup_np(pthread_t thread)
int pthread_suspend_np(void)
一個(gè)中斷驅(qū)動的線程可以調(diào)用函數(shù)pthread_suspend_np(pthread_self())阻塞自身線程的執(zhí)行,然后由中斷服務(wù)函數(shù)調(diào)用函數(shù)pthread_wakeup_np喚醒該線程的執(zhí)行,直到此線程再次調(diào)用函數(shù)pthread_suspend_np(pthread_self())將自身掛起。
軟中斷是Linux內(nèi)核常常使用的中斷,它能夠更安全地調(diào)用系統(tǒng)函數(shù)。無論如何,對于許多任務(wù)來說并不能提供硬實(shí)時(shí)性能,將會導(dǎo)致一定的延時(shí)。
int rtl_get_soft_irq(void (*handler)(int, void*, struct pt_regs *), const char* devname)分配一個(gè)虛中斷并安裝中斷處理函數(shù);void rtl_global_pend_irq(int ix) 激活虛中斷;void rtl_free_soft_irq(unsigned int irq) 釋放分配的虛中斷。
RTLinux與Linux一樣通過/dev/mem設(shè)備訪問物理內(nèi)存,具體由模塊 rtl_posixio.o 提供此項(xiàng)功能。首先應(yīng)用程序應(yīng)該打開/dev/mem設(shè)備,通過函數(shù)mmap對某段物理內(nèi)存進(jìn)行映射后,即可使用映射后的地址訪問該段物理內(nèi)存。應(yīng)用程序只能在Linux進(jìn)程中(即在應(yīng)用程序的init_module()模塊中)調(diào)用mmap,在實(shí)時(shí)進(jìn)程中調(diào)用mmap將會失敗。另一種訪問物理內(nèi)存的方法是通過Linux的函數(shù)ioremap[2]。RTLinux 訪問I/O端口的函數(shù)如下(對于x86結(jié)構(gòu)):
輸出一個(gè)字節(jié)到端口:
#include
void outb(unsigned int value, unsigned short port)
void outb_p(unsigned int value, unsigned short port)
輸出一個(gè)字到端口:
#include
void outw(unsigned int value, unsigned short port)
void outw_p(unsigned int value, unsigned short port)
從端口讀一個(gè)字節(jié):
#include
char inb(unsigned short port)
char inb_p(unsigned short port)
從端口讀一個(gè)字:
#include
short inw(unsigned short port)
short inw_p(unsigned short port)
其中帶后綴_p的函數(shù)使讀寫端口時(shí)有一個(gè)小的延時(shí),這在快速的計(jì)算機(jī)訪問慢速的ISA設(shè)備時(shí)是必需的。
評論