實(shí)驗(yàn)八 IO口驅(qū)動(dòng)實(shí)驗(yàn)_第1頁(yè)
實(shí)驗(yàn)八 IO口驅(qū)動(dòng)實(shí)驗(yàn)_第2頁(yè)
實(shí)驗(yàn)八 IO口驅(qū)動(dòng)實(shí)驗(yàn)_第3頁(yè)
實(shí)驗(yàn)八 IO口驅(qū)動(dòng)實(shí)驗(yàn)_第4頁(yè)
實(shí)驗(yàn)八 IO口驅(qū)動(dòng)實(shí)驗(yàn)_第5頁(yè)
已閱讀5頁(yè),還剩6頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

實(shí)驗(yàn)八I/O口驅(qū)動(dòng)實(shí)驗(yàn)【實(shí)驗(yàn)?zāi)康摹?、 了解PXA270微處理器GPIO的功能2、 熟悉PXA270微處理器GPIO驅(qū)動(dòng)程序的編寫(xiě)方法3、 掌握驅(qū)動(dòng)程序的加載過(guò)程和方法【實(shí)驗(yàn)原理】Linux以模塊的形式加載設(shè)備類(lèi)型,通常來(lái)說(shuō)一個(gè)模塊對(duì)應(yīng)一個(gè)設(shè)備驅(qū)動(dòng),因此是可以分類(lèi)的。將模塊分成不同的類(lèi)型或者類(lèi)并不是一成不變的,開(kāi)發(fā)人員可以根據(jù)實(shí)際工作需要在一個(gè)模塊中實(shí)現(xiàn)不同的驅(qū)動(dòng)程序。一般情況,一個(gè)設(shè)備驅(qū)動(dòng)對(duì)應(yīng)一類(lèi)設(shè)備的模塊方式,這樣便于多個(gè)設(shè)備的協(xié)調(diào)工作也利于應(yīng)用程序的開(kāi)發(fā)和擴(kuò)展。設(shè)備驅(qū)動(dòng)在準(zhǔn)備好以后可以編譯到內(nèi)核中(參考實(shí)驗(yàn)四的內(nèi)容),在系統(tǒng)啟動(dòng)時(shí)和內(nèi)核一起啟動(dòng),這種方法在嵌入式Linux系統(tǒng)中經(jīng)常被采用。通常情況下設(shè)備驅(qū)動(dòng)的動(dòng)態(tài)加載更為普遍(參考實(shí)驗(yàn)七的內(nèi)容),開(kāi)發(fā)人員不必在調(diào)試過(guò)程中頻繁啟動(dòng)機(jī)器就能完成設(shè)備驅(qū)動(dòng)的開(kāi)發(fā)工作。設(shè)備驅(qū)動(dòng)在加載時(shí)首先調(diào)用入口函數(shù)init_module(),該函數(shù)完成設(shè)備驅(qū)動(dòng)的初始化工作,比如寄存器置位、結(jié)構(gòu)體賦值等一系列工作,其中最重要的一個(gè)工作就是向內(nèi)核注冊(cè)該設(shè)備,對(duì)于字符設(shè)備調(diào)用register_chrdev()完成注冊(cè),對(duì)于塊設(shè)備需要調(diào)用register_blkdev()完成注冊(cè)。注冊(cè)成功后,該設(shè)備獲得了系統(tǒng)分配的主設(shè)備號(hào)、自定義的次設(shè)備號(hào),并建立起于文件系統(tǒng)的關(guān)聯(lián)。設(shè)備在卸載時(shí)需要回收相應(yīng)的資源,令設(shè)備的響應(yīng)寄存器復(fù)位并從系統(tǒng)中注銷(xiāo)該設(shè)備,字符設(shè)備調(diào)用unregister_chrdev()、塊設(shè)備調(diào)用unregister_blkdev()。系統(tǒng)調(diào)用部分則是對(duì)設(shè)備的操作過(guò)程,比如open、read、write、ioctl等。圖8-1為一個(gè)設(shè)備驅(qū)動(dòng)模塊動(dòng)態(tài)掛載、卸載和系統(tǒng)調(diào)用的全過(guò)程。圖8-1設(shè)備驅(qū)動(dòng)在內(nèi)核中的掛載、卸載和系統(tǒng)調(diào)用過(guò)程用戶(hù)空間I 內(nèi)核空間圖8-1設(shè)備驅(qū)動(dòng)在內(nèi)核中的掛載、卸載和系統(tǒng)調(diào)用過(guò)程用戶(hù)空間I 內(nèi)核空間1<-模塊1111insmod*Init_module()-1—,廣,4 register_XXX1 系1統(tǒng)/—設(shè)備驅(qū)動(dòng)調(diào)\r內(nèi)核模塊用rmmodClearup_module()- [ ? unregister_XXX設(shè)備驅(qū)動(dòng)程序負(fù)責(zé)將應(yīng)用程序如讀、寫(xiě)等操作正確無(wú)誤的傳遞給相關(guān)的硬件,并使硬件能夠做出正確反應(yīng)的代碼,因此在編寫(xiě)設(shè)備驅(qū)動(dòng)程序時(shí),必須要了解相應(yīng)的硬件設(shè)備的寄存器、IO口及內(nèi)存的配置參數(shù)。1、硬件接口電路介紹(1)、LED和八段數(shù)碼顯示接口電路目標(biāo)板LED和八段數(shù)碼顯示接口電路如圖8-2所示,74HC574為D鎖存器,在時(shí)鐘信號(hào)CLK作用下,該鎖存器將輸入信號(hào)進(jìn)行鎖存,即xQ=xD(x=1?8)。從圖中可以看出,LED和八段數(shù)碼顯示電路將74HC574的時(shí)鐘信號(hào)輸入端作為片選信號(hào),其中LED顯示的片選信號(hào)為L(zhǎng)ED_CS4、八段數(shù)碼顯示的片選信號(hào)為L(zhǎng)ED_CS1。在八段數(shù)碼顯示電路中,8位數(shù)據(jù)的高位(D7、D15:即數(shù)碼管的小數(shù)點(diǎn)dp段)用作八段數(shù)碼的公共選通信號(hào),通過(guò)控制PNP三極管來(lái)控制數(shù)碼管的顯示。[1.2.6.8]BD[0:31]<<^-|\BDO2\ 3\ED24\BD35\ED57\ ,\EI”974HC574LED-CS4VCC5 0VCC_5FB1LBDR191680LSDh受>CLKOEVCC>CLK1190OPENSS8J50L.T1…5R202一VCC[1.2.6.8]BD[0:31]<<^-|\BDO2\ 3\ED24\BD35\ED57\ ,\EI”974HC574LED-CS4VCC5 0VCC_5FB1LBDR191680LSDh受>CLKOEVCC>CLK1190OPENSS8J50L.T1…5R202一VCC5F12QQ一I■SS8J50L.T1JJ22DidHD11□14□151191VCC3.3一R6574Hfti7422OPE雇R2161LED420gdp81A522OPE^D.1UFR216LEIM51iiD.1UFVCC3.3一R65LED420'77D1Q1D2Q2D3Q3D4Q4D5Q5D606D7Q7D8QG>CLKOOCgIHQ顯示電路中的片選信號(hào)LED_CSx,由目標(biāo)板系統(tǒng)的PXA270xCPU的地址信號(hào)BA22?BA20通過(guò)BA20通過(guò)3-8譯碼器LC138產(chǎn)生(如圖8-3所示)。BA20BA21BA22圖8-3片選信號(hào)產(chǎn)生電路由圖可知,當(dāng)BA22、BA21、BA20=101時(shí)產(chǎn)生LED顯示電路的片選信號(hào)LED_CS4,當(dāng)BA22、BA21、BA20=010、011、100時(shí)分別產(chǎn)生八段數(shù)碼顯示電路的片選信號(hào)LED_CS1、LED_CS2、LED_CS3(另外2組八段顯示電路參考系統(tǒng)提供的總電路圖)。(2)、鍵盤(pán)接口電路目標(biāo)平臺(tái)提供了陣列鍵盤(pán)(如圖8-4所示)和單按鍵鍵盤(pán)(如圖8-5所示)兩種鍵盤(pán)接口電路,其中陣列鍵盤(pán)中行控制信號(hào)線KP-MKIN0?2分別由CPU的通用IO口GPIO100?102控制,列控制信號(hào)線KP-MKOUT0?5分別由CPU的通用IO口GPIO103?105和GPIO108控制。單按鍵鍵盤(pán)的控制信號(hào)線KP-DKIN1?2,KP-DKIN5?6分別由CPU的通用IO口GPIO94?95和GPIO98?99控制。[1]KP-DKING[1]KP-DKIN1[1]KP-CKIN2[1]KP-DKIN5VCC_3.3KP-DK1M6KP-DK1M2KP-DK1H5xxKP-DK1H1[1]KP-DKING[1]KP-DKIN1[1]KP-CKIN2[1]KP-DKIN5VCC_3.3KP-DK1M6KP-DK1M2KP-DK1H5xxKP-DK1H1圖8-5單按鍵鍵盤(pán)接口、步進(jìn)電機(jī)控制接口步進(jìn)電機(jī)控制電路如圖8-6所示,步進(jìn)電機(jī)的轉(zhuǎn)動(dòng)方向控制信號(hào)和步進(jìn)輸入信號(hào)GP1、GP2分別由CPU的通用IO口GPIO83和GPIO84控制。圖8-6步進(jìn)電機(jī)控制接口電路2、I/O驅(qū)動(dòng)程序設(shè)備驅(qū)動(dòng)程序運(yùn)行在內(nèi)核空間,而應(yīng)用程序則運(yùn)行在用戶(hù)空間,Linux操作系統(tǒng)通過(guò)系統(tǒng)調(diào)用和硬件中斷完成從用戶(hù)空間到內(nèi)核空間的控制轉(zhuǎn)移,執(zhí)行系統(tǒng)調(diào)用的內(nèi)核代碼在進(jìn)程的上下文中執(zhí)行,也就是說(shuō)代表調(diào)用進(jìn)程操作而且可以訪問(wèn)進(jìn)程地址空間的數(shù)據(jù),中斷處理程序相對(duì)進(jìn)程而言是異步的,而且與任何一個(gè)進(jìn)程都無(wú)關(guān)。

設(shè)備驅(qū)動(dòng)模塊的功能就是擴(kuò)展內(nèi)核的功能,主要完成兩部分任務(wù):一個(gè)是系統(tǒng)調(diào)用,另一個(gè)是中斷處理。下面分別以八段數(shù)碼顯示驅(qū)動(dòng)模塊為例介紹如何在一個(gè)字符驅(qū)動(dòng)設(shè)備實(shí)現(xiàn)對(duì)I/O驅(qū)動(dòng)程序的編寫(xiě)方法和過(guò)程(源碼實(shí)驗(yàn)文件為XSB_EDR_8SEG..c)。模塊初始化模塊初始化module_init(Emdoor_8Seg_init)函數(shù)中的參數(shù)Emdoor_8Seg_init實(shí)際上為八段數(shù)碼顯示驅(qū)動(dòng)模塊的初始化函數(shù)staticint_initEmdoor_8Seg_init(void),該函數(shù)主要完成將產(chǎn)生數(shù)碼顯示的片選控制信號(hào)的BA22?BA20通過(guò)void*ioremap(unsignedlongoffset,unsignedlongsize)函數(shù)為I/O內(nèi)存區(qū)域分配虛擬地址,這樣設(shè)備驅(qū)動(dòng)程序就能訪問(wèn)I/O內(nèi)存地址,同時(shí)在模塊初始化函數(shù)中,register_chrdev()函數(shù)完成字符設(shè)備在內(nèi)核系統(tǒng)中的注冊(cè)并建立與文件系統(tǒng)(Emdoor_fops)的關(guān)聯(lián)。staticint__initEmdoor_8Seg_init(void){intret;cs1_address=ioremap(SEG_CS1,32);//distributeI/Omemorymapaddresscs2_address=ioremap(SEG_CS2,4);cs3_address=ioremap(SEG_CS3,4);ret=register_chrdev(61,DEVICE_NAME,&Emdoor_fops);//registerdevicenameif(ret<0){printk(DEVICE_NAME"can'tgetmajornumber\n");returnret;}return0;}其中數(shù)碼片選信號(hào)SEG_CS1~3和設(shè)備文件名在程序中采用#define宏定義進(jìn)行定義。#defineDEVICE_NAME"emdoor_8seg"#defineSEG_CS1#defineSEG_CS2#defineSEG_CS3#defineSEG_CS1#defineSEG_CS2#defineSEG_CS30x102000000x103000000x10400000//A22,A21,A20=011->LED_CS2//A22,A21,A20=100->LED_CS3模塊的卸載模塊的卸載module_exit(Emdoor_8Seg_exit)函數(shù)中參數(shù)Emdoor_8Seg_exit實(shí)際上是模塊的從內(nèi)核卸載時(shí)所調(diào)用的staticvoid_exitEmdoor_8Seg_exit(void);設(shè)備在卸載時(shí)需要回收相應(yīng)的資源,并利用unregister_chrdev(涵數(shù)從內(nèi)核中將設(shè)備注銷(xiāo)。staticvoid__exitEmdoor_8Seg_exit(void){iounmap(cs1_address);//releaseI/Omemorymap,reclaimsystemresourceiounmap(cs2_address);iounmap(cs3_address);unregister_chrdev(61,DEVICE_NAME);//unregisterdevice}設(shè)備文件操作接口定義設(shè)備文件操作接口定義是用戶(hù)使用該設(shè)備的關(guān)鍵,合理的定義可簡(jiǎn)化應(yīng)用程序設(shè)計(jì),縮短項(xiàng)目的整體開(kāi)發(fā)周期。八段數(shù)碼顯示驅(qū)動(dòng)模塊定義了open、write、release、ioctl等四種設(shè)

備文件操作,內(nèi)容如下所示:staticstructfile_operationsEmdoor_fops=(Emdoor_8Seg_open,Emdoor_8Seg_write,Emdoor_8Seg_release,Emdoor_8Seg_open,Emdoor_8Seg_write,Emdoor_8Seg_release,Emdoor_8Seg_ioctl,//openoperationfunction//writeoperationfunction//releaseoperationfunction//IOcontroloperationfunctionwrite:release:ioctl:owner:THIS_MODULE,};設(shè)備文件操作根據(jù)設(shè)備文件操作接口定義,每一個(gè)設(shè)備文件操作對(duì)應(yīng)一個(gè)系統(tǒng)調(diào)用,在用戶(hù)程序中利用系統(tǒng)調(diào)用對(duì)設(shè)備文件進(jìn)行諸如open/write等操作時(shí),系統(tǒng)調(diào)用通過(guò)設(shè)備文件的主設(shè)備號(hào)找到相應(yīng)的設(shè)備驅(qū)動(dòng)程序,然后讀取設(shè)備文件操作接口定義的相應(yīng)的函數(shù)指針,接著把控制權(quán)交給該操作函數(shù)。在八段數(shù)碼顯示驅(qū)動(dòng)模塊定義了open、write、release>ioctl等四種設(shè)備文件操作。.打開(kāi)設(shè)備操作staticintEmdoor_8Seg_open(structinode*inode,structfile*filp){structseg*seg_7;seg_7=kmalloc(sizeof(structseg),GFP_KERNEL);//distributememoryinkernelspaceseg_7->negative=LED_MODULE;filp->private_data=seg_7;//privatedatapointerpointtoseg_7MOD_INC_USE_COUNT;//currentmodulecounteradd1return0;}.寫(xiě)設(shè)備操作staticssize_tEmdoor_8Seg_write(structfile*file,constchar*buffer,size_tcount,loff_t*ppos){inti;structseg*seg_7=file->private_data;charled_forall[6];if(count!=6)//LEDamount{printk(KERN_EMERG"thecountofinputisnotsix!!");return0;}copy_from_user(led_forall,buffer,6);//copydatafromuserspacetokernelspacefor(i=1;i<=6;i++){value_seting(seg_7,i,LED[i-1]);}Updateled(seg_7);//lightentheLEDreturn6;}.I/O控制操作unsignedlongarg)staticintEmdoor_8Seg_ioctl(structinode*ip,structfile*fp,unsignedintcmd,unsignedlongarg)charval=0x00;structseg*seg_7=fp->private_data;if(!arg)return-EINVAL;if(copy_from_user(&val,(int*)arg,sizeof(char)))return-EFAULT;switch(cmd){//controltheLEDcommandwordcase1:value_seting(seg_7,1,val);//controlthefirst8LEDbreak;case2:value_seting(seg_7,2,val);//controlthesecond8LEDbreak;case3:value_seting(seg_7,3,val);//controlthethird8LEDbreak;case4:value_seting(seg_7,4,val);break;case5:value_seting(seg_7,5,val);break;case6:value_seting(seg_7,6,val);//controlthesixth8LEDbreak;case0: //clearallLEDseg_7->negative=LED_MODULE;break;default:printk(KERN_EMERG"ioctlparameterinputerror,pleaseinputnumber0-6");break;}Updateled(seg_7);//lightenLEDreturn0;}④.釋放設(shè)備操作staticintEmdoor_8Seg_release(structinode*inode,structfile*filp){kfree(filp->private_data);//releasememorywhichdistributedbykmallocMOD_DEC_USE_COUNT;//currentmodulecountersubtract1return0;}5)內(nèi)部自定義函數(shù)在八段數(shù)碼顯示驅(qū)動(dòng)程序中,自定義了一個(gè)點(diǎn)亮數(shù)碼管的函數(shù) Updateled(structseg*seg_7)staticvoidUpdateled(structseg*seg_7){unsignedshortbuff=0x00;buff=seg_7->led1_val;buff=buff|(seg_7->led2_val<<8);writew(buff,cs1_address);//write16bitsdataintoI/Omemorybuff=0x00;buff=seg_7->led3_val;buff=buff|(seg_7->led4_val<<8);writew(buff,cs2_address);buff=0x00;buff=seg_7->led5_val;buff=buff|(seg_7->led6_val<<8);writew(buff,cs3_address);return;}和設(shè)置數(shù)碼管所顯示數(shù)值的函數(shù)value_seting(structseg*seg_7,charposition,charvalue)。voidvalue_seting(structseg*seg_7,charposition,charvalue){if(seg_7->negative==0)value=~value&~(0x1<<7);elsevalue=(0x1<<7)|value;if(position==1)seg_7->led1_val=value;elseif(position==2)seg_7->led2_val=value;elseif(position==3)seg_7->led3_val=value;elseif(position==4)seg_7->led4_val=value;elseif(position==5)seg_7->led5_val=value;elseif(position==6)seg_7->led6_val=value;}3、驅(qū)動(dòng)模塊的編譯在編譯驅(qū)動(dòng)模塊程序時(shí),應(yīng)當(dāng)編寫(xiě)適合于特定目標(biāo)平臺(tái)的Makefile編譯文件(具體參考實(shí)驗(yàn)七和實(shí)驗(yàn)二的內(nèi)容),下面為八段數(shù)碼顯示驅(qū)動(dòng)模塊的Makefile內(nèi)容,,必須注意的是交叉編譯工具變量CC和模塊將要使用和運(yùn)行的內(nèi)核源碼的include變量INCLUDEDIR兩個(gè)變量的設(shè)定必須根據(jù)編譯平臺(tái)的實(shí)際路徑進(jìn)行修改。CC=/opt/xscalevl/bin/arm-linux-gccINCLUDEDIR=/XSBase270/2.4/Kernel/xsbase/linux-2.4.21-emdoor_EDR/includeCFLAGS=-D__KERNEL__-DMODULE-Wall-O2CFLAGS+=-I..-I$(INCLUDEDIR)#8SEGTARGET_8SEG=XSB_EDR_8SEGOBJ_8SEG=$(TARGET_8SEG).oSOURCE_8SEG=$(TARGET_8SEG).call:$(OBJ_8SEG)$(OBJ_8SEG):$(SOURCE_8SEG)$(CC)$(CFLAGS)-c-o$(OBJ_8SEG)$(SOURCE_8SEG)clean:rm-rf$(OBJ_8SEG)4、驅(qū)動(dòng)模塊的加載將編譯好的驅(qū)動(dòng)模塊下載到目標(biāo)上,進(jìn)入目標(biāo)板系統(tǒng)后,利用mknod命令在/dev目錄下建立該設(shè)備的節(jié)點(diǎn)。然后利用insmod命令裝載驅(qū)動(dòng)模塊,最后在目標(biāo)平臺(tái)中運(yùn)行驅(qū)動(dòng)模塊的測(cè)試程序driverTest(測(cè)試程序的下載過(guò)程參考實(shí)驗(yàn)六的內(nèi)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論