一級(jí)a做爰片免費(fèi)網(wǎng)站孕交視頻開(kāi)封網(wǎng)站seo
目錄
一、異步通知簡(jiǎn)介
二、信號(hào)處理
2.1 驅(qū)動(dòng)程序中的處理
2.1.1?fasync_struct結(jié)構(gòu)體
2.1.2 fasync操作函數(shù)
2.1.3?kill_fasync函數(shù)
2.2 應(yīng)用程序中的處理
三、驅(qū)動(dòng)代碼
一、異步通知簡(jiǎn)介
異步通知的核心就是信號(hào)。信號(hào)類(lèi)似于硬件上使用的中斷,只不過(guò)信號(hào)是軟件層次上的,算是在軟件層次上對(duì)中斷的一種模擬。
驅(qū)動(dòng)可以通過(guò)主動(dòng)向應(yīng)用程序發(fā)送信號(hào)的方式來(lái)報(bào)告自己可以訪問(wèn),應(yīng)用程序獲取到信號(hào)以后就可以從驅(qū)動(dòng)設(shè)備中讀取或者寫(xiě)入數(shù)據(jù)。整個(gè)過(guò)程就相當(dāng)于應(yīng)用程序收到了驅(qū)動(dòng)發(fā)送過(guò)來(lái)了的一個(gè)“中斷“,然后應(yīng)用程序去響應(yīng)這個(gè)”中斷“。在整個(gè)處理過(guò)程中應(yīng)用程序并沒(méi)有去查詢驅(qū)動(dòng)設(shè)備是否可以訪問(wèn),一切都是由驅(qū)動(dòng)設(shè)備自己告訴給應(yīng)用程序的。arch/xtensa/include/uapi/asm/signal.h文件中定義了Linux所支持的所有信號(hào):
#define SIGHUP 1 /* 終端掛起或控制進(jìn)程終止 */
#define SIGINT 2 /* 終端中斷(Ctrl+C組合鍵) */
#define SIGQUIT 3 /* 終端退出(Ctrl+\組合鍵) */
#define SIGILL 4 /* 非法指令 */
#define SIGTRAP 5 /* debug使用,有斷點(diǎn)指令產(chǎn)生 */
#define SIGABRT 6 /* 由abort(3)發(fā)出的退出指令 */
#define SIGIOT 6 /* IOT指令 */
#define SIGBUS 7 /* 總線錯(cuò)誤 */
#define SIGFPE 8 /* 浮點(diǎn)運(yùn)算錯(cuò)誤 */
#define SIGKILL 9 /* 殺死、終止進(jìn)程 */
#define SIGUSR1 10 /* 用戶自定義信號(hào)1 */
#define SIGSEGV 11 /* 段違例(無(wú)效的內(nèi)存段) */
#define SIGUSR2 12 /* 用戶自定義信號(hào)2 */
#define SIGPIPE 13 /* 向非讀管道寫(xiě)入數(shù)據(jù) */
#define SIGALRM 14 /* 鬧鐘 */
#define SIGTERM 15 /* 軟件終止 */
#define SIGSTKFLT 16 /* 棧異常 */
#define SIGCHLD 17 /* 子進(jìn)程結(jié)束 */
#define SIGCONT 18 /* 進(jìn)程繼續(xù) */
#define SIGSTOP 19 /* 停止進(jìn)程的執(zhí)行,只是暫停 */
#define SIGTSTP 20 /* 停止進(jìn)程的運(yùn)行(Ctrl+Z組合鍵) */
#define SIGTTIN 21 /* 后臺(tái)進(jìn)程需要從終端讀取數(shù)據(jù) */
#define SIGTTOU 22 /* 后臺(tái)進(jìn)程需要向終端寫(xiě)數(shù)據(jù) */
#define SIGURG 23 /* 有"緊急"數(shù)據(jù) */
#define SIGXCPU 24 /* 超過(guò)CPU資源限制 */
#define SIGXFSZ 25 /* 文件大小超額 */
#define SIGVTALRM 26 /* 虛擬時(shí)鐘信號(hào) */
#define SIGPROF 27 /* 時(shí)鐘信號(hào)描述 */
#define SIGWINCH 28 /* 窗口大小改變 */
#define SIGIO 29 /* 可以進(jìn)行輸入/輸出操作 */
#define SIGPOLL SIGIO
#define SIGPWR 30 /* 斷點(diǎn)重啟 */
#define SIGSYS 31 /* 非法的系統(tǒng)調(diào)用 */
#define SIGUNUSED 31 /* 未使用信號(hào) */
在這些信號(hào)中,除了 SIGKILL(9)和 SIGSTOP(19)這兩個(gè)信號(hào)不能被忽略外,其他的信號(hào)都可以忽略。驅(qū)動(dòng)程序可以通過(guò)向應(yīng)用程序發(fā)送不同的信號(hào)以實(shí)現(xiàn)不同的功能。
二、信號(hào)處理
2.1 驅(qū)動(dòng)程序中的處理
2.1.1?fasync_struct結(jié)構(gòu)體
首先要定義一個(gè)fasync_struct結(jié)構(gòu)體指針變量:
struct fasync_struct { spinlock_t fa_lock; int magic; int fa_fd; struct fasync_struct *fa_next; struct file *fa_file; struct rcu_head fa_rcu;
};
2.1.2 fasync操作函數(shù)
然后在設(shè)備驅(qū)動(dòng)中實(shí)現(xiàn)file_operations操作集中的fasync操作函數(shù):
int (*fasync) (int fd, struct file *filp, int on)
fasync函數(shù)里一般通過(guò)調(diào)用fasync_helper函數(shù)以初始化前面定義的fasync_struct結(jié)構(gòu)體指針:
int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
fasync_helper函數(shù)的前三個(gè)參數(shù)即fasync函數(shù)的三個(gè)參數(shù),第四個(gè)參數(shù)是要初始化的fasync_struct結(jié)構(gòu)體指針變量。?在關(guān)閉驅(qū)動(dòng)文件的時(shí)候需要在file_operations操作集中的release操作函數(shù)中釋放fasync_struct,fasync_struct的釋放函數(shù)同樣是fasync_helper。
所以驅(qū)動(dòng)中有關(guān)fasync操作函數(shù)的模板代碼大致如下:
struct xxx_dev { ...... struct fasync_struct *async_queue; /* 異步相關(guān)結(jié)構(gòu)體 */
}; static int xxx_fasync(int fd, struct file *filp, int on)
{ struct xxx_dev *dev = (xxx_dev)filp->private_data; if (fasync_helper(fd, filp, on, &dev->async_queue) < 0) return -EIO; return 0;
} static struct file_operations xxx_ops = { ...... .fasync = xxx_fasync, ......
};static int xxx_release(struct inode *inode, struct file *filp)
{ return xxx_fasync(-1, filp, 0); /* 刪除異步通知 */
}
2.1.3?kill_fasync函數(shù)
當(dāng)設(shè)備可以訪問(wèn)的時(shí)候,kill_fasync函數(shù)負(fù)責(zé)發(fā)送指定的信號(hào),相當(dāng)于產(chǎn)生“中斷”:
void kill_fasync(struct fasync_struct **fp, int sig, int band)
fp:要操作的fasync_struct。
sig:要發(fā)送的信號(hào)。
band:可讀時(shí)設(shè)置為POLL_IN,可寫(xiě)時(shí)設(shè)置為POLL_OUT。
返回值:無(wú)。
2.2 應(yīng)用程序中的處理
應(yīng)用程序應(yīng)根據(jù)驅(qū)動(dòng)程序所使用的信號(hào)來(lái)設(shè)置相應(yīng)信號(hào)的處理函數(shù),應(yīng)用程序使用signal函數(shù)來(lái)設(shè)置信號(hào)的處理函數(shù)。然后使用fcntl(fd, F_SETOWN, getpid())將本應(yīng)用程序的進(jìn)程號(hào)告訴給內(nèi)核以開(kāi)啟異步通知:
flags = fcntl(fd, F_GETFL); /* 獲取當(dāng)前的進(jìn)程狀態(tài) */
fcntl(fd, F_SETFL, flags | FASYNC); /* 開(kāi)啟當(dāng)前進(jìn)程異步通知功能 */
重點(diǎn)是通過(guò)fcntl函數(shù)設(shè)置進(jìn)程狀態(tài)為FASYNC——驅(qū)動(dòng)程序中的fasync操作函數(shù)會(huì)因此而執(zhí)行。
三、驅(qū)動(dòng)代碼
以Linux驅(qū)動(dòng)開(kāi)發(fā)——(六)按鍵中斷實(shí)驗(yàn)的驅(qū)動(dòng)代碼為模板修改。
添加頭文件和相關(guān)變量:
#include <linux/fcntl.h>struct fasync_struct *async_queue;
在定時(shí)器服務(wù)函數(shù)里添加:
if(atomic_read(&dev->releasekey)) { if(dev->async_queue) kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
}
添加fasync操作函數(shù):
static int imx6uirq_fasync(int fd, struct file *filp, int on) { struct imx6uirq_dev *dev = (struct imx6uirq_dev *) filp->private_data; return fasync_helper(fd, filp, on, &dev->async_queue);
}static struct file_operations imx6uirq_fops = { .fasync = imx6uirq_fasync,
};
完善release操作函數(shù):
static int imx6uirq_release(struct inode *inode, struct file *filp){return imx6uirq_fasync(-1, filp, 0);
}static struct file_operations imx6uirq_fops = { .release = imx6uirq_release,
};