先談談如何寫linux驅動:
- 在驅動子產品初始化函數中調用register_chrdev(),将驅動向系統注冊為一個字元裝置,僞裝成一個檔案,上層的應用可以通過通路這個檔案(字元裝置),來操作驅動子產品。
- 驅動子產品注冊為字元裝置後,還需要使用者在指令行中敲mknod指令來建立一個對應的字元檔案,上層應用就是用open, close, read, write該檔案這樣的方式來通路驅動子產品。
- 裝了udev的系統,可以讓系統自動為您建立該字元檔案:調用device_create()在/dev/目錄下建立對應的字元檔案,
具體方法可以參考LinuxKernelSdioMx53代碼的用法。
以LinuxKernelSdioMx28 / LinuxKernelSdioMx53項目代碼為例:
- module_init(DibBridgeTargetModuleInit)
驅動子產品初始化入口
- DibBridgeTargetModuleInit():子產品初始化函數。
1.調用sdio_register_driver()注冊sdio接口驅動,
2.調用register_chrdev()注冊驅動子產品為字元裝置。
- sdio_register_driver():向系統注冊sdio接口驅動,調用以後,系統會觸發sdio裝置id檢測,如果裝置id和接口驅動裡.id_table裡定義的id一緻,則系統調用probe函數。
1. 可以在DibBridgeTargetModuleInit()裡調用,這樣insmod之後,驅動接口即被注冊(裝置id被注冊),有相應裝置插入則probe會被調用(此種做法參考LinuxKernelSdioMx28)
2. 也可以在sdio初始化時調用,這樣裝置插入時,probe不會被調用,隻有在sdio初始化,sdio_register_driver()被調用時,系統才會重新檢測裝置id,并調用probe。(此種做法好處是,子產品初始化不涉及何種裝置,具有更好的通用性。參考LinuxKernelSdioMx53)
- static struct sdio_driver Dib_sdio_driver
是sdio接口驅動的結構體,包括.id_table, .probe()函數等,如下
static struct sdio_driver Dib_sdio_driver = {
.name = "Dib_sdio",
.id_table = Dib_sdio_ids,
.probe = Dib_sdio_probe,
.remove = __devexit_p(Dib_sdio_remove),
};
其中.id_table很重要,它裡面定義了此sdio驅動子產品關心的sdio裝置id号,隻有插入的sdio裝置的id号和這裡面定義的id對應上,系統才會調用.probe函數。
- register_chrdev()
将驅動子產品向系統注冊為字元裝置,并将操作該裝置的接口函數file_operations也一起注冊了。
1.可以在DibBridgeTargetModuleInit()裡調用。(參考LinuxKernelSdioMx53/LinuxKernelSdioMx28代碼)
2.也可以在probe函數裡調用,即隻有在系統檢測到硬體裝置時才去注冊字元裝置(參考sdk8remote代碼)
- struct file_operations
包含如下最基本的檔案操作函數,
struct file_operations fops =
{
.ioctl = DibBridgeTargetModuleIoctl, //控制指令傳輸或資料傳輸
.open = DibBridgeTargetModuleOpen,
.read = DibBridgeTargetModuleReadData, //資料傳輸
.write = DibBridgeTargetModuleWriteData
.release = DibBridgeTargetModuleRelease,
};
- .ioctl/.read 等等
user space和kernel space的傳輸通道,通過使用copy_from_user和copy_to_user這樣的函數來實作資料傳遞