基于μCLinux的USB驅(qū)動程序?qū)崿F(xiàn)
2.3 設(shè)備的注冊與注銷
設(shè)備驅(qū)動在調(diào)用前必須首先向系統(tǒng)注冊,這時就執(zhí)行加載函數(shù)static int_init ft245bl_init(void)。該函數(shù)的核心語句是 register_chrdev(ft245bl_major,F(xiàn)T245BL_DEV,ft245bl_fops)字符注冊函數(shù)。其中,ft245bl_major是設(shè)備驅(qū)動向系統(tǒng)申請的主設(shè)備號;FT245BL_DEV是USB設(shè)備的名稱;ft245bl_fops是之前定義為 file_operations數(shù)據(jù)結(jié)構(gòu)的各個功能函數(shù)的文件指針。該函數(shù)返回值為0,表示注冊成功;返回-INVAL,表示申請的主設(shè)備號非法;返回 -EBUSY,表示該設(shè)備號正在使用。設(shè)備注冊成功后,設(shè)備名會出現(xiàn)在系統(tǒng)的/proc/devices文件中。
設(shè)備有注冊就有卸載,卸載字符設(shè)備需要調(diào)用函數(shù)unregister_chrdev(ft245bl_major,F(xiàn)T245BL_DEV),參數(shù)有主設(shè)備號和設(shè)備名兩個,USB退出驅(qū)動,用staticvoid_exit ft245bl_exit(void)函數(shù)。
2.4 編寫相應(yīng)的功能函數(shù)
對于每一個設(shè)備驅(qū)動程序來說,都有一些與此設(shè)備密切相關(guān)的功能函數(shù),通常對于塊設(shè)備或者字符設(shè)備來說,都存在著諸如打開、關(guān)閉、讀、寫這一類的操作。當進行系統(tǒng)調(diào)用時,將自動地使用驅(qū)動函數(shù)中特定的函數(shù)來實現(xiàn)具體的操作。打開函數(shù)open()主要完成以下操作,即檢查設(shè)備錯誤(諸如設(shè)備未就緒或相似的硬件問題),如果是首次打開,則初始化設(shè)備;讀取次設(shè)備號;分配和填寫要放在file→private-data內(nèi)的數(shù)據(jù)結(jié)構(gòu);增加使用計數(shù)。讀函數(shù) read()用來從外部設(shè)備中讀取數(shù)據(jù),當其為NULL指針時,將引起read()系統(tǒng)調(diào)用返回-EINVAL(“非法參數(shù)”)。函數(shù)返回一個非負值表示成功地讀取了多少字節(jié)。寫函數(shù)write()向外部設(shè)備發(fā)送數(shù)據(jù),如果沒有這個函數(shù),返回一個-EINVAL;如果返回值非負,就表示成功寫入的字節(jié)數(shù)。當設(shè)備被關(guān)閉時調(diào)用release()這個操作,有時也稱為close()。它應(yīng)該完成以下操作:使用計數(shù)減1;釋放open分配在 file→rivate-data中的內(nèi)存;在最后一次關(guān)閉操作時關(guān)閉設(shè)備。下面是FT245BL驅(qū)動程序讀函數(shù)read()的實現(xiàn):
讀取函數(shù)ft245bl_read通過判斷USB芯片RXF管腳的狀態(tài)來處理接收到的數(shù)據(jù),如果RXF為0,表示接收緩沖區(qū)(RX FIFO)中至少有1個數(shù)據(jù),處理器讀取一個數(shù)據(jù)后重新回到判斷;如果RXF為1,表示芯片沒有接收到數(shù)據(jù),這時程序啟動中斷等待事件函數(shù) wait_event_interruptible,內(nèi)核從USB設(shè)備驅(qū)動中釋放出來,運行其他程序,直到有新的數(shù)據(jù)到來時,內(nèi)核首先執(zhí)行中斷處理函數(shù) ft245bl_rx_handler,將中斷標志位irqflag置1,喚醒等待隊列ft245bl_waitqueue,然后再回到讀取函數(shù)中繼續(xù)運行。
2.5 中斷處理
設(shè)備驅(qū)動程序通過調(diào)用中斷申請函數(shù)申請中斷,其格式為:
函數(shù)調(diào)用成功返回0值,返回-INVAL表示中斷號超出范圍或者handler=NULL;返回-BUSY表示中斷已經(jīng)被占用且不能共享。其中,handler是中斷處理子程序指針,中斷產(chǎn)生時自動調(diào)用該函數(shù);參數(shù)irq為中斷號;pt_regs為中斷發(fā)生之前寄存器的映像,很少使用;irqflags控制中斷行為。irqflags=SA_INTER-RUPT表示它在運行時將禁止所有的中斷;irqflags=SA_SHIRQ 表示共享此中斷處理程序;devname為設(shè)備名稱;dev_id用于支持中斷的共享,它將作為第2個參數(shù)傳遞給中斷處理函數(shù),可以利用它來傳遞一些必要的信息。該中斷處理程序如下:本文引用地址:http://m.butianyuan.cn/article/202492.htm
評論