linux驅動筆記(五) 非同步通知

2021-10-20 12:36:54 字數 3726 閱讀 5028

1、註冊訊號處理函式

應用程式根據驅動程式所使用的訊號來設定訊號的處理函式,應用程式使用 signal 函式來

置訊號的處理函式。

sighandler_t signal(int signum, sighandler_t handler));

第乙個引數指定訊號的值, 第二個引數指定針對前面訊號值的處理函式, 若為 sig_ign, 表示忽略該信

號; 若為 sig_dfl, 表示採用系統預設方式處理訊號; 若為使用者自定義的函式, 則訊號**獲到後, 該函式

將被執行

2、將本應用程式的程序號告訴給核心

使用 fcntl(fd, f_setown, getpid())將本應用程式的程序號告訴給核心。

3、開啟非同步通知

使用如下兩行程式開啟非同步通知:

flags = fcntl(fd, f_getfl); /* 獲取當前的程序狀態 */

fcntl(fd, f_setfl, flags | fasync); /* 開啟當前程序非同步通知功能 */

重點就是通過 fcntl 函式設定程序狀態為 fasync,經過這一步,驅動程式中的 fasync 函

就會執行。

例項

void sigint_handler(int num)

int main(void)

1 、首先我們需要在驅動程式中定義乙個fasync_struct結構體指標變數,

2、如果要使用非同步通知,需要在裝置驅動中實現file_operations操作集中的fasync函式,此函式格式如下所示:

int (*fasync) (int fd, struct file *filp, int on)

fasync

函式裡面一般通過呼叫

fasync_helper

函式來初始化前面定義的

fasync_struct

結構體指標,

fasync_helper

函式原型如下:

fasync_helper函式的前三個引數就是fasync函式的那三個引數,第四個引數就是要初始化的fasync_struct結構體指標變數。當應用程式通過「fcntl(fd, f_setfl, flags | fasync)」改變fasync標記的時候,驅動程式file_operations操作集中的fasync函式就會執行。

static int ***_fasync(int fd, struct file *filp, int on)

static struct file_operations ***_ops = ;

3、在關閉驅動檔案的時候需要在file_operations操作集中的release函式中釋放fasync_struct,fasync_struct的釋放函式同樣為fasync_helper,release函式引數參考例項如下:

static int ***_release(struct inode *inode, struct file *filp)

4、驅動層如何通知應用層

kill_fasync函式

當裝置可以訪問的時候,驅動程式需要向應用程式發出訊號,相當於產生「中斷」。kill_fasync函式負責傳送指定的訊號,kill_fasync函式原型如下所示:

void kill_fasync(struct fasync_struct **fp, int sig, int band)

函式引數和返回值含義如下:

fp:要操作的fasync_struct。

sig:要傳送的訊號。

band:可讀時設定為poll_in,可寫時設定為poll_out。

返回值:無。

9.4.1.1 aio概念

9.4.1.1 aio系列api:

引數aiocb:結構體包含了傳輸的所有資訊,以及為aio操作準備的使用者空間快取區

返回值

int aio_read( struct aiocb *aiocbp );

引數aiocb:結構體包含了傳輸的所有資訊,以及為aio操作準備的使用者空間快取區

返回值

int aio_write( struct aiocb *aiocbp );

int aio_error( struct aiocb *aiocbp );

ssize_t aio_return( struct aiocb *aiocbp );

int aio_suspend( const struct aiocb *const cblist, int n, const struct timespec *timeout );

如果要取消對某個給定檔案描述符的所有請求,使用者需要提供這個檔案的描述符以及乙個對 aiocbp 的 null 引用

使用 aio_error()來驗證每個 aio 請求

int aio_cancel( int fd, struct aiocb *aiocbp );

list :是乙個 aiocb 引用的列表,最大元素的個數是由 nent 定義的

int lio_listio( int mode, struct aiocb *list, int nent, struct sigevent *sig );
io_setup( )

//initializes an asynchronous context for the current process

io_submit( )

//submits one or more asynchronous i/o operations

io_getevents( )

//gets the completion status of some outstanding asynchronous i/o operations

io_cancel( )

//cancels an outstanding i/o operation

io_destroy( )

//removes an asynchronous context for the current process

字元裝置:必須明確應支援aio(極少數是非同步i/o操作)

字元裝置驅動程式中file_operations 包含 3 個與 aio 相關的成員函式,

ssize_t (*aio_read) (struct kiocb *iocb, char *buffer, size_t count, loff_t offset);

ssize_t (*aio_write) (struct kiocb *iocb, const char *buffer, size_t count, loff_t offset);

int (*aio_fsync) (struct kiocb *iocb, int datasync);

linux中驅動非同步通知

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

linux裝置驅動筆記

雖然並不做linux有關的東西,但是記錄下點點滴滴,以備不時之需 驅動程式的編譯 make 驅動程式按模組安裝 inmod ko 執行這個命令之前首先要獲得root許可權,否則會報錯,1 operation not permmitt 檢視模組安裝情況 lsmod 解除安裝相關模組 rmmod 安裝或...

linux驅動學習之非同步通知

非同步通知是裝置狀態改變後主動通知應用程式,這樣應用程式就不需要阻塞或查詢裝置了。應用通過訊號來處理核心的非同步通知,上次使用poll select來查詢裝置的可讀狀態,下面這個例子類似,不同的是當裝置有資料時主動通知應用去讀資料。應用的c 很簡單,主要設定對訊號的處理方式,核心有資料時會收到sig...