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