驅動程式執行在核心空間中,應用程式執行在使用者空間中,兩者是不能直接通訊的。
但在實際應用中,在裝置已經準備好的時候,我們希望通知使用者程式裝置已經ok,
使用者程式可以讀取了,這樣應用程式就不需要一直查詢該裝置的狀態,從而節約了資源,這就是非同步通知。
好,那下乙個問題就來了,這個過程如何實現呢?簡單,兩方面的工作。
一 驅動方面:
1. 在裝置抽象的資料結構中增加乙個struct fasync_struct的指標
2. 實現裝置操作中的fasync函式,這個函式很簡單,其主體就是呼叫核心的fasync_helper函式。
3. 在需要向使用者空間通知的地方(例如中斷中)呼叫核心的kill_fasync函式。
4. 在驅動的release方法中呼叫前面定義的fasync函式
呵呵,簡單吧,就三點。其中fasync_helper和kill_fasync都是核心函式,我們只需要呼叫就可以了。在
1中定義的指標是乙個重要引數,fasync_helper和kill_fasync會使用這個引數。
二 應用層方面
1. 利用signal或者sigaction設定sigio訊號的處理函式
2. fcntl的f_setown指令設定當前程序為裝置檔案owner
3. fcntl的f_setfl指令設定fasync標誌
完成了以上的工作的話,當核心執行到kill_fasync函式,使用者空間sigio函式的處理函式就會被呼叫了。
呵呵,看起來不是很複雜把,讓我們結合具體**看看就更明白了。
先從應用層**開始吧:
#include
#include
#include
#include
#include
#include
#define max_len 100
void input_handler(int num)
//處理函式,沒什麼好講的,使用者自己定義
main()
再看驅動層**,驅動層其他部分**不變,就是增加了乙個fasync方法的實現以及一些改動
static struct fasync_struct *fasync_queue;
/*首先是定義乙個結構體,其實這個結構體存放的是乙個列表,這個列表儲存的是
一系列裝置檔案,sigio訊號就傳送到這些裝置上*/
static int my_fasync(int fd, struct file * filp, int on)
/*fasync方法的實現*/
在驅動的release方法中我們再呼叫my_fasync方法
int my_release(struct inode *inode, struct file *filp)
這樣後我們在需要的地方(比如中斷)呼叫下面的**,就會向fasync_queue佇列裡的裝置傳送sigio訊號
,應用程式收到訊號,執行處理程式
if (fasync_queue)
kill_fasync(&fasync_queue, sigio, poll_in);
好了,這下大家知道該怎麼用非同步通知機制了吧?
以下是幾點說明[1]:
1 兩個函式的原型
int fasync_helper(struct inode *inode, struct file *filp, int mode, struct fasync_struct **fa);
乙個"幫忙者", 來實現 fasync 裝置方法. mode 引數是傳遞給方法的相同的值, 而 fa 指標指向乙個設
備特定的 fasync_struct *
void kill_fasync(struct fasync_struct *fa, int sig, int band);
如果這個驅動支援非同步通知, 這個函式可用來傳送乙個訊號到登記在 fa 中的程序.
2. fasync_helper 用來向等待非同步訊號的裝置鍊錶中新增或者刪除裝置檔案, kill_fasync
被用來通知擁有相關裝置的程序. 它的引數是被傳遞的訊號(常常是 sigio)和 band, 這幾乎都是 poll_in[25](但
是這可用來傳送"緊急"或者帶外資料, 在網路**裡).
Linux驅動中的非同步通知
在很多應用中都需要應用程式主動去查詢驅動中是否有資料可讀或者是否可以向驅動寫入資料,對於單執行緒的應用,這可能會導致程序阻塞。當然,可以使用select來不斷輪詢驅動是否可讀或可寫,但是這並不是很好的解決方法,更好的解決方式是由驅動主動通知應用程式其狀態,而不是應用程式主動去查詢驅動的狀態。非同步通...
linux裝置驅動中的非同步通知機制
非同步通知的意思是 一旦裝置就緒,則主動通知應用程式,這樣應用程式根本就不需要查詢裝置狀態,這一點非常類似於硬體上 中斷 的概念,比較準確的稱謂是 訊號驅動的非同步i o 訊號是在軟體層次上對中斷機制的一種模擬,在原理上,乙個程序收到乙個訊號與處理器收到乙個中斷請求可以說是一樣的.訊號是非同步的,乙...
Linux裝置驅動中的非同步通知和非同步IO
前面兩章分別提到io模型中的阻塞與非阻塞linux驅動 六 裝置驅動中的阻塞與非阻塞io,io多路復用驅動中輪詢操作實現,這一章我們再來看看非同步io,這樣,io模型就可以都搞定了。回顧一下在應用程式中使用非同步io的步驟 1,應用程式 1 設定非同步標誌位 int flags fcntl fd,f...