![嵌入式課設(shè)報(bào)告_第1頁](http://file4.renrendoc.com/view11/M01/06/34/wKhkGWWlyjOAJgWlAAD2fFOJ4e8498.jpg)
![嵌入式課設(shè)報(bào)告_第2頁](http://file4.renrendoc.com/view11/M01/06/34/wKhkGWWlyjOAJgWlAAD2fFOJ4e84982.jpg)
![嵌入式課設(shè)報(bào)告_第3頁](http://file4.renrendoc.com/view11/M01/06/34/wKhkGWWlyjOAJgWlAAD2fFOJ4e84983.jpg)
![嵌入式課設(shè)報(bào)告_第4頁](http://file4.renrendoc.com/view11/M01/06/34/wKhkGWWlyjOAJgWlAAD2fFOJ4e84984.jpg)
![嵌入式課設(shè)報(bào)告_第5頁](http://file4.renrendoc.com/view11/M01/06/34/wKhkGWWlyjOAJgWlAAD2fFOJ4e84985.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
課程設(shè)計(jì)報(bào)告課程名稱嵌入式信息系統(tǒng)題目嵌入式Linux設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)指導(dǎo)教師周金和王勇設(shè)計(jì)起止日期2023-1-20至2023-1-28系別信息與通信工程系專業(yè)電子信息工程學(xué)生姓名班級(jí)/學(xué)號(hào)成績目錄TOC\o"1-2"\h\z\u一、驅(qū)動(dòng)根本概念4二、重要的數(shù)據(jù)結(jié)構(gòu)5三、驅(qū)動(dòng)注冊訪問過程7四、編譯運(yùn)行DEMO驅(qū)動(dòng)8六、DEMO驅(qū)動(dòng)文件和應(yīng)用文件的測試19七、LED驅(qū)動(dòng)與測試20八、課設(shè)總結(jié)21參考文獻(xiàn):22一、驅(qū)動(dòng)根本概念Linux的設(shè)備驅(qū)動(dòng)程序是硬件設(shè)備與應(yīng)用程序之間的一個(gè)中間軟件層,它使得某個(gè)特定硬件能夠響應(yīng)一個(gè)定義良好的內(nèi)部編程接口,同時(shí)完全隱蔽了設(shè)備的工作細(xì)節(jié),用戶通過一組與具體設(shè)備無關(guān)的標(biāo)準(zhǔn)化的調(diào)用來完成相應(yīng)的操作。驅(qū)動(dòng)程序的任務(wù)就是把這些標(biāo)準(zhǔn)化的系統(tǒng)調(diào)用映射到具體設(shè)備對于實(shí)際硬件的特定操作上,驅(qū)動(dòng)程序是內(nèi)核的一局部,可以使用中斷、DMA等操作,驅(qū)動(dòng)程序在用戶態(tài)和內(nèi)核態(tài)之間傳遞數(shù)據(jù)。Linux設(shè)備驅(qū)動(dòng)程序可以分為三大類:字符設(shè)備、塊設(shè)備和網(wǎng)絡(luò)接口設(shè)備。?字符設(shè)備所有能夠象字節(jié)流一樣訪問的設(shè)備都通過字符設(shè)備來實(shí)現(xiàn),它們被映射為文件系統(tǒng)中的節(jié)點(diǎn),通常在/dev/目錄下面,一般要包含openreadwriteclose等系統(tǒng)調(diào)用的實(shí)現(xiàn)?塊設(shè)備通常是指諸如磁盤、內(nèi)存、Hash等可以容納文件系統(tǒng)的存儲(chǔ)設(shè)備。塊設(shè)備也是通過文件系統(tǒng)來訪問,與字符設(shè)備的區(qū)別是:內(nèi)核管理數(shù)據(jù)的方式不同。它允許象字符設(shè)備一樣以字節(jié)流的方式來訪問,也可一次傳遞任意多的字節(jié)。?網(wǎng)絡(luò)接口設(shè)備通常它指的是硬件設(shè)備,但有時(shí)也可能是一個(gè)軟件設(shè)備(如回環(huán)接口loopback),它們由內(nèi)核中網(wǎng)絡(luò)子系統(tǒng)驅(qū)動(dòng),負(fù)責(zé)發(fā)送和接收數(shù)據(jù)包。它們的數(shù)據(jù)傳送往往不是面向流的,因此很難將它們映射到一個(gè)文件系統(tǒng)的節(jié)點(diǎn)上。設(shè)備驅(qū)動(dòng)應(yīng)用主設(shè)備號(hào)和次設(shè)備號(hào)來區(qū)分不同的設(shè)備。主設(shè)備號(hào)和次設(shè)備號(hào)能夠唯一地標(biāo)識(shí)一個(gè)設(shè)備,主設(shè)備號(hào)范圍0-256,設(shè)備號(hào)相同的設(shè)備使用相同的驅(qū)動(dòng)程序,次設(shè)備號(hào)用于區(qū)分具體設(shè)備的實(shí)例,可以動(dòng)態(tài)獲取主設(shè)備號(hào)。Linux下對設(shè)備號(hào)的分配請參考Documentation/devices.txt。Linux使用設(shè)備文件來統(tǒng)一對設(shè)備的訪問接口,將設(shè)備文件放在/dev/目錄下。設(shè)備的命名一般為設(shè)備文件名+數(shù)字或者字母表示的子類,例如/dev/hda1,/dev/hda2等。Linux2.4引入了設(shè)備文件系統(tǒng)〔devfs)的概念,所有的設(shè)備文件作為一個(gè)可以掛裝的文件系統(tǒng),這樣就可以被文件系統(tǒng)統(tǒng)一管理,從而設(shè)備文件就可以掛裝到任何需要的地方。一般將主設(shè)備建立一個(gè)目錄,再將具體的子設(shè)備文件建立在此目錄下。例如,/dev/mtdblock0。Linux2.6以后應(yīng)用udev文件系統(tǒng)來動(dòng)態(tài)管理設(shè)備文件,udev只為那些連接到Linux操作系統(tǒng)的設(shè)備產(chǎn)生設(shè)備文件。并且udev能通過定義一個(gè)udev規(guī)那么〔rule)來產(chǎn)生匹配設(shè)備屬性的設(shè)備文件,這些設(shè)備屬性可以是內(nèi)核設(shè)備名稱、總線路徑、廠商名稱、型號(hào)、序列號(hào)或者磁盤大小等等。動(dòng)態(tài)自動(dòng)管理設(shè)備信息:當(dāng)有設(shè)備添加內(nèi)核時(shí),udev的守護(hù)進(jìn)程偵聽到來自內(nèi)核的uevent的事件,用來添加或者刪除/dev下的設(shè)備文件,所以udev可以只為已經(jīng)連接的設(shè)備產(chǎn)生設(shè)備文件,而不會(huì)像2.4內(nèi)核一樣在/dev下產(chǎn)生大量設(shè)備文件。另外可以使用這個(gè)功能,當(dāng)有設(shè)備參加時(shí)運(yùn)行外部的程序,比方鼠標(biāo)參加時(shí)自動(dòng)禁用觸摸板之類。使用自定義命名和管理設(shè)備:使用Udev規(guī)那么文件,udev在/dev/里為所有的設(shè)備定義了內(nèi)核設(shè)備名稱,比方/dev/sda、/dev/hda、/dev/fd等等。由于udev是在用戶空間〔userspace)運(yùn)行,Linux用戶可以接下來對這些信息進(jìn)行操作,比方可以通過自定義的規(guī)那么文件,生成人性的設(shè)備標(biāo)識(shí),比方/dev/my—disk、/dev/nameusb等,還能對設(shè)置進(jìn)行參數(shù)成員用戶組權(quán)限之類的修改。二、重要的數(shù)據(jù)結(jié)構(gòu)圖1、驅(qū)動(dòng)程序的重要數(shù)據(jù)結(jié)構(gòu):structfile和structfile_operationsstructfile數(shù)據(jù)結(jié)構(gòu)定義位于include/fs.h。其中structfile結(jié)構(gòu)與驅(qū)動(dòng)相關(guān)的成員:mode_tf_mode標(biāo)識(shí)文件的讀寫權(quán)限;loff_tf_pos當(dāng)前讀寫位置;unsignedint_f_flag文件標(biāo)志,主要進(jìn)行阻塞/非阻塞型操作時(shí)檢查;structfile_operation*f_op文件操作的結(jié)構(gòu)指針;void*private_data驅(qū)動(dòng)程序一般將它指向已經(jīng)分配的數(shù)據(jù);structdentry*f_dentry文件對應(yīng)的目錄項(xiàng)結(jié)構(gòu);設(shè)備驅(qū)動(dòng)程序接口(structfile_operations),標(biāo)記化方法:staticstructfile_operationsdemo_fops={owner:THIS_MODULE,write:demo_write,read:demo_read,ioctl:demo_ioctl,open:demo_open,release:demo_release,};通常所說的設(shè)備驅(qū)動(dòng)程序接口是指structfile_operations{},它的定義位于include/linux/fs.h中。在嵌入式系統(tǒng)的開發(fā)中,通常只要實(shí)現(xiàn)如下幾個(gè)接口函數(shù)就能完成系統(tǒng)所需要的功能:init加載驅(qū)動(dòng)程序時(shí),內(nèi)核自動(dòng)調(diào)用read從設(shè)備中讀取數(shù)據(jù)write向字符設(shè)備中寫數(shù)據(jù)ioctl控制設(shè)備,實(shí)現(xiàn)除讀寫操作以外的其他控制命令open翻開設(shè)備并進(jìn)行初始化release關(guān)閉設(shè)備并釋放資源exit卸載驅(qū)動(dòng)程序時(shí),內(nèi)核自動(dòng)調(diào)用open提供應(yīng)驅(qū)動(dòng)程序初始化設(shè)備的能力,為后續(xù)的操作做準(zhǔn)備此外一般會(huì)遞增使用計(jì)數(shù),防止文件關(guān)閉前模塊被卸載通常情況下,open完成如下工作:遞增使用計(jì)數(shù)檢查特定設(shè)備錯(cuò)誤如果設(shè)備是首次翻開,那么對其進(jìn)行初始化識(shí)別次設(shè)備號(hào),如有必要,那么修改f_op指針分配并填寫filp->private_data中的數(shù)據(jù)release與open正好相反釋放由open分配的filp->private_data中的數(shù)據(jù)在最后一次關(guān)閉操作時(shí)關(guān)閉設(shè)備使用計(jì)數(shù)減一read和writeread將數(shù)據(jù)從內(nèi)核拷貝到應(yīng)用程序空間,write那么將數(shù)據(jù)從應(yīng)用程序空間拷貝到內(nèi)核。由于用戶空間和內(nèi)核空間的內(nèi)存映射方式不同,所以在內(nèi)核和用戶空間傳輸數(shù)據(jù)的時(shí)候需要使用如下的函數(shù):unsignedlongcopy_to_user(void*to,constvoid*from,unsignedlongcount);unsignedlongcopy_from_user(void*to,constvoid*from,unsignedlongcount);在阻塞型IO中,read和write調(diào)用可能會(huì)出現(xiàn)阻塞。read調(diào)用當(dāng)前無數(shù)據(jù)可讀,而又沒有數(shù)據(jù)馬上可讀,這時(shí)會(huì)睡眠并且等待,write調(diào)用也會(huì)出現(xiàn)這樣的情況。等待隊(duì)列機(jī)制-wait_queue_head_t;(定義在<linux/wait.h>中)。如果聲明了等待隊(duì)列并完成初始化,進(jìn)程就可以睡眠,可以調(diào)用sleep_on的不同變體來完成睡眠(函數(shù)聲明位于<linux/sched.h>中)。大多數(shù)情況下應(yīng)使用“可中斷〞的函數(shù),如interruptible_sleep_on。睡眠進(jìn)程被喚醒并不一定代表有數(shù)據(jù),也有可能是被其他的信號(hào)喚醒,所以醒來后需要測試condition。三、驅(qū)動(dòng)注冊訪問過程驅(qū)動(dòng)程序注冊過程〔動(dòng)態(tài)分配主設(shè)備號(hào)〕:(1)insmodmodule_name;加載驅(qū)動(dòng)程序,運(yùn)行init函數(shù)(register_chrdev(dev_Major,“module_name〞,*fs));(2)查看/proc/devices;(3)mknod/dev/module_namec/b主設(shè)備號(hào)次設(shè)備號(hào);(4)rmmodmodule_name;卸載驅(qū)動(dòng),運(yùn)行exit函數(shù)〔unregister_chrdev(dev_Major,“module_name〞,*fs)〕用戶程序調(diào)用過程:(1)Open(“/dev/module_name〞,mode);O_RDWR(2)Ioctl()(3)Write()(4)Read()(5)Close()中斷是現(xiàn)代微處理器的一個(gè)重要功能,Linux驅(qū)動(dòng)程序中的中斷處理函數(shù):externintrequest_irq(unsignedintirq,void(*handler)(int,void*,structpt_regs*),unsignedlongflag,constchar*dev_name,void*dev_id);//請求為中斷號(hào)irq分配中斷處理函數(shù)externvoidfree_irq(unsignedint,void*);//釋放中斷〔注意:不能向用戶空間發(fā)送或者接收數(shù)據(jù);不能執(zhí)行有睡眠操作的函數(shù);不能調(diào)用調(diào)度函數(shù);謹(jǐn)慎使用可重入的全局變量;自旋鎖的使用〕字符設(shè)備驅(qū)動(dòng)程序模塊通過函數(shù)intregister_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops)完成向內(nèi)核的注冊,其中major是主設(shè)備號(hào),name是設(shè)備名,fops是針對該設(shè)備的驅(qū)動(dòng)程序的接口。在系統(tǒng)中為驅(qū)動(dòng)程序模塊建立一個(gè)設(shè)備節(jié)點(diǎn):HOST#mknod/dev/democ2240〔其中/dev/demo標(biāo)識(shí)設(shè)備名為demo,“c〞說明是字符設(shè)備,224是指定的主設(shè)備號(hào),0是次設(shè)備號(hào),因?yàn)殚_發(fā)板中使用udev管理設(shè)備文件,此步可以省略〕四、編譯運(yùn)行DEMO驅(qū)動(dòng)首先,我們從中的2023嵌入式課設(shè)文件夾中下載demo的驅(qū)動(dòng)文件:demo.c和demo.h然后,在ubuntu主文件下建立driver文件夾,進(jìn)入driver文件夾,后再建立一個(gè)drv文件夾,將剛剛下載的demo.c和demo.h放入其中,然后,新建一個(gè)空白文檔,重命名為Makefile。翻開Makefile文檔后,根據(jù)課設(shè)指導(dǎo)書,寫入Makefile的內(nèi)容。接著,找到自己ubuntu下的kernel文件夾路徑,復(fù)制路徑,替換在Makefile文件中的KERNELDIR等號(hào)后的路徑目錄,再繼續(xù)在其中將CROSS_COMPILE=arm-none-linux-gnueabi-改為CROSS_COMPILE=arm-linux-gnueabihf-(因?yàn)楹笃谠陂_發(fā)版加載內(nèi)核時(shí),沒有arm-none-linux-gnueabi-,具體視情況而定)最后,在完成上述步驟后,翻開終端,利用cd命令進(jìn)入drv目錄,然后輸入命令make就完成了DEMO驅(qū)動(dòng)的編譯,得到demo.ko文件demo.c和demo.h的代碼、Makefile文檔內(nèi)容和make結(jié)果如下列圖所示:demo.h:#ifndef_DEMO_H_
#define_DEMO_H_#include<linux/ioctl.h>/*neededforthe_IOWetcstuffusedlater*//*********************************************************Macrostohelpdebugging********************************************************/#undefPDEBUG/*undefit,justincase*/
#ifdefDEMO_DEBUG
#ifdef__KERNEL__
#definePDEBUG(fmt,args...)printk(KERN_DEBUG"DEMO:"fmt,##args)
#else//usrspace
#definePDEBUG(fmt,args...)fprintf(stderr,fmt,##args)
#endif
#else#definePDEBUG(fmt,args...)/*notdebugging:nothing*/
#endif#undefPDEBUGG#definePDEBUGG(fmt,args...)/*nothing:it'saplaceholder*///設(shè)備號(hào)#defineDEMO_MAJOR224#defineDEMO_MINOR0#defineCOMMAND11#defineCOMMAND22//自己定義的設(shè)備結(jié)構(gòu)structDEMO_dev{structcdevcdev;/*Chardevicestructure*/};//函數(shù)申明,實(shí)現(xiàn)根本的read;write;llseek和ioctl函數(shù)ssize_tDEMO_read(structfile*filp,char__user*buf,size_tcount,loff_t*f_pos);ssize_tDEMO_write(structfile*filp,constchar__user*buf,size_tcount,loff_t*f_pos);loff_tDEMO_llseek(structfile*filp,loff_toff,intwhence);intDEMO_ioctl(structfile*filp,unsignedintcmd,unsignedlongarg);#endif/*_DEMO_H_*/demo.c:/**ThisfileissubjecttothetermsandconditionsoftheGNUGeneralPublic*License.Seethefile"COPYING"inthemaindirectoryofthisarchive*formoredetails.*Copyright(C)2007,2023fengGuojin(fgjnew@163)*/#include<linux/module.h>#include<linux/kernel.h>#include<linux/fs.h>#include<linux/errno.h>#include<linux/types.h>#include<linux/fcntl.h>#include<linux/cdev.h>#include<linux/version.h>#include<linux/vmalloc.h>#include<linux/ctype.h>#include<linux/pagemap.h>#include<linux/device.h>#include"demo.h"#include<linux/slab.h>MODULE_AUTHOR("bistu");MODULE_LICENSE("GPL");staticstructDEMO_dev*DEMO_devices; //申明自己定義的設(shè)備結(jié)構(gòu)的指針staticunsignedchardemo_inc=0; //計(jì)數(shù)記錄此設(shè)備被翻開的次數(shù)staticu8demoBuffer[256]; //u8是無符號(hào)8位的數(shù)據(jù)類型staticstructclass*demo_class;intDEMO_open(structinode*inode,structfile*filp){structDEMO_dev*dev; //只允許翻開設(shè)備一次if(demo_inc>0)return-ERESTARTSYS;demo_inc++;dev=container_of(inode->i_cdev,structDEMO_dev,cdev);filp->private_data=dev;return0;}intDEMO_release(structinode*inode,structfile*filp){demo_inc--;return0;}ssize_tDEMO_read(structfile*filp,char__user*buf,size_tcount,loff_t*f_pos){intresult;loff_tpos=*f_pos;/*文件的讀寫位置*/if(pos>=256){result=0;gotoout;}if(count>(256-pos)){count=256-pos;}pos+=count;if(copy_to_user(buf,demoBuffer+*f_pos,count)){count=-EFAULT;/*把數(shù)據(jù)寫到應(yīng)用程序空間*/gotoout;}*f_pos=pos;/*改變文件的讀寫位置*/out:returncount;}ssize_tDEMO_write(structfile*filp,constchar__user*buf,size_tcount,loff_t*f_pos){ssize_tretval=-ENOMEM;/*valueusedin"gotoout"statements*/loff_tpos=*f_pos;if(pos>=256){gotoout;}//如果要寫入的輸入大于剩下的內(nèi)存空間就只寫入剩下的空間數(shù)量以防溢出if(count>(256-pos)){count=256-pos;}pos+=count;//copy_from_user原文說將數(shù)據(jù)復(fù)制到用戶空間,我覺得應(yīng)該是將數(shù)據(jù)復(fù)制到內(nèi)核空間,應(yīng)該是作者筆誤,沒什么大不了的if(copy_from_user(demoBuffer+*f_pos,buf,count)){retval=-EFAULT;gotoout;}*f_pos=pos;returncount;out:returnretval;}/*ioctl的作用ioctl是用來控制設(shè)備的,unsignedintcmd就是發(fā)給設(shè)備的命令*/intDEMO_ioctl(structfile*filp,unsignedintcmd,unsignedlongarg){if(cmd==COMMAND1){printk("ioctlcommand1successfully\n");return0;}if(cmd==COMMAND2){printk("ioctlcommand2successfully\n");return0;}printk("ioctlerror\n");
return-EFAULT;}//llseek實(shí)現(xiàn)隨即存取,loff_t應(yīng)該是一個(gè)無符號(hào)整型記錄文件指針偏移量的這段代碼參考用戶態(tài)的seek()就不難理解loff_tDEMO_llseek(structfile*filp,loff_toff,intwhence){loff_tpos;pos=filp->f_pos;switch(whence){case0:pos=off;break;case1:pos+=off;break;case2:default:return-EINVAL;}if((pos>256)||(pos<0)){return-EINVAL;}returnfilp->f_pos=pos;}//file_operations這個(gè)結(jié)構(gòu)體真是相當(dāng)重要,需要搞清楚它的作用structfile_operationsDEMO_fops={
.owner=THIS_MODULE,.llseek=DEMO_llseek,.read=DEMO_read,.write=DEMO_write,.unlocked_ioctl=DEMO_ioctl,.open=DEMO_open,.release=DEMO_release,};/*******************************************************MODULEROUTINE*******************************************************/voidDEMO_cleanup_module(void){//在下面的入口函數(shù)有講MKDEVdev_tdevno=MKDEV(DEMO_MAJOR,DEMO_MINOR);if(DEMO_devices){cdev_del(&DEMO_devices->cdev);kfree(DEMO_devices);}//調(diào)用unregister_chrdev_region()函數(shù)釋放分配的一系列設(shè)備號(hào)unregister_chrdev_region(devno,1);}intDEMO_init_module(void){intresult=0;//在內(nèi)核中,dev_t類型〔在<linux/types.h>中定義〕用來保存設(shè)備編號(hào)——包括主設(shè)備號(hào)和次設(shè)備號(hào)dev_tdev=0;/*內(nèi)核中定義了三個(gè)宏來處理主、次設(shè)備號(hào):MAJOR和MINOR宏可以從16位數(shù)中提取出主、次設(shè)備號(hào),而MKDEV宏可以把主、此號(hào)合并為一個(gè)16位數(shù)。高8位用于主設(shè)備號(hào),低8位用于次設(shè)備號(hào)。*/dev=MKDEV(DEMO_MAJOR,DEMO_MINOR);/*獲取一個(gè)或多個(gè)設(shè)備編號(hào)來使用如果分配成功進(jìn)行,register_chrdev_region的返回值是0.出錯(cuò)的情況下,返回一個(gè)負(fù)的錯(cuò)誤碼,你不能存取請求的區(qū)域.*/result=register_chrdev_region(dev,1,"DEMO");if(result<0){printk(KERN_WARNING"DEMO:can'tgetmajor%d\n",DEMO_MAJOR);returnresult;}//為自定義的設(shè)備結(jié)構(gòu)申請空間DEMO_devices=kmalloc(sizeof(structDEMO_dev),GFP_KERNEL);if(!DEMO_devices){result=-ENOMEM;gotofail;}//為新申請的空間清零memset(DEMO_devices,0,sizeof(structDEMO_dev));//初始化一個(gè)字符驅(qū)動(dòng)cdev_init(&DEMO_devices->cdev,&DEMO_fops);DEMO_devices->cdev.owner=THIS_MODULE;DEMO_devices->cdev.ops=&DEMO_fops;//在內(nèi)核中添加字符驅(qū)動(dòng)result=cdev_add(&DEMO_devices->cdev,dev,1);if(result){printk(KERN_NOTICE"Error%daddingDEMO\n",result);gotofail;}//注冊udevclass接口demo_class=class_create(THIS_MODULE,"demo");if(IS_ERR(demo_class)){ printk(KERN_ERR"Errorcreatingdemoclass.\n"); cdev_del(&DEMO_devices->cdev); result=PTR_ERR(demo_class); gotofail;}device_create(demo_class,NULL,MKDEV(DEMO_MAJOR,0),NULL,"demo");return0;fail://失敗了調(diào)用出口函數(shù)DEMO_cleanup_module();returnresult;}//這兩個(gè)是內(nèi)核驅(qū)動(dòng)必備的指明程序入口和出口module_init(DEMO_init_module);module_exit(DEMO_cleanup_module);Makefile:#Tobuildmodulesoutsideofthekerneltree,werun"make"#inthekernelsourcetree;theMakefilethesethenincludesthis#Makefileonceagain.#Thisconditionalselectswhetherwearebeingincludedfromthe#kernelMakefileornot.AR=arARCH=armCROSS_COMPILE=arm-linux-gnueabihf-CC=$(CROSS_COMPILE)gccSTRIP=$(CROSS_COMPILE)stripifeq($(KERNELRELEASE),)#Assumethesourcetreeiswheretherunningkernelwasbuilt#YoushouldsetKERNELDIRintheenvironmentifit'selsewhereKERNELDIR=/home/bistu/WorkSpace/Software/Ubuntu1204_20230605/source/ubuntu-precise-kernel-chipsee-20230605#Thecurrentdirectoryispassedtosub-makesasargument PWD:=$(shellpwd)all:modulesmodules: $(MAKE)-C$(KERNELDIR)M=$(PWD)modulesmodules_install: $(MAKE)-C$(KERNELDIR)M=$(PWD)modules_installclean: rm-rf*.o*~core.depend.*d*.ko*.mod.c.tmp_versions*.order*.symvers.PHONY:modulesmodules_installcleanelse#calledfromkernelbuildsystem:justdeclarewhatourmodulesareobj-m:=demo.oendif編譯結(jié)果:圖2.demo驅(qū)動(dòng)文件編譯圖2說明demo驅(qū)動(dòng)編譯無錯(cuò)誤,形成demo.ko。五、編譯運(yùn)行DEMO應(yīng)用程序在ubuntu終端輸入:cd..退回到driver目錄下,同時(shí)翻開driver文件夾,在其下新建文件夾App,翻開文件夾,把2023嵌入式課設(shè)文件夾中的test_demo.c文件復(fù)制到其中,然后,根據(jù)課設(shè)指導(dǎo)書,建立一個(gè)空白文檔,重命名為Makefile,翻開后,復(fù)制輸入相關(guān)命令后保存,接著,再建立一個(gè)空白文檔,重命名為Rules.make,翻開后,繼續(xù)復(fù)制輸入相關(guān)命令后保存。接著,在App文件夾中建立bin文件夾。最后,在終端輸入命令:make,沒提示錯(cuò)誤,說明DEMO應(yīng)用程序編譯成功,會(huì)在App的bin文件夾下生成test_demo可執(zhí)行程序。test_demo.c等文件和編譯結(jié)果如下列圖所示test_demo.c:/**ThisfileissubjecttothetermsandconditionsoftheGNUGeneralPublic*License.Seethefile"COPYING"inthemaindirectoryofthisarchive*formoredetails.*Copyright(C)1201,2023*/#include<sys/types.h>#include<unistd.h>#include<fcntl.h>#include<linux/rtc.h>#include<linux/ioctl.h>#include<stdio.h>#include<stdlib.h>#defineCOMMAND11#defineCOMMAND22main(){ intfd; inti; chardata[256]; intretval; fd=open("/dev/demo",O_RDWR); if(fd==-1) { perror("erroropen\n"); exit(-1); } printf("open/dev/smbussuccessfully\n"); retval=ioctl(fd,COMMAND1,0); if(retval==-1) { perror("ioctlerror\n"); exit(-1); } printf("sendcommand1successfully\n"); retval=write(fd,"demo",3); if(retval==-1) { perror("writeerror\n"); exit(-1); } retval=lseek(fd,0,0); if(retval==-1) { perror("lseekerror\n"); exit(-1); } retval=read(fd,data,3); if(retval==-1) { perror("readerror\n"); exit(-1); } printf("readsuccessfully:%s\n",data); close(fd);}Makefile:ROOTDIR=.include$(ROOTDIR)/Rules.makeCFLAGS=-I$(INCLUDE_DIR)-I$(LIB_INC)-Wall#LFLAGS=-L$(LIB_DIR)objects:=$(patsubst%.c,%.o,$(wildcard*.c))executables:=$(patsubst%.c,%,$(wildcard*.c))#LIBS=-lasound-lpthreadall:$(.DELETE_ON_ERROR)$(objects)$(objects):%.o:%.c$(CROSS_COMPILE)gcc-c$(CFLAGS)$<-o$@$(CROSS_COMPILE)gcc$(CFLAGS)$<-o$(subst.o,,$(EXE_DIR)/$@)$(LFLAGS)$(LIBS)clean:rm-f*.orm-f$(EXE_DIR)/sa*distclean:cleanRules.make:#ThisisthepathtotheLinuxKernelDirectory.Changethispath#totheonewhereLinuxkerneliskept.KERNEL_DIR=#ThisisrootdirectorywhereSourceisavailable.Changethispath#totheonewheresourcefilesarekeptINSTALL_DIR=./#thisisthepathtotheexecutablewherealltheexecutablesarekeptEXE_DIR=./bin#ThisisthepathtothedirectorycontainingrequiredlibrariesLIB_DIR=#ThisispathtotheIncludefilesofLibraryLIB_INC=#Thisisthepaththeincludefolderofthekerneldirectory.Theinclude#foldershouldcontainallthenecessaryheaderfilesINCLUDE_DIR=$(KERNEL_DIR)/include-I$(KERNEL_DIR)/arch/arm/plat-omap/include/#ThisistheprefixappliedtothegccwhencompilingapplicationsandlibraryCROSS_COMPILE=arm-linux-gnueabihf-編譯結(jié)果:圖3DEMO應(yīng)用程序編譯圖4生成test_demo可執(zhí)行文件圖3和圖4說明編譯沒錯(cuò)誤,生成可執(zhí)行文件test_demo六、DEMO驅(qū)動(dòng)文件和應(yīng)用文件的測試首先將上述的demo.ko和可執(zhí)行文件demo.test復(fù)制到開發(fā)板的SD卡
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 現(xiàn)代學(xué)校后勤管理與服務(wù)創(chuàng)新
- 校園環(huán)境對幼兒自信心與自尊心的影響
- 2025年度家具行業(yè)專利技術(shù)居間轉(zhuǎn)讓合同
- 生態(tài)建筑設(shè)計(jì)在商業(yè)地產(chǎn)的前景展望
- 深入探討美顏相機(jī)的技術(shù)創(chuàng)新與應(yīng)用
- 2025年度電子信息產(chǎn)品檢測與加工技術(shù)服務(wù)合同
- 現(xiàn)代辦公環(huán)境的健康與舒適性研究
- 電商平臺(tái)的跨境服務(wù)策略與文化差異應(yīng)對
- 2025年度婚介行業(yè)獨(dú)家代理協(xié)議書模板
- 用戶體驗(yàn)在產(chǎn)品設(shè)計(jì)結(jié)構(gòu)中的重要性
- 2024年度體育賽事贊助合同:運(yùn)動(dòng)員代言與贊助權(quán)益2篇
- 智研咨詢發(fā)布:2024年中國新疫苗行業(yè)市場現(xiàn)狀、發(fā)展概況、未來前景分析報(bào)告
- 2025屆西藏林芝一中高三第二次診斷性檢測英語試卷含解析
- 藥企銷售總經(jīng)理競聘
- 開封市第一屆職業(yè)技能大賽健康照護(hù)項(xiàng)目技術(shù)文件(國賽)
- 公路電子收費(fèi)系統(tǒng)安裝合同范本
- 醫(yī)院培訓(xùn)課件:《傷口評估與測量》
- 2021年全國高考物理真題試卷及解析(全國已卷)
- 期末試卷(試題)-2024-2025學(xué)年四年級(jí)上冊數(shù)學(xué)滬教版
- 《第一單元口語交際:即興發(fā)言》教案-2023-2024學(xué)年六年級(jí)下冊語文統(tǒng)編版
- 綜合實(shí)踐項(xiàng)目 制作水族箱飼養(yǎng)淡水魚 教學(xué)設(shè)計(jì)-2024-2025學(xué)年魯科版生物六年級(jí)上冊
評論
0/150
提交評論