當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > Linux字符設(shè)備驅(qū)動模型之框架解說
一、軟件操作硬件設(shè)備模型
在進(jìn)行嵌入式開發(fā)的過程中,在常做的事情就是驅(qū)動配置硬件設(shè)備,然后根據(jù)功能需求使用硬件設(shè)備,實(shí)現(xiàn)功能的邏輯。如下圖為其相互之間的關(guān)系。
如上圖所示:
驅(qū)動程序:主要作為操作和配置硬件設(shè)備,使得硬件設(shè)備能夠正常進(jìn)行工作。例如,在寫點(diǎn)燈程序時,前提條件是從原理圖了解到LED等與CPU/MCU之間的硬件連接(使用了哪一個GPIO口),驅(qū)動程序的作用就是初始化配置GPIO口,使得GPIO口能夠進(jìn)行工作,比如現(xiàn)在配置為推完輸出模式。GPIO能夠正常工作之后,那么就需要進(jìn)行基本的操作了,即燈亮和等滅。這就是驅(qū)動程序。
應(yīng)用程序:當(dāng)驅(qū)動程序能夠時間基本的燈亮和燈滅,那么是需要實(shí)現(xiàn)跑馬燈,還是各種花樣的燈的顯示,這就由應(yīng)用程序來決定了。
硬件設(shè)備能夠接受CPU/MCU通過驅(qū)動程序進(jìn)行的操作,或者是能夠?yàn)镃PU/MCU提供有效的數(shù)據(jù)。
二、Linux系統(tǒng)軟件操作硬件模型
對于Linux操作系統(tǒng)而言,因其系統(tǒng)的強(qiáng)大和所支持功能的完善,可支持各種設(shè)備在Linux操作系統(tǒng)下運(yùn)行。所以設(shè)備的類型可謂繁多,如:字符設(shè)備,塊設(shè)備,網(wǎng)絡(luò)接口設(shè)備,USB設(shè)備,PCI設(shè)備,平臺設(shè)備,混雜設(shè)備……等等,而設(shè)備類型不同,也意味著其對應(yīng)的驅(qū)動程序模型不同。即每一種類型的設(shè)備,都有其相應(yīng)的驅(qū)動模型。
但總體而言,既然都是運(yùn)行在Linux操作系統(tǒng)下的設(shè)備,所以其應(yīng)當(dāng)存在相應(yīng)的驅(qū)動架構(gòu)來進(jìn)行驅(qū)動設(shè)備。如下圖:
如上圖,對于Linux操作系統(tǒng)而言,用戶空間的應(yīng)用程序和內(nèi)核空間的驅(qū)動程序,有著千絲萬縷的關(guān)系,但卻又相互獨(dú)立。他們通過文件的方式進(jìn)行相互之間的通信。而驅(qū)動程序則是依賴于Linux內(nèi)核的驅(qū)動架構(gòu)進(jìn)行編寫的程序,為用戶空間的應(yīng)用程序提供相應(yīng)的接口通道。而設(shè)備操作程序則是在Linux內(nèi)核驅(qū)動架構(gòu)下進(jìn)行與設(shè)備直接交互的程序代碼,比如配置初始化CPU私有外設(shè),初始化硬件設(shè)備,對硬件設(shè)備進(jìn)行基本操作等等,總之目的是讓硬件設(shè)備能夠正常的工作。
那么在Linux系統(tǒng)中編寫內(nèi)核驅(qū)動,其驅(qū)動模型是怎樣的呢??
如上圖:
初始化內(nèi)核驅(qū)動:依賴于Linux內(nèi)核的驅(qū)動模型,建立所需要操作的設(shè)備驅(qū)動并進(jìn)行相應(yīng)的操作。如下圖:
實(shí)現(xiàn)設(shè)備操作:根據(jù)硬件設(shè)備的型號、功能特性等,實(shí)現(xiàn)驅(qū)動硬件設(shè)備正常工作,能夠進(jìn)行基本的操作,比如讀取設(shè)備數(shù)據(jù)或者向設(shè)備寫數(shù)據(jù)等。
注銷設(shè)備驅(qū)動:在Linux系統(tǒng)中,會存在設(shè)備熱拔插或者用戶不想使用相應(yīng)設(shè)備的應(yīng)用場景,那么可以將相應(yīng)的設(shè)備驅(qū)動在內(nèi)核空間注銷,將不能使用相應(yīng)的設(shè)備驅(qū)動。
三、Linux字符設(shè)備驅(qū)動模型
對于Linux內(nèi)核驅(qū)動而言,任何一種設(shè)備驅(qū)動模型都會用Linux內(nèi)核中的一種結(jié)構(gòu)來進(jìn)行描述。
對于字符設(shè)備確定而言,在Linux內(nèi)核中使用struct cdev結(jié)構(gòu)來描述。其結(jié)構(gòu)原型如下:
對于Linux內(nèi)核給出的描述設(shè)備的結(jié)構(gòu),其結(jié)構(gòu)成員并不是都是由程序員使用的,有些結(jié)構(gòu)成員由內(nèi)核內(nèi)部使用,有些結(jié)構(gòu)成員有程序員使用。比如以上struct cdev結(jié)構(gòu)中,由程序員使用的成員為unsigned int count; 、dev_t dev;和const struct file_operations *ops;。
【unsigned int count;】:其表示設(shè)備的數(shù)目/數(shù)量,在同一個系統(tǒng)中,可能存在多個相同的設(shè)備,那么不需要每一個設(shè)備就為其提供一個驅(qū)動,而是統(tǒng)一提供同一個驅(qū)動,只需要在驅(qū)動中識別出是操作哪一個設(shè)備即可。Count結(jié)構(gòu)成員的作用就是記錄這一個驅(qū)動中存在多少個設(shè)備。
【dev_t dev;】:表示這個設(shè)備的設(shè)備號,在Linux操作系統(tǒng)中,通過設(shè)備號的方式來進(jìn)行區(qū)分不同是設(shè)備。
【const struct file_operations *ops;】:設(shè)備驅(qū)動操作的函數(shù)集/方法集。這個方法集為上層應(yīng)用程序提供相應(yīng)的接口通道。實(shí)現(xiàn)用戶空間的操作函數(shù)與內(nèi)核空間的操作實(shí)現(xiàn)一一映射關(guān)系。
四、Linux操作系統(tǒng)中硬件的操作方式有句話叫做“對于Linux而言,一切皆文件”,所以對于在用戶空間的應(yīng)用程序而言,在面向硬件設(shè)備的操作時,也是通過文件的方式進(jìn)行操作。操作相應(yīng)的設(shè)備文件節(jié)點(diǎn),就等同于操作了其設(shè)備文件節(jié)點(diǎn)對應(yīng)的硬件設(shè)備。
硬件設(shè)備相關(guān)的設(shè)備文件節(jié)點(diǎn)存放于/dev目錄下。如下圖:
如上圖所示,/dev目錄下的文件節(jié)點(diǎn)均為對應(yīng)的硬件設(shè)備的設(shè)備文件。例如:ttyS0設(shè)備文件為PC臺式機(jī)默認(rèn)的9針串口設(shè)備節(jié)點(diǎn)。所以對相應(yīng)設(shè)備文件節(jié)點(diǎn)的讀寫操作即是對其所對應(yīng)的硬件進(jìn)行讀寫操作。