本篇文章將介紹Linux設(shè)備驅(qū)動開發(fā)的基本知識,帶你快速撥開Linux驅(qū)動這團迷霧。文章分為如下3個小節(jié)進行講解:
1、設(shè)備驅(qū)動的概念和作用;
2、在無操作系統(tǒng)和有操作系統(tǒng)的情況下設(shè)備驅(qū)動的設(shè)計開發(fā);
3、Linux設(shè)備驅(qū)動的重點、難點和學(xué)習(xí)方法。
文章最后會給出一個簡單的LED驅(qū)動在無操作系統(tǒng)和Linux操作系統(tǒng)下的實現(xiàn)示例。
好,Let's go
1、設(shè)備驅(qū)動的概念和作用
大家都知道在Linux開發(fā)中是一個分層的思想,也就是說應(yīng)用層、操作系統(tǒng)層、驅(qū)動層和硬件層分別獨立,然后為上一層提供API接口。對設(shè)備驅(qū)動通俗一點的解釋就是:驅(qū)使硬件設(shè)備行動。驅(qū)動與底層硬件直接打交道,按照硬件設(shè)備的具體工作方式,讀寫其寄存器,完成設(shè)備輪詢、中斷處理和DMA通信等。設(shè)備驅(qū)動實際上充當(dāng)了硬件和應(yīng)用軟件之間的紐帶,在系統(tǒng)沒有操作系統(tǒng)的情況下工程師可以根據(jù)硬件設(shè)備的特點自行定義接口,如對串口定義SerialSend()、SerialReceive(),對繼電器定義RelayOn()、RelayOff()等。而在有操作系統(tǒng)的情況下,驅(qū)動的架構(gòu)則由操作系統(tǒng)定義,因為驅(qū)動架構(gòu)也屬于操作系統(tǒng)內(nèi)核的一部分,驅(qū)動工程師必須按照相應(yīng)的架構(gòu)設(shè)計驅(qū)動,這樣的話驅(qū)動才能融入操作系統(tǒng)內(nèi)核中,并正常運行。
2、在無操作系統(tǒng)和有操作系統(tǒng)的情況下設(shè)備驅(qū)動的設(shè)計開發(fā)
2.1、無操作系統(tǒng)的情況下
事實上,在許多情況下我們的程序也運行在無操作系統(tǒng)的環(huán)境中(裸機程序),因為對于那些功能比較單一、控制并不復(fù)雜的系統(tǒng)不需要多任務(wù)調(diào)度和文件系統(tǒng)等復(fù)雜的功能,用單任務(wù)架構(gòu)完全可以很好的實現(xiàn)我們的需求,也就是在一個無限循環(huán)(單片機編程中的while(1)死循環(huán))中夾雜著對設(shè)備中斷的檢測或者對設(shè)備的輪詢。這一部分的知識相信有過單片機編程經(jīng)驗的朋友一定非常熟悉了,下面是這種單任務(wù)軟件的架構(gòu):
主函數(shù)
在這樣的系統(tǒng)中,雖然不存在操作系統(tǒng),但是設(shè)備驅(qū)動必須存在。一般情況下每一種設(shè)備驅(qū)動都會定義成一個軟件模塊,包含.c文件和.h文件。
2.2、有操作系統(tǒng)的情況下
當(dāng)包含操作系統(tǒng)時,我們還需要將驅(qū)動融入內(nèi)核,為了實現(xiàn)這種融合,必須在所有設(shè)備的驅(qū)動中設(shè)計提供給操作系統(tǒng)內(nèi)核的接口,這類接口由操作系統(tǒng)規(guī)定(這是一個復(fù)雜的過程,在后續(xù)更新的文章中會由淺及深的說明)。所以,存在操作系統(tǒng)的時候,驅(qū)動便成為了連接硬件和Linux內(nèi)核的橋梁。當(dāng)設(shè)備成功注冊到系統(tǒng)中,也就是讓系統(tǒng)知道了我們需要使用的設(shè)備的存在之后,Linux會將設(shè)備映射到文件系統(tǒng)的文件和目錄中,然后通過系統(tǒng)調(diào)用的接口open()、write()、read()、close()等即可訪問我們的設(shè)備。
3、Linux設(shè)備驅(qū)動的重點、難點和學(xué)習(xí)方法
Linux設(shè)備驅(qū)動的學(xué)習(xí)是一項浩繁和長久的過程,其中包含了如下重點和難點:
1、編寫Linux設(shè)備驅(qū)動要求工程師有一定的硬件基礎(chǔ);
2、編寫Linux設(shè)備驅(qū)動要求工程師有非常好的C語言基礎(chǔ),能靈活的運用C語言的結(jié)構(gòu)體、指針以及內(nèi)存動態(tài)申請和釋放等;
3、編寫Linux設(shè)備驅(qū)動要求工程師有一定的Linux內(nèi)核基礎(chǔ),并不要求對內(nèi)核的各個部分有深入的研究,但至少我們要明白驅(qū)動程序與內(nèi)核的接口;
4、編寫Linux設(shè)備驅(qū)動要求工程師有多任務(wù)并發(fā)控制和同步的基礎(chǔ),因為在驅(qū)動中會大量的使用自旋鎖、互斥、信號量和等待隊列等并發(fā)與同步機制。
看到這里,相信你已經(jīng)對Linux設(shè)備驅(qū)動有了基本的認(rèn)識,首先我們要明白,Linux驅(qū)動程序是門檻最高難度最大的一部分,當(dāng)然薪資也是相對最高的,所以只要我們掌握了方法堅持學(xué)習(xí)下去,一定可以撥開這團迷霧看見陽光。筆者會定期更新關(guān)于嵌入式Linux和C語言在開發(fā)和學(xué)習(xí)中的經(jīng)驗和技巧。歡迎關(guān)注!
文章的最后,給出LED驅(qū)動在無操作系統(tǒng)和Linux操作系統(tǒng)下的實現(xiàn)示例,以供大家作以比較。LED一般直接由CPU的GPIO口控制,GPIO一般由兩組寄存器控制,即一組控制寄存器和一組數(shù)據(jù)寄存器??刂萍拇嫫骺稍O(shè)置GPIO口的工作方式為輸入或輸出。當(dāng)引腳被設(shè)置為輸出時,向數(shù)據(jù)寄存器的對應(yīng)位寫入1和0分別在引腳上產(chǎn)生高電平和低電平;當(dāng)引腳設(shè)置為輸入時,讀取數(shù)據(jù)寄存器的對應(yīng)位可獲得引腳上的電平高低。
在無操作系統(tǒng)時的LED驅(qū)動如下:
上述程序中的LedInit()、LedOn()、LedOff()都直接作為驅(qū)動提供給應(yīng)用程序使用。
在Linux下,我們使用字符設(shè)備驅(qū)動的框架來編寫對應(yīng)于上圖中的LED驅(qū)動程序,為了遵循Linux編程的命名習(xí)慣,重新將其命名為led_init()、led_on()、led_off(),注意:你現(xiàn)在并不需要能夠讀懂下圖中的這些代碼,我在后續(xù)的文章更新中會繼續(xù)講解說明。
Linux操作系統(tǒng)下的LED驅(qū)動程序:
在這里,我們只需要有一個感性的認(rèn)識即可,那就是上圖中陌生的結(jié)構(gòu)和元素都是Linux內(nèi)核為設(shè)備定義的,在后面的學(xué)習(xí)中,我們只需要會使用即可(都是套路)。
-
led
+關(guān)注
關(guān)注
242文章
23252瀏覽量
660554 -
Linux
+關(guān)注
關(guān)注
87文章
11292瀏覽量
209322 -
API
+關(guān)注
關(guān)注
2文章
1499瀏覽量
61959
發(fā)布評論請先 登錄
相關(guān)推薦
評論