qnx 设备驱动开发_QNX驱动开发——应用层与resource manger交互 | 学步园
QNX操作系統是一個類Unix實時操作系統,遵從POSIX規范,驅動程序具有良好的可移植性。
編寫任何驅動程序都會遇到同樣的一個問題:應用程序與驅動程序之間是如何進行交互的。其實這個問題很簡單,QNX有大量資料說明這一點。
當客戶端調用fd = open(“dev/mydevice”,O_RDWR)打開設備mydevice,并期望從設定的地址上讀寫數據時,這個問題就產生了。實際上QNX提供了一套靈活的消息交互機制,大致上可以分為以下三個步驟:
第一,加載驅動程序,創建服務線程,把底層IO函數與POSIX函數進行連接,在命名空間注冊設備名,通過Event loop或Thread
pool等待消息的接收,同時使父進程在后臺運行以加載其他應用程序。
第二,當應用程序調用open()函數時,process manger受到請求在命名空間中找到名為dev/mydevice的resource
manger,QNX內核庫打開它,應用程序通過返回的句柄與之建立連接。
第三,隨后當調用read (fd, buf, 512)函數時,內核庫發送了一個_IO_READ的消息,此時之前建立的Event loop或Thread
pool就可以接收到這個消息,通過判斷消息的類型調用到相應的IO函數,比如:
int io_read (resmgr_context_t *ctp,??io_read_t *msgRESMGR_OCB_T*ocb);
其實可以看出來了,fd, buf, 512這幾個參數主要就是通過io_read_t *msg這個參數傳過來的。其實client主要指定了一個設備,希望向這個設備的某個地址讀取長度為512字節的數據,然后放到buf當中。
接下來發生的事情就比較簡單了,就是在自己實現的io_read函數中解析這個消息傳遞來的參數,并給出回復。在client-server消息交互模型中,此時client就處在了reply
blocked的狀態等待server的回復。在io_read中做了哪些事情呢?首先要驗證下傳來的消息是否是正確的io_read消息,同時檢查到底是否是nonblock方式打開。然后解析msg->i.nbytes來確定需要傳遞多少個數據,然后調用底層函數讀取硬件數據,通過_IO_SET_READ_NBYTES
(ctp, msg->i.nbytes);來告訴client可以返回的數據量。
對于如何回復數據來說,QNX確實提供了不少簡單的方法。可以使用return(ENOMEM)返回一個錯誤;或者使用return(EOK)返回操作成功。如果想返回一定量數據的話,可以設置IOV數組返回,
比如通過設置IOV來返回一個或多個數組,比如:
SETIOV (ctp->iov, buffer, nbytes);
return (_RESMGR_NPARTS(1));
或者直接調用宏返回一個完整的buffer:
return (_RESMGR_PTR(ctp, buffer, nbytes));
寫數據的操作與讀數據的操作類似,不再贅述。這樣就完成了上層數據請求,下層數據讀取并返回的過程,server重新回到receive blocked的狀態。細心的朋友可能已經看出來了,既然是讀寫數據,那么地址是如何設置的呢?其實是通過devctl來設置的,其格式為
int devctl( int fd, int dcmd, void *data, size_t nbytes, int * return_info);
其中最值得一提的就是int dcmd這個參數,這是一個自定義的命令,可以通過這個命令傳遞一個結構體指針,比如:
Typedef struct{
Uint32_t addr_t;
Uint32_t status_r;
} my_cfg_t;
#define MYCMD_SET_ADDR? __DIOT(_DCMD_MISC, 0x01, my_cfg_t)
在client應用程序中定義my_cfg_t addr;通過命令
Devctl(fd, MYCMD_SET_ADDR,& addr,sizeof(my_cfg_t),NULL);
完成設置。對于底層來說就比較簡單了,主要分為獲取數據指針,解析傳來的命令獲得數據就可以了。
總結
以上是生活随笔為你收集整理的qnx 设备驱动开发_QNX驱动开发——应用层与resource manger交互 | 学步园的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 男生想追你的表现暗示(男生一旦想追你会有
- 下一篇: 电脑显示器在闪白光(电脑显示器在闪白光什