S3C2410看門狗驅動分析

根據linux中總線、設備和驅動這個模型來看,所有的設備驅動都掛在總線上,並且驅動應該是和平臺無關的。唯一和平臺有關的一類驅動應該是芯片內部的各個控制器的驅動,例如芯片內部I2C控制器,芯片內部LCD控制器,芯片內部看門狗等等。如果是一個外部的LCD控制器的驅動程序,它的實現一定要和平臺無關,這樣針對不同的平臺只要修改板級文件即可,而不需要修改驅動程序本身。從linux內核源代碼中的S3c2410_wdt.c(位於drivers/watchdog中)可以看出,從不同的角度看,看門狗分別可以屬於:平臺設備、字符設備和混雜設備。所以可以看到該驅動程序中不僅實現了平臺設備驅動的probe, remove等函數,還實現了字符設備的file-operations中的open,write, ioctl, llseek, release等函數。下面分析這個驅動程序。

 

第一個問題:platform_driver和platform_device是如何建立關聯的?

   在驅動程序S3c2410_wdt.c中定義了platform_driver結構體s3c2410wdt_driver,代碼清單如下:

 

其中的.name = "s3c2410-wdt"代表了驅動的名稱。

而相應的設備在平臺相關的文件中已經定義了(在arch/arm/plat-s3c24xx/Devs.c)代碼清單如下:

其中的設備名稱也是"s3c2410-wdt".

並且這個設備已經在平臺初始化時使用platform_add_devices函數添加到了總線上。 以smdk2410開發板爲例,代碼清單如下:

可知現在總線已經掛上了一個名爲"s3c2410-wdt"的設備了。

 

在加載驅動模塊時,執行了watchdog_init函數,代碼清單如下:

其中platform_driver_register函數的作用是將這個驅動註冊到platform總線上,同時尋找在platform總線上與之匹配的設備。使用sourceinsight可以清楚看到這其中主要函數的執行順序爲:

platform_driver_register --> driver_register --> bus_add_driver --> driver_attach --> bus_for_each_dev --> __driver_attach --> driver_match_device --> platform的match方法:of_platform_bus_match。仔細查看這個方法會發現實際上就是匹配了設備的名稱和驅動的名稱,只要這兩個名字一樣,就匹配成功。如果匹配成功,則在__driver_attach中繼續調用driver__probe_device方法,這個方法最終調用的就是platform_driver中的probe方法。至此完成了驅動程序與設備的關聯。

 

第二個問題:既然最正確的驅動程序中不應該包含平臺相關的代碼,那麼驅動是怎樣得到平臺的信息的呢?

   這裏使用了platform_driver中的probe方法。 probe,顧名思義,是“探測”,是driver對device的探測。結合S3c2410_wdt.c源代碼對探測的過程作進一步理解。

 

第三個問題: 具體操作硬件的代碼在哪?

在S3c2410_wdt.c中直接對硬件進行操作的函數有

s3c2410wdt_start --開始開始看門狗計時器

s3c2410wdt_stop --停止看門狗計時器

s3c2410wdt_keepalive --“餵狗”

s3c2410wdt_set_heartbeat -- 設置“心跳”,就是計數週期

s3c2410wdt_suspend --掛起看門狗,就是在關閉看門狗之前保存狀態

s3c2410wdt_resume --恢復看門狗計時器

 

第四個問題: 這些操作硬件的代碼在驅動程序中又是怎麼組織的呢?

前面說到,芯片內部的這個看門狗從不同角度看是有不同的身份的:平臺設備,字符設備和混雜設備。下圖顯示了操作硬件的代碼是怎樣組織的。

 

 

 ------------------------------------------------------以上---------------------------------------------------

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章