支援非同步通知的globalfifo驅動

2021-08-10 18:09:59 字數 2640 閱讀 4300

驅動程式執行在核心空間中,應用程式執行在使用者空間中,兩者是不能直接通訊的。但在實際應用中,在裝置已經準備好的時候,我們希望通知使用者程式裝置已經ok,使用者程式可以讀取了,這樣應用程式就不需要一直查詢該裝置的狀態,從而節約了資源,這就是非同步通知。好,那下乙個問題就來了,這個過程如何實現呢?簡單,兩方面的工作。

在裝置抽象的資料結構中增加乙個struct fasync_struct的指標

實現裝置操作中的fasync函式,這個函式很簡單,其主體就是呼叫核心的fasync_helper函式。

在需要向使用者空間通知的地方(例如中斷中)呼叫核心的kill_fasync函式。

在驅動的release方法中呼叫前面定義的fasync函式

其中fasync_helper和kill_fasync都是核心函式,我們只需要呼叫就可以了。在1中定義的指標是乙個重要引數,fasync_helper和kill_fasync會使用這個引數。

利用signal或者sigaction設定sigio訊號的處理函式

fcntl的f_setown指令設定當前程序為裝置檔案owner

fcntl的f_setfl指令設定fasync標誌

完成了以上的工作的話,當核心執行到kill_fasync函式,使用者空間sigio函式的處理函式就會被呼叫了。

1.增加非同步通知後的globalfifo裝置結構體

struct globalfifo_dev

;

2.支援非同步通知的globalfifo裝置驅動fasync()函式

static

int globalfifo_fasync(int fd,struct file *filp,int mode)

3支援非同步通知的globalfifo裝置驅動寫函式

static ssize_t globalfifo_write(struct file *filp,const char _user *buf,size_t count,loff_t *ppos)

_set_current_state(task_interruptible) //改變程序狀態為睡眠

mutex_unlock(& dev-> mutex);

//up(&dev->sem);

schedule();

if(signal_pending(current)

mutex_lock(& dev-> mutex);

//down(&dev->sem);

}//從使用者空間拷貝到核心空間

if(count >globalfifo_size- dev->current_len)

count=globalfifo_size-dev

->current_len;

if(copy_form_user(dev->mem+dev->current_len,buf,count)) else

ret=count;

} out:mutex_unlock(& dev-> mutex);//up(&dev->sem);

out2:remove_wait_queue(&dev->w_wait,&wait);

set_current_state(task_running);

return ret;

}

4用globalfifo_fasync()函式將檔案從非同步通知列表中刪除

static

int globalfifo_release(struct inode *inode,struct file *filp)

監控 globalfifo 非同步 通知 訊號 的 應用 程式

static

void signalio_handler(int signum)

void main( void)

else

}(注:上面有一行解釋為:這時系統就會自動呼叫驅動程式的fasync方法,我的理解是:這個時候我們聯絡一下後面的驅動,我們會發現在驅動層,是在file_operation中對應的fasync的函式呼叫,這是,會首先調fasync對應的my_fasync函式,而後者會進行 將該裝置登記到fasync_queue佇列中去,為後續做準備)

以下是幾點說明:

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](但是這可用來傳送」緊急」或者帶外資料, 在網路**裡).

9 2支援非同步通知的globalfifo驅動

在裝置驅動和應用程式的非同步通知互動中,僅僅在應用程式端捕獲訊號時不夠的,因為訊號 沒有的源頭在裝置驅動端。因此,應該在合適的時機讓裝置驅動釋放訊號 在裝置驅動程式中增加訊號釋放的相關 裝置驅動中非同步通知程式設計比較簡單,組要用到一項資料結構和兩個函式。資料結構式fasync struct結構體,...

非同步通知與非同步I O

非同步通知 很簡單,一旦裝置準備好,就主動通知應用程式,這種情況下應用程式就不需要查詢裝置狀態,這是不是特像硬體上常提的 中斷的概念 上邊比較準確的說法其實應該叫做 訊號驅動的非同步i o 訊號是在軟體層次上對中斷機制的一種模擬。阻塞 i o意味著一直等待裝置可訪問再訪問,非阻塞i o意味著使用po...

Linux核心的非同步通知

非同步通知類似於中斷,主要用於實現驅動通過傳送訊號通知應用程式。應用層 void my signal fun int signum int main int argc,char argv fcntl fd,f setown,getpid 告訴驅動要發訊號給本應用程式。oflags fcntl fd,...