Linux驅(qū)動(dòng)學(xué)習(xí)筆記:異步通知_第1頁(yè)
Linux驅(qū)動(dòng)學(xué)習(xí)筆記:異步通知_第2頁(yè)
Linux驅(qū)動(dòng)學(xué)習(xí)筆記:異步通知_第3頁(yè)
Linux驅(qū)動(dòng)學(xué)習(xí)筆記:異步通知_第4頁(yè)
免費(fèi)預(yù)覽已結(jié)束,剩余1頁(yè)可下載查看

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第第頁(yè)Linux驅(qū)動(dòng)學(xué)習(xí)筆記:異步通知

什么是異步通知

異步通知在(Linux)的實(shí)現(xiàn)中是通過(guò)(信號(hào)),而信號(hào)是在軟件層次上對(duì)中斷機(jī)制的一種(模擬)。這種機(jī)制和中斷非常類似,所以可以以中斷的思想來(lái)理解這一過(guò)程,信號(hào)其實(shí)就相當(dāng)于應(yīng)用層的中斷。

信號(hào)可以直接進(jìn)行用戶空間進(jìn)程和內(nèi)核進(jìn)程之間的交互,內(nèi)核進(jìn)程也可以利用它來(lái)通知用戶空間進(jìn)程發(fā)生了哪些系統(tǒng)事件。

如果該進(jìn)程當(dāng)前并未處于執(zhí)行態(tài),則該信號(hào)就由內(nèi)核保存起來(lái),直到該進(jìn)程恢復(fù)執(zhí)行再傳遞給它;如果一個(gè)信號(hào)被進(jìn)程設(shè)置為阻塞,則該信號(hào)的傳遞被延遲,直到其阻塞被取消時(shí)才被傳遞給進(jìn)程。

異步通知和異步IO的區(qū)別

異步通知:當(dāng)資源可獲得時(shí),由驅(qū)動(dòng)程序向應(yīng)用層發(fā)送一個(gè)信號(hào),主動(dòng)通知應(yīng)用程序,再由應(yīng)用程序發(fā)起訪問(wèn)。

異步IO:主動(dòng)獲取設(shè)備的資源信息,首先發(fā)起一個(gè)IO操作請(qǐng)求,資源可用時(shí),應(yīng)用層注冊(cè)的回調(diào)函數(shù)會(huì)被主動(dòng)調(diào)用。但是異步通知不能直接調(diào)用應(yīng)用層注冊(cè)的回調(diào)函數(shù),而是由驅(qū)動(dòng)程序向應(yīng)用層發(fā)送一個(gè)信號(hào)。

信號(hào)含義

信號(hào)名含義默認(rèn)操作SIGHUP該信號(hào)在用戶終端連接(正常或非正常)結(jié)束時(shí)發(fā)出,通常是在終端的控制進(jìn)程結(jié)束時(shí),通知同一會(huì)話內(nèi)的各個(gè)作業(yè)與控制終端不再關(guān)聯(lián)。終止SIGINT該信號(hào)在用戶鍵入INTR字符(通常是Ctrl-C)時(shí)發(fā)出,終端驅(qū)動(dòng)程序發(fā)送此信號(hào)并送到前臺(tái)進(jìn)程中的每一個(gè)進(jìn)程。終止SIGQUIT該信號(hào)和SIGINT類似,但由QUIT字符(通常是Ctrl-\\)來(lái)控制。終止SIGILL該信號(hào)在一個(gè)進(jìn)程企圖執(zhí)行一條非法指令時(shí)(可執(zhí)行文件本身出現(xiàn)錯(cuò)誤,或者試圖執(zhí)行數(shù)據(jù)段、堆棧溢出時(shí))發(fā)出。終止SIGFPE該信號(hào)在發(fā)生致命的算術(shù)運(yùn)算錯(cuò)誤時(shí)發(fā)出。這里不僅包括浮點(diǎn)運(yùn)算錯(cuò)誤,還包括溢出及除數(shù)為0等其它所有的算術(shù)的錯(cuò)誤。終止SIGKILL該信號(hào)用來(lái)立即結(jié)束程序的運(yùn)行,并且不能被阻塞、處理和忽略。終止SIGALRM該信號(hào)當(dāng)一個(gè)(定時(shí)器)到時(shí)的時(shí)候發(fā)出。終止SIGSTOP該信號(hào)用于暫停一個(gè)進(jìn)程,且不能被阻塞、處理或忽略。暫停進(jìn)程SIGTSTP該信號(hào)用于暫停交互進(jìn)程,用戶可鍵入SUSP字符(通常是Ctrl-Z)發(fā)出這個(gè)信號(hào)。暫停進(jìn)程SIGCHLD子進(jìn)程改變狀態(tài)時(shí),父進(jìn)程會(huì)收到這個(gè)信號(hào)忽略SIGABORT該信號(hào)用于結(jié)束進(jìn)程終止當(dāng)應(yīng)用層接收到一個(gè)信號(hào)時(shí),可以對(duì)信號(hào)執(zhí)行忽略、捕捉和缺省三種操作:

忽略信號(hào):對(duì)信號(hào)不做任何處理,但是有兩個(gè)信號(hào)不能忽略:即SIGKILL及SIGSTOP。

捕捉信號(hào):定義信號(hào)處理函數(shù),當(dāng)信號(hào)發(fā)生時(shí),執(zhí)行相應(yīng)的處理函數(shù)。

缺省信號(hào):執(zhí)行Linux對(duì)該信號(hào)的默認(rèn)操作

應(yīng)用層使用信號(hào)

以下是應(yīng)用層捕捉SIGIO信號(hào)的簡(jiǎn)單示例:

voidinput_handler(intsignum){//如果驅(qū)動(dòng)發(fā)送了SIGIO信號(hào),在此處理printf("recivefrom%d\\n",signum);}intmain(){intfd,oflags;fd=open("/dev/global",O_RDWR,S_IRUSR|S_IWUSR);if(fd!=-1){//啟動(dòng)信號(hào)機(jī)制signal(SIGIO,input_handler);//設(shè)置SIGIO信號(hào)的處理函數(shù)fcntl(fd,F_SETOWN,get(pi)d());//將進(jìn)程ID賦值給filp->f_owneroflags=fcntl(fd,F_GETFL);fcntl(fd,F_SETFL,oflags|FASYNC);//驅(qū)動(dòng)的fasync方法被調(diào)用while(1){sleep(1000);}}}當(dāng)應(yīng)用層F_SETOWN,驅(qū)動(dòng)什么都沒(méi)做,內(nèi)核只是將進(jìn)程的ID賦值給filp->f_owner;當(dāng)應(yīng)用層F_SETFL被執(zhí)行來(lái)打開FASYNC,驅(qū)動(dòng)的fasync方法被調(diào)用.當(dāng)數(shù)據(jù)到達(dá),驅(qū)動(dòng)向進(jìn)程發(fā)出一個(gè)SIGIO信號(hào)驅(qū)動(dòng)如何實(shí)現(xiàn)異步信號(hào)

驅(qū)動(dòng)的實(shí)現(xiàn)主要用到一個(gè)結(jié)構(gòu)體和兩個(gè)函數(shù):

fasync_struct結(jié)構(gòu)體:

structfasync_struct{spinlock_tfa_lock;intmagic;intfa_fd;structfasync_struct*fa_next;/*singlylinkedlist*/structfile*fa_file;structrcu_he(ad)fa_rcu;};函數(shù):

fasync_helper():用于處理FASYNC標(biāo)志變更

fasync_helper()函數(shù)是用來(lái)初始化fasync_struct結(jié)構(gòu)體變量,并設(shè)置異步通知隊(duì)列的

intfasync_helper(intfd,//文件描述符structfile*filp,//文件指針inton,structfasync_struct**fapp);//要設(shè)置的結(jié)構(gòu)第三個(gè)參數(shù)on表示設(shè)置還是刪除,on為真時(shí)初始化,為假時(shí)(0),移除.

kill_fasync():發(fā)送信號(hào)

voidkill_fasync(structfasync_struct**fp,intsig,intband);fp:是已初始化的fasync_struct數(shù)據(jù)結(jié)構(gòu)

sig:要發(fā)送的信號(hào)

band:在可讀時(shí)設(shè)置為POLL_IN,在可寫時(shí)設(shè)置為POLL_OUT;

驅(qū)動(dòng)實(shí)例

staticstructfasync_struct*btn_fasync;staticirqreturn_tbtn_irq_handler(intirq,void*dev){structbtn_t*p=(structbtn_t*)dev;//發(fā)送信號(hào)kill_fasync(returnIRQ_HANDLED;}staticintbtn_drv_fasync(intfd,structfile*fp,inton){//初始化btn_fasync結(jié)構(gòu),并添加到異步通知列表中returnfasync_helper(fd,fp,on,}staticintbtn_drv_close(structinode*inode,structfile*filp){if(filp->f_flags//將文件從異步通知的列表中刪除return0;}staticstructfile_opera(ti)onsbtn_ops={.release=btn_drv_close,.fasync=btn_drv_fasync,};主要步驟:

1、構(gòu)造structfasync_struct鏈表的頭

2、實(shí)現(xiàn)fasync接口函數(shù),調(diào)用fasync_helper函數(shù)來(lái)構(gòu)造structfasync_struct節(jié)點(diǎn),并加入鏈表。

3、在資源可用時(shí),調(diào)用kill_fasync發(fā)送信號(hào),并設(shè)置資源的

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論