物聯網之核心及驅動開發初級五(平臺匯流排開發)
高階驅動--平臺匯流排:
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)