- 存儲技術(shù)原理分析
- 敖青云著
- 1384字
- 2018-12-27 02:38:23
2.7 驅(qū)動模型編程模式
由于Linux驅(qū)動模型核心的支持,驅(qū)動模型編程變得比較簡單,并且有一定的“套路”可循,以及后面要講述的PCI子系統(tǒng)和SCSI子系統(tǒng)都是驅(qū)動模型編程的范例,我們這里先大致概括如下。
1.總線類型邏輯
定義一個總線類型(struct bus_type)對象,在該對象中,需要指定總線類型的名字,還需要實(shí)現(xiàn)一些回調(diào)函數(shù),例如match、probe等。
在子系統(tǒng)或模塊加載時調(diào)用bus_register函數(shù)向Linux內(nèi)核注冊這個總線類型,在子系統(tǒng)或模塊卸載時調(diào)用bus_unregister函數(shù)從Linux內(nèi)核注銷這個總線類型。一般子系統(tǒng)或模塊也可以根據(jù)需要對bus_register和bus_unregister函數(shù)進(jìn)行封裝。
如果所有功能不是在一個模塊中實(shí)現(xiàn),就需要使用EXPORT_SYMBOL宏導(dǎo)出總線類型以便其他代碼使用。
2.設(shè)備邏輯
定義功能設(shè)備結(jié)構(gòu)體,通常將驅(qū)動模型設(shè)備描述符(struct device)作為一個域嵌入到這個結(jié)構(gòu)體。此外,還可以在結(jié)構(gòu)體中嵌入另一個驅(qū)動模型設(shè)備描述符(struct device)。如果是這樣,那么前一個我們稱為“內(nèi)嵌的通用設(shè)備”,它是為了將這個功能設(shè)備鏈入到總線類型的設(shè)備鏈表而用的,而后一個我們稱為“內(nèi)嵌的類設(shè)備”,它是為了將這個功能設(shè)備鏈入到類的設(shè)備鏈表而用的。建議定義專門的宏或內(nèi)聯(lián)函數(shù)實(shí)現(xiàn)從驅(qū)動模型設(shè)備獲得功能設(shè)備,這種定義方式可以讓編譯器檢查要執(zhí)行的操作的類型安全性。
在功能設(shè)備被發(fā)現(xiàn)時,除了業(yè)務(wù)邏輯所必須的初始化外,還需要對“內(nèi)嵌的通用設(shè)備”以及“內(nèi)嵌的類設(shè)備”進(jìn)行初始化。對于“內(nèi)嵌的通用設(shè)備”,最重要的要初始化的域有bus_id、parent和bus。bus_id域是一個ASCII字符串,包含了設(shè)備在總線上的地址,其格式取決于特定的總線,這一點(diǎn)在sysfs中表示設(shè)備非常必要。parent是設(shè)備物理意義上的父親。總線驅(qū)動需要正確設(shè)置這個域。bus域是一個指向設(shè)備所屬總線類型的指針,這個域應(yīng)該設(shè)置為前面聲明并初始化的bus_type。對于“內(nèi)嵌的類設(shè)備”,最重要的要初始化的域有class。當(dāng)然,可以調(diào)用device_initialize函數(shù)對它們執(zhí)行一些基本的初始化動作。
在其后的某個時間,應(yīng)該調(diào)用device_add函數(shù),分別傳入“內(nèi)嵌的通用設(shè)備”和“內(nèi)嵌的類設(shè)備”的地址,向Linux內(nèi)核添加功能設(shè)備。這將會把功能設(shè)備同時鏈入到總線類型的設(shè)備鏈表,以及類的設(shè)備鏈表中,盡管實(shí)際上的功能設(shè)備對象只有一個。它還會在sysfs文件系統(tǒng)中為功能設(shè)備創(chuàng)建相應(yīng)的目錄,并添加屬性文件以及符號鏈接文件等。如果要從Linux內(nèi)核中刪除功能設(shè)備,則應(yīng)該分別針對“內(nèi)嵌的通用設(shè)備”和“內(nèi)嵌的類設(shè)備”調(diào)用device_del函數(shù)。
功能設(shè)備被添加到系統(tǒng),它就確確實(shí)實(shí)存在了。至于是何時被綁定到功能驅(qū)動,那就是驅(qū)動模型核心的事了。
3.驅(qū)動邏輯
驅(qū)動邏輯和設(shè)備邏輯類似。首先是聲明一個功能驅(qū)動結(jié)構(gòu)體,將驅(qū)動模型驅(qū)動描述符(struct device_driver)作為它的一個域,還可以根據(jù)需要包含了驅(qū)動模型核心可能調(diào)用的操作集。
在稍后的某個時刻,調(diào)用driver_register函數(shù)向Linux內(nèi)核注冊功能驅(qū)動,以其內(nèi)嵌的驅(qū)動模型驅(qū)動描述符為參數(shù),在注冊之前,必須初始化一些必要的域:例如name和bus。其中bus域必須指向前面聲明并初始化的bus_type。與此相反,在驅(qū)動從Linux內(nèi)核注銷時,調(diào)用driver_unregister函數(shù)。一般子系統(tǒng)或模塊也可以根據(jù)需要對driver_register和driver_unregister函數(shù)進(jìn)行封裝。
注冊驅(qū)動會將功能驅(qū)動掛入總線類型的驅(qū)動鏈表,并在sysfs文件系統(tǒng)中為功能驅(qū)動創(chuàng)建對應(yīng)的目錄,以及屬性文件和符號鏈接等。與此同時,驅(qū)動模型會嘗試將驅(qū)動去綁定總線類型的設(shè)備鏈表中的設(shè)備。是否可以綁定完全是功能特定的,因此往往最終要調(diào)用功能驅(qū)動中定義的回調(diào)方法。
4.類和接口邏輯
取決于具體的功能,子系統(tǒng)或模塊也可使實(shí)現(xiàn)類和接口邏輯。它們基本上也采用類似的流程,具體例子可以參考SCSI子系統(tǒng),以及sg模塊。
- Natural Language Processing Fundamentals
- Google App Inventor
- 群體智能與數(shù)據(jù)挖掘
- 網(wǎng)絡(luò)組建與互聯(lián)
- Docker on Amazon Web Services
- HBase Essentials
- Mastering Ansible(Second Edition)
- Xilinx FPGA高級設(shè)計(jì)及應(yīng)用
- Effective Business Intelligence with QuickSight
- 巧學(xué)活用Photoshop
- 我的IT世界
- Hands-On Data Analysis with Scala
- Kibana 7 Quick Start Guide
- BeagleBone Home Automation
- 工業(yè)機(jī)器人設(shè)計(jì)與實(shí)例詳解