平臺總線開發筆記:https://blog.csdn.net/weixin_39148042/article/details/82495343
高級驅動--平臺總線:
Linux設備驅動模型的由來:
1,實現入口函數 xxx_init()和卸載函數 xxx_exit()
2,申請設備號 register_chrdev (與內核相關)
3,利用udev/mdev機制創建設備文件(節點) class_create, device_create (與內核相關)
4,硬件部分初始化
io資源映射 ioremap,內核提供gpio庫函數 (與硬件相關)
註冊中斷(與硬件相關)
5,構建 file_operation結構 (與內核相關)
6,實現操作硬件方法 xxx_open,xxx_read,xxxx_write
設備驅動模型:總線、device、driver
device對象:設備對象,描述設備信息,包括地址,中斷號,甚至其他自定義的數據
driver對象:描述設備驅動的方法(代碼邏輯)
bus:平臺總線,平臺總線會建立兩個鏈表,一個與device相關的鏈表,另一個與driver相關的鏈表,我們寫的所有的device和driver都會添加(註冊)到bus中的相應鏈表中,device和driver中都有一個名字,找出device和driver名字相同的匹配在一起,形成一個完整的設備驅動,然後調用driver中的probe函數(方法),如果需要移除設備,調用driver中的remove函數(方法),這就是bus的功能。
Sysfs文件系統:告訴我們內核驅動的一些信息
下圖是拓撲圖,表示設備之間的一種關係,可以通過總線查看一個設備,也可以通過Devices查看一個設備,還可以通過一個類來查看一個設備。
/sys目錄下存放的有Buses、Devices、Classes
Buses:所有總線,下圖usb是其中的一個總線
Devices:所有設備的集合
Classes:將所有設備進行分類,比如:輸入設備等
總線設備都可以在Buses、Devices和Classes中找到。
/sys:
block:用於管理塊設備,系統中的每一個塊設備會在該目錄下對應一個子目錄。
bus:用於管理總線,每註冊一條總線,在該目錄下有一個對應的子目錄。
其中,每個總線子目錄下會有兩個子目錄:devices和drivers。
devices包含系統中所有屬於該總線的的設備。
class:將系統中的設備按功能分類。
dev:該目錄包含已註冊的設備號(設備節點)的視圖,包括char和block
kernel:內核中的相關參數。
module:內核中的模塊信息。
fireware:內核中的固件信息。
fs:描述內核中的文件系統。
配對函數(match)、探測函數(probe)和卸載函數:
1,int (*match)(struct device *dev, struct device_driver *drv);--總線bus
當總線上添加了新設備或者新驅動函數的時候,內核會調用一次或者多次這個函數。
如果現在添加了一個新的驅動(driver),內核就會調用所屬總線(bus)的match函數,
配對總線上所有的設備(device),如果驅動能夠對應處理其中一個設備,函數返回1,
告訴內核配對成功。一般的,match函數是判斷設備的結構體成員device->bus_id
和驅動函數的結構體成員device_driver->name是否一致,如果一致,
那就表明配對成功。
2,int (*probe)(struct device *dev);---- 驅動driver
當配對(match)成功後,內核就會調用指定驅動中的probe函數來查詢設備能否被該
驅動操作,如果可以,驅動就會對該設備進行相應的操作,如初始化。所以說,真正
的驅動函數入口是在probe函數中。
3, int (*remove) (struct device *dev); ---驅動driver
當設備從總線中移除時,內核會調用驅動函數中的remove函數調用,進行一些設備
卸載相應的操作
總線模型編程:
平臺總線模型:
平臺總線編程接口:
Pdev註冊和註銷
int platform_device_register(struct platform_device * pdev)
void platform_device_unregister(struct platform_device * pdev)
獲取資源數據
int platform_get_irq(struct platform_device * dev,unsigned int num)
struct resource * platform_get_resource_byname(struct platform_device * dev, unsigned int type,const char * name)