linux字符設(shè)備驅(qū)動(dòng)專業(yè)課程設(shè)計(jì)方案報(bào)告_第1頁
linux字符設(shè)備驅(qū)動(dòng)專業(yè)課程設(shè)計(jì)方案報(bào)告_第2頁
linux字符設(shè)備驅(qū)動(dòng)專業(yè)課程設(shè)計(jì)方案報(bào)告_第3頁
linux字符設(shè)備驅(qū)動(dòng)專業(yè)課程設(shè)計(jì)方案報(bào)告_第4頁
linux字符設(shè)備驅(qū)動(dòng)專業(yè)課程設(shè)計(jì)方案報(bào)告_第5頁
已閱讀5頁,還剩11頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

一、課程設(shè)計(jì)目標(biāo)Linux系統(tǒng)開源性使其在嵌入式系統(tǒng)開發(fā)中得到了越來越廣泛應(yīng)用,但其本身并沒有對(duì)種類繁多硬件設(shè)備全部提供現(xiàn)成驅(qū)動(dòng)程序,尤其是因?yàn)楣こ虘?yīng)用中靈活性,其驅(qū)動(dòng)程序更是難以統(tǒng)一,這時(shí)就需開發(fā)一套適合于自己產(chǎn)品設(shè)備驅(qū)動(dòng)。對(duì)用戶而言,設(shè)備驅(qū)動(dòng)程序隱藏了設(shè)備具體細(xì)節(jié),對(duì)多種不一樣設(shè)備提供了一致接口,通常來說是把設(shè)備映射為一個(gè)特殊設(shè)備文件,用戶程序能夠像對(duì)其它文件一樣對(duì)此設(shè)備文件進(jìn)行操作。經(jīng)過這次課程設(shè)計(jì)能夠了解linux模塊機(jī)制,知道怎樣加載模塊和卸載模塊,深入熟悉模塊相關(guān)操作。加深對(duì)驅(qū)動(dòng)程序定義和設(shè)計(jì)了解,了解linux驅(qū)動(dòng)編寫過程,提升自己動(dòng)手能力。二、課程設(shè)計(jì)內(nèi)容和要求字符設(shè)備驅(qū)動(dòng)程序1、設(shè)計(jì)目標(biāo):掌握設(shè)備驅(qū)動(dòng)程序編寫、編譯和裝載、卸載方法,了解設(shè)備文件創(chuàng)建,并知道怎樣編寫測試程序測試自己驅(qū)動(dòng)程序是否能夠正常工作2、設(shè)計(jì)要求:1)編寫一個(gè)簡單字符設(shè)備驅(qū)動(dòng)程序,該字符設(shè)備包含打開、讀、寫、I\O控制和釋放五個(gè)基礎(chǔ)操作。2)編寫一個(gè)測試程序,測試字符設(shè)備驅(qū)動(dòng)程序正確性。3)要求在試驗(yàn)匯報(bào)中列出Linux內(nèi)核版本和內(nèi)核模塊加載過程。三、系統(tǒng)分析和設(shè)計(jì)1、系統(tǒng)分析系統(tǒng)調(diào)用是操作系統(tǒng)內(nèi)核和應(yīng)用程序之間接口,設(shè)備驅(qū)動(dòng)程序是操作系統(tǒng)內(nèi)核和機(jī)器硬件之間接口。設(shè)備驅(qū)動(dòng)程序?yàn)閼?yīng)用程序屏蔽了硬件細(xì)節(jié),這么在應(yīng)用程序看來,硬件設(shè)備只是一個(gè)設(shè)備文件,應(yīng)用程序能夠象操作一般文件一樣對(duì)硬件設(shè)備進(jìn)行操作。設(shè)備驅(qū)動(dòng)程序是內(nèi)核一部分,它完成以下功效:1、對(duì)設(shè)備初始化和釋放;2、把數(shù)據(jù)從內(nèi)核傳送到硬件和從硬件讀取數(shù)據(jù);3、讀取應(yīng)用程序傳送給設(shè)備文件數(shù)據(jù)和回送應(yīng)用程序請(qǐng)求數(shù)據(jù);4、檢測和處理設(shè)備出現(xiàn)錯(cuò)誤。字符設(shè)備提供給應(yīng)用程序是一個(gè)流控制接口,關(guān)鍵包含open、close(或release)、read、write、ioctl、poll和mmap等。在系統(tǒng)中添加一個(gè)字符設(shè)備驅(qū)動(dòng)程序,實(shí)際上就是給上述操作添加對(duì)應(yīng)代碼。對(duì)于字符設(shè)備和塊設(shè)備,Linux內(nèi)查對(duì)這些操作進(jìn)行了統(tǒng)一抽象,把它們定義在結(jié)構(gòu)體file_operations中。2、系統(tǒng)設(shè)計(jì):2.1、模塊設(shè)計(jì):打開設(shè)備讀操作寫操作I/O控制釋放設(shè)備字符設(shè)備驅(qū)動(dòng)2.2數(shù)據(jù)結(jié)構(gòu)說明字符設(shè)備驅(qū)動(dòng)關(guān)鍵應(yīng)用了三種數(shù)據(jù)結(jié)構(gòu):=1\*GB3①file_operations結(jié)構(gòu),這是設(shè)備驅(qū)動(dòng)程序所提供一組用一個(gè)結(jié)構(gòu)向系統(tǒng)進(jìn)行說明入口點(diǎn);=2\*GB3②file結(jié)構(gòu),關(guān)鍵用于和文件系統(tǒng)對(duì)應(yīng)設(shè)備驅(qū)動(dòng)程序。代表一個(gè)打開文件,它由內(nèi)核在open時(shí)創(chuàng)建,并傳輸給在該文件上進(jìn)行操作全部函數(shù),直到碰到最終close函數(shù)。在文件全部實(shí)例全部被關(guān)閉以后,內(nèi)核會(huì)釋放這個(gè)數(shù)據(jù)結(jié)構(gòu);=3\*GB3③inode結(jié)構(gòu),提供了相關(guān)特殊設(shè)備文件/dev/mydev信息。各個(gè)結(jié)構(gòu)定義以下:(1)file_operations結(jié)構(gòu):staticconststructfile_operationsmy_fops={.owner=THIS_MODULE,.llseek=my_llseek,.read=my_read,.write=my_write,.open=my_open,.release=my_release,.unlocked_ioctl=ioctl,};(2)file結(jié)構(gòu):1)讀staticssize_tmy_read(structfile*filp,char__user*buf,size_tsize,loff_t*ppos)2)寫staticssize_tmy_write(structfile*filp,constchar__user*buf,size_tsize,loff_t*ppos)3)seek文件定位staticloff_tmy_llseek(structfile*filp,loff_toffset,intwhence)4)I\O控制staticintioctl(structfile*file,unsignedintcmd,unsignedlongarg)(3)inode結(jié)構(gòu):1)打開intmy_open(structinode*inode,structfile*filp)2)釋放intmy_release(structinode*inode,structfile*filp)2.3、算法步驟圖:結(jié)束結(jié)束文件釋放函數(shù)ly_release()設(shè)備驅(qū)動(dòng)模塊卸載函數(shù)mydev_exit()開始設(shè)備驅(qū)動(dòng)模塊加載函數(shù)ly_init()文件打開函數(shù)ly_open()讀函數(shù)ly_read()寫函數(shù)ly_write()Seek文件定位函數(shù)ly_llseek()I\O控制函數(shù)Ioctl()四、系統(tǒng)測試和調(diào)試分析4.1系統(tǒng)測試4.1.1開啟超級(jí)管理員模式并輸入密碼命令:sudosu4.1.2對(duì)源程序進(jìn)行編譯命令:make4.1.3加載驅(qū)動(dòng)程序并查看命令:insmodlydev.ko和lsmod4.1.4顯示主設(shè)備號(hào)命令:cat/proc/devices4.1.5創(chuàng)建節(jié)點(diǎn)并查看命令:mknod/dev/lydev550和cd/dev4.1.6編譯測試程序命令:gcc–ottest.c4.1.7運(yùn)行測試函數(shù)命令:./t4.1.8進(jìn)行打開設(shè)備操作命令:14.1.9進(jìn)行寫操作并輸入hello命令:24.1.10進(jìn)行讀操作命令:34.1.11進(jìn)行I/O控制命令:44.1.12進(jìn)行釋放設(shè)備操作命令:54.1.13進(jìn)行退出操作命令:64.1.14卸載驅(qū)動(dòng)程序命令:rmmodlydev4.1.15查看日志命令:dmesg4.1.16刪除節(jié)點(diǎn)并查看命令:rmlydev和ls4.2調(diào)試分析最開始時(shí)候沒有啟用sudo模式,造成很多命令不能實(shí)施,啟用模式時(shí)候需要輸入密碼,不過輸入密碼時(shí)候是不顯示東西認(rèn)為犯錯(cuò),查閱資料以后才知道是應(yīng)有現(xiàn)象。程序測試一遍以后再次測試很多命令不能實(shí)施,原因是第一次測試以后產(chǎn)生多種文件沒有刪除,再次測試會(huì)顯示已存在。有一次測試程序,不能卸載驅(qū)動(dòng),用lsmod查看有兩個(gè)進(jìn)程使用,以后強(qiáng)制關(guān)機(jī)才能正常使用,原因不明,以后要加強(qiáng)學(xué)習(xí)。五、程序清單1.主程序#include<linux/module.h>#include<linux/types.h>#include<linux/fs.h>#include<linux/errno.h>#include<linux/mm.h>#include<linux/sched.h>#include<linux/init.h>#include<linux/cdev.h>#include<linux/slab.h>#include<asm/io.h>#include<asm/system.h>#include<asm/uaccess.h>#include"lydev.h"#defineSCULL_IOC_MAGIC'k'#defineSCULL_IOCRESET_IO(SCULL_IOC_MAGIC,0)#defineSCULL_IOCSQUANTUM_IOW(SCULL_IOC_MAGIC,1,int)#defineSCULL_IOCSQSET_IOW(SCULL_IOC_MAGIC,2,int)#defineSCULL_IOCTQUANTUM_IO(SCULL_IOC_MAGIC,3)#defineSCULL_IOCTQSET_IO(SCULL_IOC_MAGIC,4)#defineSCULL_IOCGQUANTUM_IOR(SCULL_IOC_MAGIC,5,int)#defineSCULL_IOCGQSET_IOR(SCULL_IOC_MAGIC,6,int)#defineSCULL_IOCQQUANTUM_IO(SCULL_IOC_MAGIC,7)#defineSCULL_IOCQQSET_IO(SCULL_IOC_MAGIC,8)#defineSCULL_IOCXQUANTUM_IOWR(SCULL_IOC_MAGIC,9,int)#defineSCULL_IOCXQSET_IOWR(SCULL_IOC_MAGIC,10,int)#defineSCULL_IOCHQUANTUM_IO(SCULL_IOC_MAGIC,11)#defineSCULL_IOCHQSET_IO(SCULL_IOC_MAGIC,12)#defineSCULL_IOC_MAXNR14staticintly_major=55;module_param(ly_major,int,S_IRUGO);structly_dev*ly_devp;/*設(shè)備結(jié)構(gòu)體指針*/structcdevcdev;staticintioctl(structfile*file,unsignedintcmd,unsignedlongarg);/*文件打開函數(shù)*/intly_open(structinode*inode,structfile*filp){structly_dev*dev;/*獲取次設(shè)備號(hào)*/intnum=MINOR(inode->i_rdev);if(num>=MYDEV_NR_DEVS)return-ENODEV;dev=&ly_devp[num];/*將設(shè)備描述結(jié)構(gòu)指針賦值給文件私有數(shù)據(jù)指針*/filp->private_data=dev;return0;}/*文件釋放函數(shù)*/intly_release(structinode*inode,structfile*filp){return0;}/*讀函數(shù)*/staticssize_tly_read(structfile*filp,char__user*buf,size_tsize,loff_t*ppos){unsignedlongp=*ppos;unsignedintcount=size;intret=0;structly_dev*dev=filp->private_data;/*取得設(shè)備結(jié)構(gòu)體指針*//*判定讀位置是否有效*/if(p>=MYDEV_SIZE)return0;if(count>MYDEV_SIZE-p)count=MYDEV_SIZE-p;/*讀數(shù)據(jù)到用戶空間*/if(copy_to_user(buf,(void*)(dev->data+p),count)){ret=-EFAULT;}else{*ppos+=count;ret=count;printk(KERN_INFO"read%dbytes(s)from%lx\n",count,p);}returnret;}/*寫函數(shù)*/staticssize_tly_write(structfile*filp,constchar__user*buf,size_tsize,loff_t*ppos){unsignedlongp=*ppos;unsignedintcount=size;intret=0;structly_dev*dev=filp->private_data;/*取得設(shè)備結(jié)構(gòu)體指針*//*分析和獲取有效寫長度*/if(p>=MYDEV_SIZE)return0;if(count>MYDEV_SIZE-p)count=MYDEV_SIZE-p;/*從用戶空間寫入數(shù)據(jù)*/if(copy_from_user(dev->data+p,buf,count))ret=-EFAULT;else{*ppos+=count;ret=count;printk(KERN_INFO"written%dbytes(s)from%lx\n",count,p);}returnret;}/*I\O控制函數(shù)*/staticintioctl(structfile*file,unsignedintcmd,unsignedlongarg){ if(_IOC_TYPE(cmd)!=SCULL_IOC_MAGIC) { return-EFAULT; } if(_IOC_NR(cmd)>SCULL_IOC_MAXNR) { return-EFAULT; } switch(cmd){caseSCULL_IOCRESET:printk("SCULL_IOCRESET+%lx",arg);break;caseSCULL_IOCSQUANTUM:/*Set:argpointstothevalue*/printk("SCULL_IOCSQUANTUM+%lx",arg);break;caseSCULL_IOCTQUANTUM:/*Tell:argisthevalue*/printk("SCULL_IOCTQUANTUM+%lx",arg);break;caseSCULL_IOCGQUANTUM:/*Get:argispointertoresult*/printk("SCULL_IOCGQUANTUM+%lx",arg);break;caseSCULL_IOCQQUANTUM:/*Query:returnit(it'spositive)*/printk("SCULL_IOCQQUANTUM+%lx",arg);break;caseSCULL_IOCXQUANTUM:/*eXchange:useargaspointer*/printk("SCULL_IOCXQUANTUM+%lx",arg);break;caseSCULL_IOCHQUANTUM:/*sHift:likeTell+Query*/printk("SCULL_IOCHQUANTUM+%lx",arg); break;}return0; }/*seek文件定位函數(shù)*/staticloff_tly_llseek(structfile*filp,loff_toffset,intwhence){loff_tnewpos;switch(whence){case0:/*SEEK_SET*/newpos=offset;break;case1:/*SEEK_CUR*/newpos=filp->f_pos+offset;break;case2:/*SEEK_END*/newpos=MYDEV_SIZE-1+offset;break;default:/*can'thappen*/return-EINVAL;}if((newpos<0)||(newpos>MYDEV_SIZE))return-EINVAL;filp->f_pos=newpos;returnnewpos;}/*文件操作結(jié)構(gòu)體*/staticconststructfile_operationsly_fops={.owner=THIS_MODULE,.llseek=ly_llseek,.read=ly_read,.write=ly_write,.open=ly_open,.release=ly_release,.unlocked_ioctl=ioctl,};/*設(shè)備驅(qū)動(dòng)模塊加載函數(shù)*/staticintlydev_init(void){intresult;inti;dev_tdevno=MKDEV(ly_major,0);/*靜態(tài)申請(qǐng)?jiān)O(shè)備號(hào)*/if(ly_major)result=register_chrdev_region(devno,2,"lydev");else/*動(dòng)態(tài)分配設(shè)備號(hào)*/{result=alloc_chrdev_region(&devno,0,2,"lydev");ly_major=MAJOR(devno);}if(result<0)returnresult;/*初始化cdev結(jié)構(gòu)*/cdev_init(&cdev,&ly_fops);cdev.owner=THIS_MODULE;cdev.ops=&ly_fops;/*注冊(cè)字符設(shè)備*/cdev_add(&cdev,MKDEV(ly_major,0),MYDEV_NR_DEVS);/*為設(shè)備描述結(jié)構(gòu)分配內(nèi)存*/ly_devp=kmalloc(MYDEV_NR_DEVS*sizeof(structly_dev),GFP_KERNEL);if(!ly_devp)/*申請(qǐng)失敗*/{result=-ENOMEM;gotofail_malloc;}memset(ly_devp,0,sizeof(structly_dev));/*為設(shè)備分配內(nèi)存*/for(i=0;i<MYDEV_NR_DEVS;i++){ly_devp[i].size=MYDEV_SIZE;ly_devp[i].data=kmalloc(MYDEV_SIZE,GFP_KERNEL);memset(ly_devp[i].data,0,MYDEV_SIZE);}printk("模塊加載成功!\n");return0;fail_malloc:unregister_chrdev_region(devno,1);returnresult;}/*模塊卸載函數(shù)*/staticvoidlydev_exit(void){cdev_del(&cdev);/*注銷設(shè)備*/kfree(ly_devp);/*釋放設(shè)備結(jié)構(gòu)體內(nèi)存*/unregister_chrdev_region(MKDEV(ly_major,0),2);/*釋放設(shè)備號(hào)*/printk("模塊卸載成功!\n");}MODULE_LICENSE("GPL");module_init(lydev_init);module_exit(lydev_exit);2.測試程序#include<stdio.h>#include<sys/types.h>#include<unistd.h>#include<fcntl.h>#include<linux/rtc.h>#include<linux/ioctl.h>#include<string.h>#include<stdlib.h>#defineMAXBUF20#defineSCULL_IOC_MAGIC'k'#defineSCULL_IOCRESET_IO(SCULL_IOC_MAGIC,0)#defineSCULL_IOCSQUANTUM_IOW(SCULL_IOC_MAGIC,1,int)#defineSCULL_IOCSQSET_IOW(SCULL_IOC_MAGIC,2,int)#defineSCULL_IOCTQUANTUM_IO(SCULL_IOC_MAGIC,3)#defineSCULL_IOCTQSET_IO(SCULL_IOC_MAGIC,4)#defineSCULL_IOCGQUANTUM_IOR(SCULL_IOC_MAGIC,5,int)#defineSCULL_IOCGQSET_IOR(SCULL_IOC_MAGIC,6,int)#defineSCULL_IOCQQUANTUM_IO(SCULL_IOC_MAGIC,7)#defineSCULL_IOCQQSET_IO(SCULL_IOC_MAGIC,8)#defineSCULL_IOCXQUANTUM_IOWR(SCULL_IOC_MAGIC,9,int)#defineSCULL_IOCXQSET_IOWR(SCULL_IOC_MAGIC,10,int)#defineSCULL_IOCHQUANTUM_IO(SCULL_IOC_MAGIC,11)#defineSCULL_IOCHQSET_IO(SCULL_IOC_MAGIC,12)#defineSCULL_IOC_MAXNR14intmain(){inttestdev;inti,flag=1,t,len=-1;charsel;charbuf[MAXBUF],tmp[MAXBUF];printf("1、打開設(shè)備\n2、寫操作\n3、讀操作\n4、I/O控制\n5、釋放設(shè)備\n6、退出\n");while(1){printf("請(qǐng)輸入要實(shí)施操作:");sel=getchar();getchar();switch(sel){case'1':testdev=open("/dev/lydev",O_RDWR);if(testdev<0){printf("設(shè)備打開失敗\n");break;}flag=0;printf("設(shè)備打開成功!\n"break;/*case'2':if(flag){printf("請(qǐng)先打開設(shè)備!\n");break;}printf("請(qǐng)輸入寫入字符串:");gets(tmp);len=strlen(tmp);printf("len=%d\n",len);t=write(testdev,tmp,len);if(t<0){printf("寫操作失敗!\n");break;}printf("%s字符串寫入成功!\n",tmp);break;case'3':if(flag){printf("請(qǐng)先打開設(shè)備!\n");break;}if(len<0){printf("請(qǐng)優(yōu)異行寫操作!\n");break;}t=read(testdev,buf,len);if(t<0){printf("讀操作失敗!\n");break;}printf("讀操作成功!結(jié)果為:%s\n",buf);break;*/case'2':if(flag){printf("請(qǐng)先打開設(shè)備!\n");continue;}printf("請(qǐng)輸入要寫入字符串:");gets(tmp);len=sizeof(tmp);//strlen(tmp);t=write(testdev,tmp,len);if(t<0){perror("寫操作失敗!\n");exit(-1);}printf("字符串:%s寫入成功!\n",tmp);break;case'3':if(flag){printf("請(qǐng)先打開設(shè)備!\n");continue;}lseek(testdev,0,SEEK_SET);t=read(testdev,buf,len);if(t<0){perror("讀操作失敗!\n");exit(-1);}printf("讀操作成功!結(jié)果為:%s\n",buf);break;case'4':if(flag){printf("請(qǐng)先打開設(shè)備!\n");break;}t=ioctl(testdev,SCULL_IOCTQUANTUM,3);if(t<0){

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論