![linux驅(qū)動程序的編寫_第1頁](http://file4.renrendoc.com/view/fafd4d10fdcba2f1abce802b45cef390/fafd4d10fdcba2f1abce802b45cef3901.gif)
![linux驅(qū)動程序的編寫_第2頁](http://file4.renrendoc.com/view/fafd4d10fdcba2f1abce802b45cef390/fafd4d10fdcba2f1abce802b45cef3902.gif)
![linux驅(qū)動程序的編寫_第3頁](http://file4.renrendoc.com/view/fafd4d10fdcba2f1abce802b45cef390/fafd4d10fdcba2f1abce802b45cef3903.gif)
![linux驅(qū)動程序的編寫_第4頁](http://file4.renrendoc.com/view/fafd4d10fdcba2f1abce802b45cef390/fafd4d10fdcba2f1abce802b45cef3904.gif)
![linux驅(qū)動程序的編寫_第5頁](http://file4.renrendoc.com/view/fafd4d10fdcba2f1abce802b45cef390/fafd4d10fdcba2f1abce802b45cef3905.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
linux驅(qū)動程序的編寫
底層(硬件層):需要你自己對于硬件相當(dāng)?shù)牧私?,能夠獨立繪制PCB并進(jìn)行焊接,之后調(diào)試板子,做好電路板。比如omap3530,你需要繪制至少四層PCB電路板,其中ARM核心板是最難掌握的部分,外圍電路要注意各種走線技巧等等。繪制完P(guān)CB之后就需要你的焊接功夫。將元器件焊接在PCB上。最后調(diào)試電路板,這是這一層設(shè)計中的收尾工作,也是最具有挑戰(zhàn)性的工作。調(diào)試電路需要大量的經(jīng)驗,對于初學(xué)者來說,需要很強的電路知識,對于硬件的性能以及應(yīng)用要非常了解才行。
嵌入式系統(tǒng)組成:中間層(驅(qū)動層):電路板已經(jīng)有現(xiàn)成的。你需要編程使一個死的板子,活起來,就是把程序下載進(jìn)去,能叫板子跑起來。這里需要你對于ARM芯片的結(jié)構(gòu)有很好的掌握,要會讀芯片資料(datasheet)通常都是英文的。了解其內(nèi)部資源我們就可以進(jìn)行驅(qū)動編程了。我們平時所使用單片機(jī),一般都是寫好的程序,各個管腳在什么時序下輸出么信號(1或0),來操作實現(xiàn)相應(yīng)借口的外圍設(shè)備,比如液晶屏、LED燈等。單片機(jī)也可以叫做簡單的嵌入式。原理相同。ARM也可以向單片機(jī)一樣使用,但我們更多的是要對ARM加入操作系統(tǒng)的,這才是我們最常說的嵌入式。加入操作系統(tǒng)了以后,芯片對于個個資源的調(diào)度有了更系統(tǒng)的統(tǒng)籌規(guī)劃,可以更充分的利用ARM芯片的系統(tǒng)資源,提高性能,使資源合理分配。而通常的驅(qū)動是在操作系統(tǒng)下工作的.比如基于LINUX或WINCE等等下的驅(qū)動程序。驅(qū)動程序是鏈接硬件平臺和操作系統(tǒng)的紐帶,當(dāng)然編寫驅(qū)動要同時兼顧操作系統(tǒng)特點和硬件接口的特點。做驅(qū)動的開發(fā),需要對于軟硬件都要有所了解,其中更偏重操作系統(tǒng)的理解。這部分工作也是最難做的。
嵌入式系統(tǒng)組成:上層(應(yīng)用層):應(yīng)用層,即我們所說的軟件編程了。就象我們手機(jī)里QQ和飛信一樣,我們需要根據(jù)我們手機(jī)的操作系統(tǒng)來編寫應(yīng)用程序。對于各個開發(fā)板,我們同樣需要根據(jù)它里邊的系統(tǒng)進(jìn)行應(yīng)用開發(fā)。這部分,應(yīng)該是幾乎脫離硬件了,我們只需簡單的了解硬件即可。我們只需深刻理解操作系統(tǒng)的中各個系統(tǒng)函數(shù)和接口函數(shù),即可進(jìn)行開發(fā)。需要很強的C++水平。嵌入式系統(tǒng)組成:嵌入式應(yīng)用對成本和實時性比較敏感,而對linux的應(yīng)用主要體現(xiàn)在對硬件的驅(qū)動程序的編寫和上層應(yīng)用程序的開發(fā)上.嵌入式linux驅(qū)動程序的基本結(jié)構(gòu)和標(biāo)準(zhǔn)Linux的結(jié)構(gòu)基本一致,也支持模塊化模式,所以,大部分驅(qū)動程序編成模塊化形式,而且,要求可以在不同的體系結(jié)構(gòu)上安裝。linux是可以支持模塊化模式的,但由于嵌入式應(yīng)用是針對具體的應(yīng)用,所以,一般不采用該模式,而是把驅(qū)動程序直接編譯進(jìn)內(nèi)核之中。但是這種模式是調(diào)試驅(qū)動模塊的極佳方法。linux設(shè)備驅(qū)動程序的功能
系統(tǒng)調(diào)用是操作系統(tǒng)內(nèi)核和應(yīng)用程序之間的接口,設(shè)備驅(qū)動程序是操作系統(tǒng)內(nèi)核和機(jī)器硬件之間的接口。設(shè)備驅(qū)動程序為應(yīng)用程序屏蔽了硬件的細(xì)節(jié),這樣在應(yīng)用程序看來,硬件設(shè)備只是一個設(shè)備文件,應(yīng)用程序可以像操作普通文件一樣對硬件設(shè)備進(jìn)行操作。同時,設(shè)備驅(qū)動程序是內(nèi)核的一部分,它完成以下的功能:對設(shè)備初始化和釋放;把數(shù)據(jù)從內(nèi)核傳送到硬件和從硬件讀取數(shù)據(jù);讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù)和回送應(yīng)用程序請求的數(shù)據(jù);檢測和處理設(shè)備出現(xiàn)的錯誤。在linux操作系統(tǒng)下有字符設(shè)備和塊設(shè)備,網(wǎng)絡(luò)設(shè)備三類主要的設(shè)備文件類型。linux設(shè)備驅(qū)動程序的功能
字符設(shè)備和塊設(shè)備的主要區(qū)別是:在對字符設(shè)備發(fā)出讀寫請求時,實際的硬件I/O一般就緊接著發(fā)生了;塊設(shè)備利用一塊系統(tǒng)內(nèi)存作為緩沖區(qū),當(dāng)用戶進(jìn)程對設(shè)備請求滿足用戶要求時,就返回請求的數(shù)據(jù)。塊設(shè)備是主要針對磁盤等慢速設(shè)備設(shè)計的,以免耗費過多的CPU時間來等待。linux設(shè)備驅(qū)動程序的功能
Linux字符設(shè)備驅(qū)動的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)是cdev和file_operations結(jié)構(gòu)體。1)cdev結(jié)構(gòu)體在linux2.6內(nèi)核中,使用cdev結(jié)構(gòu)體描述一個字符設(shè)備,cdev結(jié)構(gòu)體的定義如下:struct
cdev{
struct
kobject
kobj;/*內(nèi)嵌的kobject對象*/
structmodule*owner;/*所屬模塊*/
struct
file_operations*ops;/*文件操作結(jié)構(gòu)體*/
struct
list_headlist;
dev_tdev;/*設(shè)備號*/unsignedintcount;};1字符設(shè)備驅(qū)動結(jié)構(gòu)cdev結(jié)構(gòu)體的dev_t成員定義了設(shè)備號,為32位,其中12位主設(shè)備號,20位次設(shè)備號。使用下列宏可以從dev_t獲得主設(shè)備號和次設(shè)備號。*dev_t這個不是structure,是簡單變量,只用于保存一組majornumber和minornumber.Linux提供一組mactor對其進(jìn)行讀寫:MAJOR(dev_tdev);//讀取設(shè)備的majornumberMINOR(dev_tdev);//讀取設(shè)備的minornumber1字符設(shè)備驅(qū)動結(jié)構(gòu)而使用下列宏則可以通過主設(shè)備號和次設(shè)備號生成dev_t;MKDEV(int
major,intminor);//從一組指定的majornumber和minornumber創(chuàng)建一個dev_tcdev結(jié)構(gòu)體的另一個重要成員file_operations定義了字符設(shè)備提供給文件系統(tǒng)的接口函數(shù)。
Linux2.6內(nèi)核提供了一組函數(shù)用于操作cdev結(jié)構(gòu)體:voidcdev_init(struct
cdev*,struct
file_operations*);struct
cdev*cdev_alloc(void);/*動態(tài)申請一個cdev空間內(nèi)存*/voidcdev_put(struct
cdev*p);int
cdev_add(struct
cdev*,dev_t,unsigned);/*向系統(tǒng)添加、注冊一個cdev*/voidcdev_del(struct
cdev*);/*向系統(tǒng)注銷一個cdev*/1字符設(shè)備驅(qū)動結(jié)構(gòu)cdev_init()函數(shù)用于初始化cdev的成員,并建立cdev和file_operations之間的連接,其源代碼如下所示:voidcdev_init(struct
cdev*cdev,struct
file_operations*fops){memset(cdev,0,sizeof*cdev);
INIT_LIST_HEAD(&cdev->list);
kobject_init(&cdev->kobj,&ktype_cdev_default);
cdev->ops=fops;/*將傳入的文件操作結(jié)構(gòu)體指針賦值給cdev的ops*/}1字符設(shè)備驅(qū)動結(jié)構(gòu)cdev_alloc()函數(shù)用于動態(tài)申請一個cdev內(nèi)存,其源代碼清單如下:struct
cdev*cdev_alloc(void){
struct
cdev*p=kzalloc(sizeof(struct
cdev),GFP_KERNEL);
if(p){
INIT_LIST_HEAD(&p->list);
kobject_init(&p->kobj,&ktype_cdev_dynamic); } returnp;}1字符設(shè)備驅(qū)動結(jié)構(gòu)cdev_add()函數(shù)和cdev_del()函數(shù)分別向系統(tǒng)添加和刪除一個cdev,完成字符設(shè)備的注冊和注銷。對cdev_add()的調(diào)用通常發(fā)生在字符設(shè)備驅(qū)動模塊加載函數(shù)中,而對cdev_del()函數(shù)的調(diào)用通常發(fā)生在字符設(shè)備驅(qū)動模塊卸載函數(shù)中。1字符設(shè)備驅(qū)動結(jié)構(gòu)2)分配和釋放設(shè)備號在調(diào)用cdev_add()函數(shù)向系統(tǒng)注冊字符設(shè)備之前,應(yīng)首先調(diào)用register_chrdev_region()或alloc_chrdev_region()函數(shù)向系統(tǒng)申請設(shè)備號,這兩個函數(shù)的原型為:int
register_chrdev_region(dev_t
from,unsigned
count,constchar*name);int
alloc_chrdev_region(dev_t*dev,unsigned
baseminor,unsigned
count,constchar*name);1字符設(shè)備驅(qū)動結(jié)構(gòu)register_chrdev_region()函數(shù)用于已知起始設(shè)備的設(shè)備號的情況,而alloc_chrdev_regione用于設(shè)備號未知,向系統(tǒng)動態(tài)申請未被占用的設(shè)備號的情況,函數(shù)調(diào)用成功之后,會把得到的設(shè)備號放入第一個參數(shù)dev中。后者的優(yōu)點在于它會自動避開設(shè)備號重復(fù)的沖突。相反地,在調(diào)用cdev_del()函數(shù)從系統(tǒng)注銷字符設(shè)備之后,unregister_chrdev_region()應(yīng)該被調(diào)用以釋放原先申請的設(shè)備號,這個函數(shù)的原型為:voidunregister_chrdev_region(dev_t
from,unsignedcount);from:要分配設(shè)備編號范圍的起始值,經(jīng)常設(shè)置為0.count:所請求的連續(xù)設(shè)備編號的個數(shù)。Name:是和該設(shè)備范圍關(guān)聯(lián)的設(shè)備名稱,它將出現(xiàn)在/proc/devices和sysfs中。1字符設(shè)備驅(qū)動結(jié)構(gòu)3)file_operations結(jié)構(gòu)體file_operations結(jié)構(gòu)體中的成員函數(shù)是字符設(shè)備驅(qū)動程序設(shè)計的主體內(nèi)容,是這符設(shè)備驅(qū)動與內(nèi)核的接口,是用戶空間對linux進(jìn)行系統(tǒng)調(diào)用的最終落實者。這些函數(shù)實際會在程序進(jìn)行l(wèi)inux的open()、write()、read()、close()等系統(tǒng)調(diào)用時最終被調(diào)用。字符設(shè)備驅(qū)動程序中,具體實現(xiàn)這些函數(shù),通常,比如file_operation中的read這個函數(shù)指針將指向這個具體的驅(qū)動程序中的函數(shù)xxx_read().
1字符設(shè)備驅(qū)動結(jié)構(gòu)通常,一個設(shè)備驅(qū)動程序包括兩個基本的任務(wù):驅(qū)動設(shè)備的某些函數(shù)作為系統(tǒng)調(diào)用執(zhí)行;而某些函數(shù)則負(fù)責(zé)處理中斷(即中斷處理函數(shù))。而file_operations
結(jié)構(gòu)的每一個成員的名稱都對應(yīng)著一個系統(tǒng)調(diào)用。用戶程序利用系統(tǒng)調(diào)用,比如在對一個設(shè)備文件進(jìn)行諸如read操作時,這時對應(yīng)于該設(shè)備文件的驅(qū)動程序就會執(zhí)行相關(guān)的ssize_t(*read)(structfile*,char*,size_t,loff_t*);函數(shù)。在操作系統(tǒng)內(nèi)部,外部設(shè)備的存取是通過一組固定入口點進(jìn)行的,這些入口點由每個外設(shè)的驅(qū)動程序提供,由file_operations結(jié)構(gòu)向系統(tǒng)進(jìn)行說明,因此,編寫設(shè)備驅(qū)動程序的主要工作就是編寫子函數(shù),并填充file_operations的各個域。file_operations結(jié)構(gòu)在kernel/include/linux/fs.h中可以找到。1字符設(shè)備驅(qū)動結(jié)構(gòu)struct
file_operations{
structmodule*owner;/*擁有該結(jié)構(gòu)的模塊的指針,一般為THIS_MODULES*/
loff_t(*llseek)(structfile*,loff_t,int);/*用來修改文件當(dāng)前的讀寫位置*/
ssize_t(*read)(structfile*,char*,size_t,loff_t*);/*從設(shè)備中同步讀取數(shù)據(jù)*/
ssize_t(*write)(structfile*,constchar*,size_t,loff_t*);/*向設(shè)備發(fā)送數(shù)據(jù)*/ssize_t(*aio_read)(structfile*,char*,size_t,loff_t*);/*初始化一個異步的讀取操作*/
ssize_t(*aio_write)(structfile*,constchar*,size_t,loff_t*);/*初始化一個異步的寫入操作*/
int(*readdir)(structfile*,void*,filldir_t);/*僅用于讀取目錄,對于設(shè)備文件,該字符為null*/ unsignedint(*poll)(structfile*,struct
poll_table_struct*);/*輪詢函數(shù),判斷目前是否可以進(jìn)行非阻塞的讀取或?qū)懭?/
int(*ioctl)(struct
inode*,structfile*,unsignedint,unsignedlong);/*執(zhí)行設(shè)備I/O的控制命令*/
int(*mmap)(structfile*,struct
vm_area_struct*);/*用于請求將設(shè)備內(nèi)存映射到進(jìn)程地址空間*/
int(*open)(struct
inode*,structfile*);/*打開*/
int(*flush)(structfile*);
int(*release)(struct
inode*,structfile*);/*關(guān)閉*/
int(*fsync)(structfile*,struct
dentry*,int
datasync);/*刷新待處理的數(shù)據(jù)*/
int(*fasync)(int,structfile*,int);/*通知設(shè)備FASYNC標(biāo)志發(fā)生變化*/
int(*lock)(structfile*,int,struct
file_lock*);
ssize_t(*readv)(structfile*,conststruct
iovec*,unsignedlong,loff_t*);
ssize_t(*writev)(structfile*,conststruct
iovec*,unsignedlong,loff_t*);
ssize_t(*sendpage)(structfile*,structpage*,int,size_t,loff_t*,int);/*通常為NULL*/ unsignedlong(*get_unmapped_area)(structfile*,unsignedlong,unsignedlong,unsignedlong,unsignedlong);#ifdefMAGIC_ROM_PTR
int(*romptr)(structfile*,struct
vm_area_struct*);#endif/*MAGIC_ROM_PTR*/};1字符設(shè)備驅(qū)動結(jié)構(gòu)File_operations結(jié)構(gòu)中的成員全部是函數(shù)指針,所以實質(zhì)上就是函數(shù)的跳轉(zhuǎn)表。每個進(jìn)程對設(shè)備的操作,都會根據(jù)major、minor設(shè)備號,轉(zhuǎn)換成對file_op
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 攝影工作室裝修免租合同
- 二零二五年度辦公室文員工作責(zé)任與獎勵合同
- 科技園區(qū)房產(chǎn)居間合同模板
- 餐飲連鎖居間合同
- 車輛長期租賃合同協(xié)議
- 代簽合同委托書
- 企業(yè)知識產(chǎn)權(quán)保護(hù)與管理策略研究項目名稱
- 項目策劃與執(zhí)行流程指南
- 農(nóng)業(yè)災(zāi)害防治技術(shù)研究與應(yīng)用方案
- 終止合同協(xié)議書
- 元宇宙視域下非遺保護(hù)與傳播途徑探究
- 2025年買賣個人房屋合同(4篇)
- 2025代運營合同范本
- 武漢2025年湖北武漢理工大學(xué)管理人員招聘筆試歷年參考題庫附帶答案詳解
- 第十一章《功和機(jī)械能》達(dá)標(biāo)測試卷(含答案)2024-2025學(xué)年度人教版物理八年級下冊
- 辦公用品價格清單
- DB3713T 340-2024 實景三維數(shù)據(jù)接口及服務(wù)發(fā)布技術(shù)規(guī)范
- 八年級生物開學(xué)摸底考(長沙專用)(考試版)
- 傳染病監(jiān)測預(yù)警與指揮信息平臺升級建設(shè)方案
- (工作規(guī)范)公路預(yù)防性養(yǎng)護(hù)工作手冊
評論
0/150
提交評論