基于μCLinux的USB驅動程序實現
2.3 設備的注冊與注銷
設備驅動在調用前必須首先向系統注冊,這時就執行加載函數static int_init ft245bl_init(void)。該函數的核心語句是 register_chrdev(ft245bl_major,FT245BL_DEV,ft245bl_fops)字符注冊函數。其中,ft245bl_major是設備驅動向系統申請的主設備號;FT245BL_DEV是USB設備的名稱;ft245bl_fops是之前定義為 file_operations數據結構的各個功能函數的文件指針。該函數返回值為0,表示注冊成功;返回-INVAL,表示申請的主設備號非法;返回 -EBUSY,表示該設備號正在使用。設備注冊成功后,設備名會出現在系統的/proc/devices文件中。
設備有注冊就有卸載,卸載字符設備需要調用函數unregister_chrdev(ft245bl_major,FT245BL_DEV),參數有主設備號和設備名兩個,USB退出驅動,用staticvoid_exit ft245bl_exit(void)函數。
2.4 編寫相應的功能函數
對于每一個設備驅動程序來說,都有一些與此設備密切相關的功能函數,通常對于塊設備或者字符設備來說,都存在著諸如打開、關閉、讀、寫這一類的操作。當進行系統調用時,將自動地使用驅動函數中特定的函數來實現具體的操作。打開函數open()主要完成以下操作,即檢查設備錯誤(諸如設備未就緒或相似的硬件問題),如果是首次打開,則初始化設備;讀取次設備號;分配和填寫要放在file→private-data內的數據結構;增加使用計數。讀函數 read()用來從外部設備中讀取數據,當其為NULL指針時,將引起read()系統調用返回-EINVAL(“非法參數”)。函數返回一個非負值表示成功地讀取了多少字節。寫函數write()向外部設備發送數據,如果沒有這個函數,返回一個-EINVAL;如果返回值非負,就表示成功寫入的字節數。當設備被關閉時調用release()這個操作,有時也稱為close()。它應該完成以下操作:使用計數減1;釋放open分配在 file→rivate-data中的內存;在最后一次關閉操作時關閉設備。下面是FT245BL驅動程序讀函數read()的實現:

讀取函數ft245bl_read通過判斷USB芯片RXF管腳的狀態來處理接收到的數據,如果RXF為0,表示接收緩沖區(RX FIFO)中至少有1個數據,處理器讀取一個數據后重新回到判斷;如果RXF為1,表示芯片沒有接收到數據,這時程序啟動中斷等待事件函數 wait_event_interruptible,內核從USB設備驅動中釋放出來,運行其他程序,直到有新的數據到來時,內核首先執行中斷處理函數 ft245bl_rx_handler,將中斷標志位irqflag置1,喚醒等待隊列ft245bl_waitqueue,然后再回到讀取函數中繼續運行。
2.5 中斷處理
設備驅動程序通過調用中斷申請函數申請中斷,其格式為:

函數調用成功返回0值,返回-INVAL表示中斷號超出范圍或者handler=NULL;返回-BUSY表示中斷已經被占用且不能共享。其中,handler是中斷處理子程序指針,中斷產生時自動調用該函數;參數irq為中斷號;pt_regs為中斷發生之前寄存器的映像,很少使用;irqflags控制中斷行為。irqflags=SA_INTER-RUPT表示它在運行時將禁止所有的中斷;irqflags=SA_SHIRQ 表示共享此中斷處理程序;devname為設備名稱;dev_id用于支持中斷的共享,它將作為第2個參數傳遞給中斷處理函數,可以利用它來傳遞一些必要的信息。該中斷處理程序如下:本文引用地址:http://www.104case.com/article/202492.htm
評論