一、芯片手冊(cè)閱讀方法
芯片手冊(cè)往往長(zhǎng)達(dá)數(shù)百頁甚至上千頁忿偷,而且全部都是英文金顿,從頭到尾不加區(qū)分地閱讀需要花費(fèi)非常長(zhǎng)的時(shí)間,而且不一定能獲取對(duì)設(shè)計(jì)設(shè)備驅(qū)動(dòng)有幫助的信息鲤桥。芯片手冊(cè)的正確閱讀方法是快速而準(zhǔn)確地定位到有用的信息揍拆,重點(diǎn)閱讀這些信息,忽略無關(guān)的內(nèi)容茶凳。
下面以S3C6410A的datasheet為例來分析閱讀方法礁凡,為了直觀地反應(yīng)閱讀過程,本節(jié)的圖都直接從手冊(cè)中抓圖而得慧妄。
打開S3C6410A的datasheet顷牌,發(fā)現(xiàn)頁數(shù)為1378頁,閱讀這樣的數(shù)據(jù)手冊(cè)所花費(fèi)的時(shí)間足夠完成整個(gè)驅(qū)動(dòng)的設(shè)計(jì)工作了塞淹。S3C6410A datasheet的第一章“PRODUCT OVERVIES”即“產(chǎn)品綜述”是必讀的窟蓝,通過閱讀這一部分可以獲知整個(gè)芯片的組成。這一章往往會(huì)給出一個(gè)芯片的整體結(jié)構(gòu)圖饱普,并對(duì)芯片內(nèi)的主要模塊進(jìn)行一個(gè)簡(jiǎn)潔的描述运挫。如圖1.1所示,S3C6410A的整體結(jié)構(gòu)圖在第61頁出現(xiàn)套耕。
圖1.1 S3C6410A的整體結(jié)構(gòu)圖
接下來的第2~43章每一章都對(duì)應(yīng)S3C6410A整體結(jié)構(gòu)圖中的一個(gè)模塊谁帕,這可以從該芯片手冊(cè)的目錄結(jié)構(gòu)圖中看出來。
第2章的“MemoryMap”即“內(nèi)存映射”比較關(guān)鍵冯袍,對(duì)應(yīng)定位存儲(chǔ)器和外設(shè)所對(duì)應(yīng)的基地址有直接指導(dǎo)意義匈挖,這一部分應(yīng)該細(xì)看。
第3~34章對(duì)應(yīng)于CPU內(nèi)部集成的外設(shè)或總線控制器康愤,當(dāng)具體編寫某一接口的驅(qū)動(dòng)時(shí)儡循,應(yīng)該詳細(xì)閱讀,主要是分析數(shù)據(jù)征冷、控制择膝、地址寄存器(datasheet中一般會(huì)以表格列出)的訪問控制和具體設(shè)備的操作流程(datasheet中會(huì)給出步驟,有的還會(huì)給出流程圖)检激。譬如為了編寫S3C6410A的IIC控制器驅(qū)動(dòng)肴捉,我們可以詳細(xì)閱讀類似圖1.2的寄存器定義表格和圖1.3的操作流程圖腹侣。
圖1.2 芯片手冊(cè)中以表格形式列出的寄存器定義
圖1.3 芯片手冊(cè)中給出外設(shè)控制器的操作流程
第44章“ELECTRICAL DATA”即“電氣數(shù)據(jù)”,描述芯片的電氣特性齿穗,如電壓傲隶、電流和各種工作模式下的時(shí)序及建立時(shí)間和保持時(shí)間的要求。所有的datasheet都會(huì)包含類似章節(jié)缤灵,這一章對(duì)于硬件工程師比較關(guān)鍵,但是一般來說蓝晒,驅(qū)動(dòng)工程師不需要閱讀腮出。
第45章“MECHANICAL DATA”即“機(jī)械數(shù)據(jù)”,描述芯片的物理特性芝薇,尺寸和封裝胚嘲,硬件工程師會(huì)依據(jù)這一章繪制芯片的封裝(footprint),驅(qū)動(dòng)工程師無需閱讀洛二。
二馋劈、Linux設(shè)備驅(qū)動(dòng)基礎(chǔ)
2.1 設(shè)備驅(qū)動(dòng)的作用
任何一個(gè)計(jì)算機(jī)系統(tǒng)的運(yùn)轉(zhuǎn)都是系統(tǒng)中軟硬件共同努力的結(jié)果,沒有硬件的軟件是空中樓閣晾嘶,而沒有軟件的硬件則只是一堆廢鐵妓雾。硬件是底層基礎(chǔ),是所有軟件得以運(yùn)行的平臺(tái)垒迂,代碼最終會(huì)落實(shí)為硬件上的組合邏輯與時(shí)序邏輯械姻。軟件則實(shí)現(xiàn)了具體的應(yīng)用,它按照各種不同的業(yè)務(wù)需求而設(shè)計(jì)机断,完成了用戶的最終訴求楷拳。硬件較固定,軟件則很靈活可以適應(yīng)各種復(fù)雜多變的應(yīng)用吏奸。
對(duì)設(shè)備驅(qū)動(dòng)最通俗的解釋就是“驅(qū)使硬件設(shè)備行動(dòng)”欢揖。驅(qū)動(dòng)與底層硬件直接打交道,按照硬件設(shè)備的具體工作方式奋蔚,讀寫設(shè)備的寄存器她混,完成設(shè)備的輪詢、中斷處理泊碑、DMA通信产上,進(jìn)行物理內(nèi)存向虛擬內(nèi)存的映射等,最終讓通信設(shè)備能收發(fā)數(shù)據(jù)蛾狗,讓顯示設(shè)備能顯示文字和畫面晋涣,讓存儲(chǔ)設(shè)備能記錄文件和數(shù)據(jù)等。
由此可見沉桌,設(shè)備驅(qū)動(dòng)充當(dāng)了硬件和應(yīng)用軟件之間的紐帶谢鹊,它使得應(yīng)用軟件只需要調(diào)用系統(tǒng)軟件的應(yīng)用編程接口(API)就可以讓硬件去完成要求的工作算吩。驅(qū)動(dòng)程序溝通著硬件和應(yīng)用軟件,而驅(qū)動(dòng)工程師則溝通著硬件工程師和應(yīng)用軟件工程師佃扼。目前偎巢,隨著通信、電子行業(yè)的迅速發(fā)展兼耀,全世界每天都會(huì)有大量的新芯片被生產(chǎn)压昼,大量的新電路板被設(shè)計(jì),也因此瘤运,會(huì)有大量設(shè)備驅(qū)動(dòng)需要開發(fā)窍霞。這些驅(qū)動(dòng),或運(yùn)行在簡(jiǎn)單的單任務(wù)環(huán)境拯坟,或運(yùn)行在VxWorks但金、Linux、Windows等多任務(wù)操作系統(tǒng)環(huán)境郁季,發(fā)揮著不可替代的作用冷溃。
大多數(shù)編程可以分為兩個(gè)部分:==機(jī)制==,++需要提供什么功能++梦裂;==策略==:++如何使用這些功能++似枕。++Linux應(yīng)用程序則是實(shí)現(xiàn)策略,而Linux驅(qū)動(dòng)程序的目的就是實(shí)現(xiàn)機(jī)制年柠,而且要完成應(yīng)用程序到驅(qū)動(dòng)再到具體硬件的映射任務(wù)++菠净。
在Linux中,驅(qū)動(dòng)程序是內(nèi)核的一部分彪杉,它屏蔽了硬件細(xì)節(jié)毅往,是整個(gè)操作系統(tǒng)的基礎(chǔ)。
2.2 設(shè)備的分類與特點(diǎn)
驅(qū)動(dòng)針對(duì)的對(duì)象是存儲(chǔ)器和外設(shè)(包括CPU內(nèi)部集成的存儲(chǔ)器和外設(shè))派近,而不是針對(duì)CPU核攀唯。Linux將存儲(chǔ)器和外設(shè)分為3個(gè)基礎(chǔ)大類:++字符設(shè)備、塊設(shè)備渴丸、網(wǎng)絡(luò)設(shè)備++侯嘀。
字符設(shè)備是指必須以串行順序依次進(jìn)行訪問的設(shè)備,如觸摸屏谱轨、磁帶驅(qū)動(dòng)器戒幔、鼠標(biāo)等。塊設(shè)備可以任意順序進(jìn)行訪問土童,以塊為單位進(jìn)行操作诗茎,如磁盤、軟驅(qū)等献汗。字符設(shè)備不需要經(jīng)過系統(tǒng)的快速緩沖敢订,而塊設(shè)備需經(jīng)過系統(tǒng)的快速緩沖王污。但是,字符設(shè)備和塊設(shè)備并沒有嚴(yán)格的界限楚午,有些設(shè)備(如Flash設(shè)備)既可看做字符設(shè)備昭齐,也可作為塊設(shè)備來訪問。
字符設(shè)備和塊設(shè)備的驅(qū)動(dòng)設(shè)計(jì)呈現(xiàn)出很大的差異矾柜,但對(duì)于用戶而言阱驾,他們都使用文件系統(tǒng)操作接口open()、close()怪蔑、read()里覆、write()、ioctl()等進(jìn)行訪問饮睬。
在Linux系統(tǒng)中租谈,網(wǎng)絡(luò)設(shè)備是面向數(shù)據(jù)包的接收和發(fā)送而設(shè)計(jì)篮奄,并不對(duì)應(yīng)文件系統(tǒng)節(jié)點(diǎn)捆愁。內(nèi)核與網(wǎng)絡(luò)設(shè)備的通信與內(nèi)核和字符設(shè)備、塊設(shè)備的通信方式完全不同窟却。
另外一些設(shè)備分類方法中所稱的I2C驅(qū)動(dòng)昼丑、USB驅(qū)動(dòng)、PCI驅(qū)動(dòng)夸赫、LCD驅(qū)動(dòng)等本身可歸納入3個(gè)基礎(chǔ)大類菩帝,但是對(duì)于這些復(fù)雜的設(shè)備,Linux也定義了獨(dú)特的驅(qū)動(dòng)體系結(jié)構(gòu)茬腿。
2.3 設(shè)備驅(qū)動(dòng)的重點(diǎn)與難點(diǎn)
Linux設(shè)備驅(qū)動(dòng)學(xué)習(xí)是一項(xiàng)好飯的工作呼奢,包含如下的重點(diǎn)和難點(diǎn):
- 編寫Linux設(shè)備驅(qū)動(dòng)要求工程師有非常好的硬件基礎(chǔ),懂得SRAM切平、Flash握础、SDRAM、磁盤的讀寫方式悴品、UART禀综、IIC、USB苔严、LCD等設(shè)備的接口及輪詢定枷、中斷、DMA的原理届氢,PCI總線的工作方式以及CPU的內(nèi)存管理單元MMU等欠窒;
- 編寫Linux設(shè)備驅(qū)動(dòng)要求工程師有非常好的C語言基礎(chǔ),能靈活地運(yùn)用C語言的結(jié)構(gòu)體退子、指針贱迟、函數(shù)指針及內(nèi)存動(dòng)態(tài)申請(qǐng)和釋放等姐扮;
- 編寫Linux設(shè)備驅(qū)動(dòng)要求工程師有一定的Linux內(nèi)核基礎(chǔ),雖然并不要求工程師對(duì)內(nèi)核各個(gè)部分有深入的研究衣吠,但至少要明白驅(qū)動(dòng)與內(nèi)核的接口茶敏。尤其是對(duì)于塊設(shè)備、網(wǎng)絡(luò)設(shè)備缚俏、Flash設(shè)備惊搏、串口設(shè)備等復(fù)雜設(shè)備,內(nèi)核定義的驅(qū)動(dòng)體系架構(gòu)本身就非常復(fù)雜忧换;
- 編寫Linux設(shè)備驅(qū)動(dòng)要求工程師有非常好的多任務(wù)并發(fā)控制和同步的基礎(chǔ)恬惯,因?yàn)樵隍?qū)動(dòng)中會(huì)大量使用自旋鎖、互斥亚茬、信號(hào)量酪耳、等待隊(duì)列等并發(fā)與同步機(jī)制。
上述經(jīng)驗(yàn)值的獲取并非朝夕之事刹缝,因此需要我們有足夠的學(xué)習(xí)恒心和毅力碗暗。
動(dòng)手實(shí)踐永遠(yuǎn)是學(xué)習(xí)任何軟件開發(fā)的最好方法,學(xué)習(xí)Linux設(shè)備驅(qū)動(dòng)的一個(gè)注意事項(xiàng)是要避免管中窺豹梢夯、只見樹木不見森林言疗,因?yàn)楦黝怢inux設(shè)備驅(qū)動(dòng)都從屬于一個(gè)Linux設(shè)備驅(qū)動(dòng)的架構(gòu),單純而片面地學(xué)習(xí)幾個(gè)函數(shù)颂砸、幾個(gè)數(shù)據(jù)結(jié)構(gòu)是不可能理清驅(qū)動(dòng)中各組成部分之間的關(guān)系的噪奄。因此,Linux驅(qū)動(dòng)的分析方法是點(diǎn)面結(jié)合人乓,將對(duì)函數(shù)和數(shù)據(jù)結(jié)構(gòu)的理解放在整體架構(gòu)的背景之中勤篮。
2.4 應(yīng)用-內(nèi)核-驅(qū)動(dòng)-硬件關(guān)系
2.4.1 無操作系統(tǒng)設(shè)備驅(qū)動(dòng)
在沒有操作系統(tǒng)的情況下,設(shè)備驅(qū)動(dòng)的接口被直接提交給了應(yīng)用軟件工程師色罚,應(yīng)用軟件沒有跨越任何層次就直接訪問了設(shè)備驅(qū)動(dòng)的接口碰缔。驅(qū)動(dòng)包含的接口函數(shù)也與硬件的功能直接吻合,沒有任何附加功能保屯。圖2.1所示為無操作系統(tǒng)情況下硬件手负、驅(qū)動(dòng)與應(yīng)用軟件的關(guān)系。
圖2.1 無操作系統(tǒng)時(shí)正確的硬件姑尺、驅(qū)動(dòng)和應(yīng)用軟件的關(guān)系
下面為兩種不合理的設(shè)計(jì)竟终。圖2.2中將設(shè)備驅(qū)動(dòng)和具體的應(yīng)用軟件模塊平等對(duì)待,驅(qū)動(dòng)中包含了業(yè)務(wù)層面上的處理切蟋,這顯然不符合軟件設(shè)計(jì)中高內(nèi)聚统捶、低耦合的要求。圖2.3中直接在應(yīng)用中操作硬件的寄存器,而不是單獨(dú)設(shè)計(jì)驅(qū)動(dòng)模塊喘鸟,這意味著系統(tǒng)中不存在或未能充分利用可被重用的驅(qū)動(dòng)代碼匆绣。
圖2.2 驅(qū)動(dòng)與應(yīng)用高耦合的不合理設(shè)計(jì)
圖2.3 應(yīng)用直接訪問硬件的不合理設(shè)計(jì)
[圖片上傳失敗...(image-10a194-1551320965105)]
2.4.2 有操作系統(tǒng)設(shè)備驅(qū)動(dòng)
當(dāng)系統(tǒng)中存在操作系統(tǒng)時(shí),驅(qū)動(dòng)變成了連接硬件和內(nèi)核的橋梁什黑。如圖2.4所示崎淳,操作系統(tǒng)的存在勢(shì)必要求設(shè)備驅(qū)動(dòng)附加更多的代碼和功能,把單一的“驅(qū)使硬件設(shè)備行動(dòng)”變成操作系統(tǒng)內(nèi)與硬件交互的模塊愕把,它對(duì)外呈現(xiàn)為操作系統(tǒng)API拣凹,不再給應(yīng)用軟件工程師直接提供接口。
圖2.4 硬件恨豁、驅(qū)動(dòng)嚣镜、操作系統(tǒng)和應(yīng)用程序的關(guān)系
2.4.3 Linux設(shè)備驅(qū)動(dòng)與整個(gè)軟硬件系統(tǒng)的關(guān)系
在Linux系統(tǒng)中,如圖2.5和2.6所示橘蜜,除網(wǎng)絡(luò)設(shè)備外菊匿,字符設(shè)備與塊設(shè)備都被映射到Linux文件系統(tǒng)的文件和目錄,通過文件系統(tǒng)的系統(tǒng)調(diào)用接口open()计福、write()跌捆、read()、close()等即可訪問字符設(shè)備和塊設(shè)備棒搜。所有的字符設(shè)備和塊設(shè)備都統(tǒng)一地呈現(xiàn)給用戶疹蛉。塊設(shè)備比字符設(shè)備負(fù)責(zé),在它上面會(huì)首先建立一個(gè)磁盤/Flash文件系統(tǒng),如FAT债蜜、EXT2娇唯、EXT3、YAFFS2集绰、JFFS2、UBIFS等,它們定義了文件和目錄在存儲(chǔ)介質(zhì)上的組織埃叭。
圖2.5 Linux設(shè)備驅(qū)動(dòng)與整個(gè)軟硬件系統(tǒng)的關(guān)系
圖2.6 Linux設(shè)備驅(qū)動(dòng)與整個(gè)軟硬件系統(tǒng)的關(guān)系
應(yīng)用程序可以使用Linux的系統(tǒng)調(diào)用接口編程,也可以使用C庫(kù)函數(shù)悉罕,出于代碼可移植性的目的赤屋,推薦使用C庫(kù)。C庫(kù)函數(shù)本身也通過系統(tǒng)調(diào)用接口而實(shí)現(xiàn)壁袄,如C庫(kù)函數(shù)fopen()类早、fwrite()、fread()嗜逻、fclose()分別會(huì)調(diào)用操作系統(tǒng)的API:open()涩僻、write()、read()、close()逆日。
2.4.4 有系統(tǒng)后驅(qū)動(dòng)更復(fù)雜嵌巷,那要操作系統(tǒng)干什么?
首先室抽,一個(gè)復(fù)雜的軟件系統(tǒng)需要處理多個(gè)并發(fā)的任務(wù)搪哪,沒有操作系統(tǒng),想完成多任務(wù)并發(fā)是很困難的坪圾;
其次噩死,操作系統(tǒng)給我們提供內(nèi)存管理機(jī)制;一個(gè)典型的例子是神年,對(duì)于多數(shù)含MMU的處理器而言已维,Windows、Linux等操作系統(tǒng)可以讓每個(gè)進(jìn)程都可以獨(dú)立地訪問4GB的內(nèi)存空間已日;
簡(jiǎn)而言之垛耳,操作系統(tǒng)通過給驅(qū)動(dòng)制造麻煩來達(dá)到給上層應(yīng)用提供便利的目的。當(dāng)驅(qū)動(dòng)都按照操作系統(tǒng)給出的獨(dú)立于設(shè)備的接口而設(shè)計(jì)飘千,那么應(yīng)用程序?qū)⒖墒褂媒y(tǒng)一的系統(tǒng)調(diào)用接口來訪問各種設(shè)備堂鲜。對(duì)于類UNIX的VxWorks、Linux等操作系統(tǒng)而言护奈,當(dāng)應(yīng)用程序通過write()缔莲、read()等函數(shù)讀寫文件就可訪問各種字符設(shè)備和塊設(shè)備,而不論設(shè)備的具體類型和工作方式霉旗,這將是怎樣的便利痴奏?