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