版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
北京郵電大學(xué)嵌入式系統(tǒng)開發(fā)實驗報告學(xué)院:班級:姓名:學(xué)號:序號:目錄一、 實驗?zāi)康?1二、 實驗設(shè)備 1三、 根底實驗〔實驗一~實驗七〕 11. 實驗五 12. 實驗六 13. 實驗七 1四、 驅(qū)動程序 51. 設(shè)備驅(qū)動程序的概念 52. 驅(qū)動程序結(jié)構(gòu) 63. 設(shè)備注冊和初始化 74. 設(shè)備驅(qū)動程序的開發(fā)過程 8五、 根本接口實驗 81. 實驗十二簡單設(shè)備驅(qū)動程序 92. 實驗十三CPUGPIO驅(qū)動程序設(shè)計 93. 實驗十四中斷實驗 104. 實驗十五數(shù)碼管顯示實驗 125. 實驗十六LED點(diǎn)陣驅(qū)動程序設(shè)計 196. 實驗十七AD驅(qū)動實驗 237. 實驗十八DA驅(qū)動實驗 26六、 實驗中遇到的問題及解決方法 30七、 實驗總結(jié)及心得 31實驗?zāi)康耐ㄟ^實驗熟悉Linux環(huán)境,并掌握一些根本接口驅(qū)動的寫法和用C語言編寫簡單的實驗程序。學(xué)習(xí)LINUX開發(fā)環(huán)境的搭建,通訊配置等。并熟練掌握LINUX驅(qū)動程序的編寫及開發(fā)流程。對嵌入式系統(tǒng)有進(jìn)一步的了解。實驗設(shè)備1.一套PXA270EP嵌入式實驗箱2.安裝Redhat9的宿主PC機(jī),并且配置好ARMLinux的開發(fā)環(huán)境根底實驗〔實驗一~實驗七〕實驗一~七為根底實驗,目的是為后續(xù)實驗搭建好軟、硬件環(huán)境,配置好相關(guān)的協(xié)議、效勞,并通過編寫最簡單的HelloWorld程序進(jìn)行測試。由于后面的實驗都要依靠前面實驗的配置,故本段只著重表達(dá)實驗七的具體實現(xiàn)。實驗五實驗五為宿主PC機(jī)配置了TFTP效勞。TFTP(TrivialFileTransferProtocol)是簡單文件傳輸協(xié)議,由于特定開發(fā)環(huán)境的制約,這一效勞是必須的。在配置完成后,每次重啟宿主PC機(jī)時,都須先輸入命令:servicexinetdrestart,以啟動TFTP效勞。實驗六實驗六為宿主PC機(jī)配置了NFS效勞。NFS(NetworkFileSystem)指網(wǎng)絡(luò)文件系統(tǒng),它實現(xiàn)了文件在不同的系統(tǒng)間使用。當(dāng)我們想用遠(yuǎn)端檔案時,只需調(diào)用“mount〞就可以遠(yuǎn)端系統(tǒng)掛接在自己的檔案系統(tǒng)之下。每次重啟宿主PC機(jī)時,都須先輸入命令:servicenfsrestart,以啟動nfs效勞。實驗七實驗七通過用c語言編寫的簡單程序HelloWorld,測試前面幾個實驗是否成功配置好環(huán)境,從超級終端可以看到HelloWorld程序的運(yùn)行結(jié)果。實驗步驟如下:硬件連接:連接宿主PC機(jī)和一臺PXA270-RP目標(biāo)板。翻開宿主PC機(jī)電源,進(jìn)入Linux操作系統(tǒng)。啟動RedHat9.0的圖形界面,如以下圖,假設(shè)您是以root身份登陸在文本模式下,則輸入命令startx啟動圖形界面。進(jìn)入RedHat9.0圖形界面后,翻開一個終端窗〔Terminal〕。輸入minicom然后回車,minicim設(shè)置為1152008NI無流控。 翻開PXA270_RP目標(biāo)板電源,按目標(biāo)板上的BOOT鍵,在minicom中應(yīng)該會看到如以下圖:在minicom終端窗口中,如圖,輸入以下四條命令rootifconfigeth0upmount-onolock://mntcd/mnt此時,先將該窗口最小化,在后面的第10操作步驟中還將會回到該窗口中進(jìn)行操作。宿主機(jī)上翻開一個終端窗口〔Terminal〕,點(diǎn)擊【紅帽/SystemTools/Terminal】啟動終端窗口,輸入以下4條命令:①cd/home②mkdirHW③cdHW④viHelloWorld.c/*請您輸入程序7.1程序清單*/此時會顯示一個空白的屏幕,這條命令的含義是,使用Vi編輯器,對一個名叫HelloWorld.c的文件進(jìn)行編輯,我們看到的空白窗口是對文件進(jìn)行編輯的窗口,如以下圖。就像在Windows系統(tǒng)下面使用寫字板等一樣道理。在vi里面先單擊鍵盤A鍵,然后左下角會變成—INSER。輸入程序的時候和其他編輯器是一樣的,如以下圖。當(dāng)輸入程序完畢后,單擊鍵盤Esc鍵,然后按“:〞〔冒號〕此時左下角會出現(xiàn)冒號然后輸入“wq〞最后按“Enter〞確認(rèn)存盤退出vi編輯器,如以下圖。在上面同一個終端窗口中,輸入以下2條命令交叉編譯HelloWorld.c源程序,并查看生成的.o目標(biāo)文件,如圖7-10,圖7-11:①arm-linux-gcc–oHelloWorldHelloWorld.c②ls等到再次出現(xiàn)提示符,代表程序已經(jīng)正確編譯。如果此步出現(xiàn)錯誤信息,請查看錯誤信息,并且重新編輯原來的C文件,修改錯誤。直到正確編譯。重新翻開第7步最小化的開有minicom的終端窗口,即到PXA270-RP目標(biāo)板的mnt目錄下,請您輸入以下3條命令,運(yùn)行HelloWorld編譯成功的HelloWorld目標(biāo)程序:①cdhome/HW/*回到minicom中目標(biāo)板的/mnt/home/HW目錄下*/②ls③./HelloWorld/*此時會看到如以下圖*/驅(qū)動程序設(shè)備驅(qū)動程序的概念設(shè)備驅(qū)動程序?qū)嶋H是處理和操作硬件控制器的軟件,從本質(zhì)上講,是內(nèi)核中具有最高特權(quán)級的、駐留內(nèi)存的、可共享的底層硬件處理例程。驅(qū)動程序是內(nèi)核的一局部,是操作系統(tǒng)內(nèi)核與硬件設(shè)備的直接接口,驅(qū)動程序屏蔽了硬件的細(xì)節(jié),完成以下功能:對設(shè)備初始化和釋放;對設(shè)備進(jìn)行管理,包括實時參數(shù)設(shè)置,以及提供對設(shè)備的操作接口;讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù)或者回送應(yīng)用程序請求的數(shù)據(jù);檢測和處理設(shè)備出現(xiàn)的錯誤。Linux操作系統(tǒng)將所有的設(shè)備全部看成文件,并通過文件的操作界面進(jìn)行操作。對用戶程序而言,設(shè)備驅(qū)動程序隱藏了設(shè)備的具體細(xì)節(jié),對各種不同設(shè)備提供了一致的接口,一般來說,是把設(shè)備映射為一個特殊的設(shè)備文件,用戶程序可以像對其他文件一樣對此設(shè)備文件進(jìn)行操作。這意味著:由于每一個設(shè)備至少由文件系統(tǒng)的一個文件代表,因而都有一個“文件名〞。應(yīng)用程序通常可以通過系統(tǒng)調(diào)用open()翻開設(shè)備文件,建立起與目標(biāo)設(shè)備的連接。翻開了代表著目標(biāo)設(shè)備的文件,即建立起與設(shè)備的連接后,可以通過read()、write()、ioctl()等常規(guī)的文件操作對目標(biāo)設(shè)備進(jìn)行操作。設(shè)備文件的屬性由三局部信息組成:第一局部是文件的類型,第二局部是一個主設(shè)備號,第三局部是一個次設(shè)備號。其中類型和主設(shè)備號結(jié)合在一起惟一地確定了設(shè)備文件驅(qū)動程序及其界面,而次設(shè)備號則說明目標(biāo)設(shè)備是同類設(shè)備中的第幾個。由于Linux中將設(shè)備當(dāng)做文件處理,所以對設(shè)備進(jìn)行操作的調(diào)用格式與對文件的操作類似,主要包括open()、read()、write()、ioctl()、close()等。應(yīng)用程序發(fā)出系統(tǒng)調(diào)用命令后,會從用戶態(tài)轉(zhuǎn)到核心態(tài),通過內(nèi)核將open()這樣的系統(tǒng)調(diào)用轉(zhuǎn)換成對物理設(shè)備的操作。驅(qū)動程序結(jié)構(gòu)一個設(shè)備驅(qū)動程序模塊的根本框架在系統(tǒng)內(nèi)部,I/O設(shè)備的存取通過一組固定的入口點(diǎn)來進(jìn)行,入口點(diǎn)也可以理解為設(shè)備的句柄,就是對設(shè)備進(jìn)行操作的根本函數(shù)。字符型設(shè)備驅(qū)動程序提供如下幾個入口點(diǎn):open入口點(diǎn)。翻開設(shè)備準(zhǔn)備I/O操作。對字符設(shè)備文件進(jìn)行翻開操作,都會調(diào)用設(shè)備的open入口點(diǎn)。open子程序必須對將要進(jìn)行的I/O操作做好必要的準(zhǔn)備工作,如去除緩沖區(qū)等。如果設(shè)備是獨(dú)占的,即同一時刻只能有一個程序訪問此設(shè)備,則open子程序必須設(shè)置一些標(biāo)志以表示設(shè)備處于忙狀態(tài)。close入口點(diǎn)。關(guān)閉一個設(shè)備。當(dāng)最后一次使用設(shè)備完成后,調(diào)用close子程序。獨(dú)占設(shè)備必須標(biāo)記設(shè)備方可再次使用。read入口點(diǎn)。從設(shè)備上讀數(shù)據(jù)。對于有緩沖區(qū)的I/O操作,一般是從緩沖區(qū)里讀數(shù)據(jù)。對字符設(shè)備文件進(jìn)行讀操作將調(diào)用read子程序。write入口點(diǎn)。往設(shè)備上寫數(shù)據(jù)。對于有緩沖區(qū)的I/O操作,一般是把數(shù)據(jù)寫入緩沖區(qū)里。對字符設(shè)備文件進(jìn)行寫操作將調(diào)用write子程序。ioctl入口點(diǎn)。執(zhí)行讀、寫之外的操作。select入口點(diǎn)。檢查設(shè)備,看數(shù)據(jù)是否可讀或設(shè)備是否可用于寫數(shù)據(jù)。select系統(tǒng)調(diào)用在檢查與設(shè)備文件相關(guān)的文件描述符時使用select入口點(diǎn)。設(shè)備注冊和初始化設(shè)備的驅(qū)動程序在加載的時候首先需要調(diào)用入口函數(shù)init_module(),該函數(shù)最重要的一個工作就是向內(nèi)核注冊該設(shè)備,對于字符設(shè)備調(diào)用register_chrdev()完成注冊。register_chrdev的定義為:intregister_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops);其中,major是為設(shè)備驅(qū)動程序向系統(tǒng)申請的主設(shè)備號,如果為0,則系統(tǒng)為此驅(qū)動程序動態(tài)分配一個主設(shè)備號。name是設(shè)備名,fops是對各個調(diào)用的入口點(diǎn)說明。此函數(shù)返回0時表示成功;返回-EINVAL,表示申請的主設(shè)備號非法,主要原因是主設(shè)備號大于系統(tǒng)所允許的最大設(shè)備號;返回-EBUSY,表示所申請的主設(shè)備號正在被其他設(shè)備程序使用。如果動態(tài)分配主設(shè)備號成功,此函數(shù)將返回所分配的主設(shè)備號。如果register_chrdev()操作成功,設(shè)備名就會出現(xiàn)在/proc/dvices文件中。Linux在/dev目錄中為每個設(shè)備建立一個文件,用ls–l命令列出函數(shù)返回值,假設(shè)小于0,則表示注冊失敗;返回0或者大于0的值表示注冊成功。注冊以后,Linux將設(shè)備名與主、次設(shè)備號聯(lián)系起來。當(dāng)有對此設(shè)備名的訪問時,Linux通過請求訪問的設(shè)備名得到主、次設(shè)備號,然后把此訪問分發(fā)到對應(yīng)的設(shè)備驅(qū)動,設(shè)備驅(qū)動再根據(jù)次設(shè)備號調(diào)用不同的函數(shù)。當(dāng)設(shè)備驅(qū)動模塊從Linux內(nèi)核中卸載,對應(yīng)的主設(shè)備號必須被釋放。字符設(shè)備在cleanup_module()函數(shù)中調(diào)用unregister_chrdev()來完成設(shè)備的注銷。unregister_chrdev()的定義為:intunregister_chrdev(unsignedintmajor,constchar*name);包括設(shè)備注冊在內(nèi),設(shè)備驅(qū)動的初始化函數(shù)主要完成的功能是有以下5項。〔1〕對驅(qū)動程序管理的硬件進(jìn)行必要的初始化。對硬件存放器進(jìn)行設(shè)置。比方,設(shè)置中斷掩碼,設(shè)置串口的工作方式、并口的數(shù)據(jù)方向等?!?〕初始化設(shè)備驅(qū)動相關(guān)的參數(shù)。一般說來,每個設(shè)備都要定義一個設(shè)備變量,用以保存設(shè)備相關(guān)的參數(shù)。在這一步驟里對設(shè)備變量中的項進(jìn)行初始化?!?〕在內(nèi)核注冊設(shè)備。調(diào)用register_chrdev()函數(shù)來注冊設(shè)備。〔4〕注冊中斷。如果設(shè)備需要IRQ支持,則要使用request_irq()函數(shù)注冊中斷。〔5〕其他初始化工作。初始化局部一般還負(fù)責(zé)給設(shè)備驅(qū)動程序申請包括內(nèi)存、時鐘、I/O端口等在內(nèi)的系統(tǒng)資源,這些資源也可以在open子程序或者其他地方申請。這些資源不用時,應(yīng)該釋放,以利于資源的共享。假設(shè)驅(qū)動程序是內(nèi)核的一局部,初始化函數(shù)則要按如下方式聲明:int__initchr_driver_init(void);其中__init是必不可少的,在系統(tǒng)啟動時會由內(nèi)核調(diào)用chr_driver_init,完成驅(qū)動程序的初始化。當(dāng)驅(qū)動程序是以模塊的形式編寫時,則要按照如下方式聲明:intinit_module(void)當(dāng)運(yùn)行后面介紹的insmod命令插入模塊時,會調(diào)用init_module函數(shù)完成初始化工作。設(shè)備驅(qū)動程序的開發(fā)過程由于嵌入式設(shè)備由于硬件種類非常豐富,在默認(rèn)的內(nèi)核發(fā)布版中不一定包括所有驅(qū)動程序。所以進(jìn)行嵌入式Linux系統(tǒng)的開發(fā),很大的工作量是為各種設(shè)備編寫驅(qū)動程序。除非系統(tǒng)不使用操作系統(tǒng),程序直接操縱硬件。嵌入式Linux系統(tǒng)驅(qū)動程序開發(fā)與普通Linux開發(fā)沒有區(qū)別??梢栽谟布a(chǎn)廠家或者Internet上尋找驅(qū)動程序,也可以根據(jù)相近的硬件驅(qū)動程序來改寫,這樣可以加快開發(fā)速度。實現(xiàn)一個嵌入式Linux設(shè)備驅(qū)動的大致流程如下。〔1〕查看原理圖,理解設(shè)備的工作原理。一般嵌入式處理器的生產(chǎn)商提供參考電路,也可以根據(jù)需要自行設(shè)計?!?〕定義設(shè)備號。設(shè)備由一個主設(shè)備號和一個次設(shè)備號來標(biāo)識。主設(shè)備號惟一標(biāo)識了設(shè)備類型,即設(shè)備驅(qū)動程序類型,它是塊設(shè)備表或字符設(shè)備表中設(shè)備表項的索引。次設(shè)備號僅由設(shè)備驅(qū)動程序解釋,區(qū)分被一個設(shè)備驅(qū)動控制下的某個獨(dú)立的設(shè)備?!?〕實現(xiàn)初始化函數(shù)。在驅(qū)動程序中實現(xiàn)驅(qū)動的注冊和卸載。〔4〕設(shè)計所要實現(xiàn)的文件操作,定義file_operations結(jié)構(gòu)。〔5〕實現(xiàn)所需的文件操作調(diào)用,如read、write等?!?〕實現(xiàn)中斷效勞,并用request_irq向內(nèi)核注冊,中斷并不是每個設(shè)備驅(qū)動所必需的?!?〕編譯該驅(qū)動程序到內(nèi)核中,或者用insmod命令加載模塊?!?〕測試該設(shè)備,編寫應(yīng)用程序,對驅(qū)動程序進(jìn)行測試。根本接口實驗在完成了根本實驗后,我們開始著手根本接口實驗。在這些實驗中,我們學(xué)習(xí)如何編寫設(shè)備驅(qū)動程序,及如何用測試程序檢驗驅(qū)動程序是否正確,并通過改寫測試程序正常地對驅(qū)動程序進(jìn)行相關(guān)操作。實驗十二 簡單設(shè)備驅(qū)動程序本次實驗的任務(wù)是編寫一個字符型設(shè)備驅(qū)動程序,并學(xué)習(xí)在應(yīng)用程序中調(diào)用驅(qū)動??紤]到我們初次接觸驅(qū)動程序的編寫,對此還十分陌生,因此指導(dǎo)書中提供了本次實驗所要用到的程序源代碼。雖然這樣一個字符型設(shè)備驅(qū)動程序并沒有任何實際作用,但是它讓我們輕松掌握了嵌入式驅(qū)動的編寫過程,因為復(fù)雜繁瑣的驅(qū)動,其骨架都是相同的。因此,看懂本實驗的源代碼,學(xué)習(xí)并模仿其編寫方法,對于后續(xù)實驗有著非常重要的意義。實驗十三 CPUGPIO驅(qū)動程序設(shè)計在本實驗中,我們要編寫第一個針對實際硬件的驅(qū)動程序。我們知道,但凡操作系統(tǒng)控制外部設(shè)備,即使是最簡單的硬件電路,也是需要驅(qū)動的。本實驗涉及的外部硬件只有電阻和發(fā)光二極管。我們使用自己編寫的驅(qū)動程序與應(yīng)用程序控制GPIO96的電平,通過LED的亮滅來判斷,是否CPU做出了正確的響應(yīng)。補(bǔ)充代碼〔1〕//WRITEssize_tSIMPLE_GPIO_LED_write(structfile*file,constchar*buf,size_tcount,loff_t*f_ops){#ifdefOURS_GPIO_LED_DEBUGprintk("SIMPLE_GPIO_LED_write[--kernel--]\n");#endifreturncount;} 補(bǔ)充代碼〔2〕//OPENssize_tSIMPLE_GPIO_LED_open(structinode*inode,structfile*file){#ifdefOURS_GPIO_LED_DEBUGprintk("SIMPLE_GPIO_LED_open[--kernel--]\n");#endifMOD_INC_USE_COUNT;return0;} 補(bǔ)充代碼〔3〕//structfile_operationsGPIO_LED_ctl_ops={open:SIMPLE_GPIO_LED_open,read:SIMPLE_GPIO_LED_read,write:SIMPLE_GPIO_LED_write,ioctl:SIMPLE_GPIO_LED_ioctl,release:SIMPLE_GPIO_LED_release,};實驗作業(yè)要求在目標(biāo)板上LED閃爍產(chǎn)生亮7秒,滅2秒的效果在測試程序中有這樣一段代碼:while(1){ ioctl(fd,LED_OFF);sleep(1); //休眠1秒ioctl(fd,LED_ON);sleep(1); }只需將上面的代碼改為如下代碼即可:while(1){ ioctl(fd,LED_OFF);sleep(2); //滅2秒ioctl(fd,LED_ON);sleep(7); //亮7秒}實驗十四 中斷實驗在理論課中,我們學(xué)習(xí)了許多中斷方面的知識,包括中斷向量、中斷優(yōu)先級、中斷過程等。在PXA270系統(tǒng)里,中斷控制器分外部設(shè)備和PXA270X處理器設(shè)備產(chǎn)生的兩個層次的中斷,前者是初級的中斷源,后者是次級中斷源,大量的次級中斷源通常被映射為一個初級中斷源。補(bǔ)充代碼1voidshowversion(void){printk("*********************************************\n");printk("\t%s\t\n",VERSION);printk("*********************************************\n\n");}static intSimpleINT_temp_count=0;補(bǔ)充代碼2//READssize_tSIMPLE_INT_read(structfile*file,char*buf,size_tcount,loff_t*f_ops){#ifdefOURS_INT_DEBUG printk("SIMPLE_INT_read[--kernel--]\n"); #endif returncount;} 補(bǔ)充代碼3//WRITEssize_tSIMPLE_INT_write(structfile*file,constchar*buf,size_tcount,loff_t*f_ops){#ifdefOURS_INT_DEBUG printk("SIMPL_INT_write[--kernel--]\n"); #endif returncount;}補(bǔ)充代碼4//structfile_operationsINT_ctl_ops={open:SIMPLE_INT_open,read:SIMPLE_INT_read,write:SIMPLE_INT_write,ioctl:SIMPLE_INT_ioctl,release:SIMPLE_INT_release,}; 解了硬件中斷腳與中斷的對應(yīng)關(guān)系以及中斷號與中斷處理程對應(yīng)關(guān),對于今后編寫更為復(fù)雜的中斷程序打下根底。實驗十五 數(shù)碼管顯示實驗在此實驗中,我們要編寫針對74LV164的驅(qū)動程序,并用其串并轉(zhuǎn)換功能來控制八段LED數(shù)碼管的顯示。補(bǔ)充代碼1voidshowversion(void){printk("*********************************************\n");printk("\t%s\t\n",VERSION);printk("*********************************************\n\n");}補(bǔ)充代碼2//READssize_tSERIAL_LED_read(structfile*file,char*buf,size_tcount,loff_t*f_ops){#ifdefOURS_HELLO_DEBUG printk("SERIAL_LED_read[--kernel--]\n"); #endif returncount;} 補(bǔ)充代碼3//WRITEssize_tSERIAL_LED_write(structfile*file,constchar*buf,size_tcount,loff_t*f_ops){#ifdefOURS_HELLO_DEBUG printk("SERIAL_LED_write[--kernel--]\n"); #endif write_byte(*buf); returncount;}補(bǔ)充代碼4//IOCTLssize_tSERIAL_LED_ioctl(structinode*inode,structfile*file,unsignedintcmd,longdata){#ifdefOURS_HELLO_DEBUG printk("SERIAL_LED_ioctl[--kernel--]\n");#endif return0;}補(bǔ)充代碼5//OPENssize_tSERIAL_LED_open(structinode*inode,structfile*file){#ifdefOURS_HELLO_DEBUG printk("SERIAL_LED_open[--kernel--]\n");#endif MOD_INC_USE_COUNT; return0;} 補(bǔ)充代碼6//RELEASE/CLOSEssize_tSERIAL_LED_release(structinode*inode,structfile*file){ #ifdefOURS_HELLO_DEBUG printk("SERIAL_LED_release[--kernel--]\n");#endif MOD_DEC_USE_COUNT; return0;}補(bǔ)充代碼7//structfile_operationsSERIAL_LED_ops={open:SERIAL_LED_open,read:SERIAL_LED_read,write:SERIAL_LED_write,ioctl:SERIAL_LED_ioctl,release:SERIAL_LED_release,};補(bǔ)充代碼8staticint__initHW_SERIAL_LED_init(void){intret=-ENODEV; ret=devfs_register_chrdev(SERIAL_LED_MAJOR,"serial_led_ctl",&SERIAL_LED_ops); showversion(); if(ret<0) { printk("pxa270init_modulefailedwith%d\n[--kernel--]",ret); returnret; } else { printk("pxa270serial_led_driverregistersuccess!!![--kernel--]\n"); } returnret;}補(bǔ)充代碼9staticint__initpxa270_SERIAL_LED_init(void){intret=-ENODEV; #ifdefOURS_HELLO_DEBUGprintk("pxa270_SERIAL_LED_init[--kernel--]\n");#endifret=HW_SERIAL_LED_init();if(ret)returnret;return0;}補(bǔ)充代碼10staticvoid__exitcleanup_SERIAL_LED(void){#ifdefOURS_HELLO_DEBUG printk("cleanup_SERIAL_LED[--kernel--]\n");#endif devfs_unregister_chrdev(SERIAL_LED_MAJOR,"serial_led");}補(bǔ)充代碼11MODULE_DESCRIPTION("serial_leddrivermodule");MODULE_AUTHOR("liduo");MODULE_LICENSE("GPL");module_init(pxa270_SERIAL_LED_init);module_exit(cleanup_SERIAL_LED);使用測試程序看到的測試結(jié)果是數(shù)碼管按0-9顯示輸出。實驗作業(yè)要求在上述根底上,分別實現(xiàn)一下兩個功能:①要求您再編寫一個測試程序,實現(xiàn)PXA270-EP目標(biāo)板上的LED數(shù)碼管循環(huán)顯示的數(shù)字9-0。②要求您再編寫一個測試程序,實現(xiàn)PXA270-EP目標(biāo)板上的LED數(shù)碼管循環(huán)顯示的數(shù)字02468。由于在測試程序中定義了數(shù)組buf[10]分別存儲了0-9是個數(shù),因此上述功能的實現(xiàn)方法是,分別對測試程序做如下修改:原測試程序:while(1){ for(count=0;count<10;count++){ data[0]=buf[count];ret=write(fd,data,1);sleep(1);}}實現(xiàn)功能①:while(1){ for(count=9;count>=0;count--) //倒序顯示數(shù)字{ data[0]=buf[count];ret=write(fd,data,1);sleep(1);}}結(jié)果顯示實現(xiàn)功能②:while(1){ for(count=0;count<9;count=count+2) //更改顯數(shù)順序{ data[0]=buf[count];ret=write(fd,data,1);sleep(1);}}結(jié)果顯示通過更改顯數(shù)的順序,很容易實現(xiàn)實驗作業(yè)里要求的功能。實驗十六LED點(diǎn)陣驅(qū)動程序設(shè)計通過本實驗的操作,我們將8X8的點(diǎn)陣LED驅(qū)動起來并通過編寫測試程序,使其能夠按照您的意圖進(jìn)行顯示。要求您還編寫更多的測試程序補(bǔ)充代碼1voidshowversion(void){printk("*********************************************\n");printk("\t%s\t\n",VERSION);printk("*********************************************\n\n");}補(bǔ)充代碼2//READssize_tSIMPLE_LED_read(structfile*file,char*buf,size_tcount,loff_t*f_ops){#ifdefOURS_LED_DEBUG printk("SIMPLE_LED_read[--kernel--]\n"); #endif returncount;} 補(bǔ)充代碼3//IOCTLssize_tSIMPLE_LED_ioctl(structinode*inode,structfile*file,unsignedintcmd,longdata){ #ifdefOURS_LED_DEBUG printk("SIMPLE_LED_ioctl[--kernel--]\n");#endif return0;}補(bǔ)充代碼4//structfile_operationsLED_ctl_ops={ open: SIMPLE_LED_open,read:SIMPLE_LED_read,write:SIMPLE_LED_write,ioctl:SIMPLE_LED_ioctl,release:SIMPLE_LED_release,};補(bǔ)充代碼5staticint__initpxa270_LED_CTL_init(void){intret=-ENODEV; #ifdefOURS_LED_DEBUGprintk("pxa270_LED_CTL_init[--kernel--]\n");#endifret=HW_LED_CTL_init();if(ret)returnret;return0;}補(bǔ)充代碼6staticvoid__exitcleanup_LED_ctl(void){#ifdefOURS_LED_DEBUG printk("cleanup_LED_ctl[--kernel--]\n");#endif outw(0x0000,ioremap_addr); devfs_unregister_chrdev(SIMPLE_LED_MAJOR,"led_ary_ctl");}①要求您再編寫一個測試程序,實現(xiàn)按橫的方向隔行順序掃描LED點(diǎn)陣數(shù)碼管。②要求您再編寫一個測試程序,實現(xiàn)按豎的方向順序掃描LED點(diǎn)陣數(shù)碼管。作業(yè)一,隔行掃描: for(i=1;i<=8;i2++){ buf[0]=c; buf[1]=~r;//row for(j=1;j<=8;j++){ write(fd,buf,2); printf("buf[0],buf[1]:[%x,%x]\n",buf[0],buf[1]); usleep(200000);//sleep0.2second r=r<<1; buf[1]=~r;//column } r=1; c=c<<1;結(jié)果顯示作業(yè)二,豎向掃描: for(i=1;i<=8;i++){ buf[0]=c; buf[1]=~r;//row for(j=1;j<=8;j++){ write(fd,buf,2); printf("buf[0],buf[1]:[%x,%x]\n",buf[0],buf[1]); usleep(200000);//sleep0.2second r=r<<1; buf[1]=~r;//column } r=1; c=c<<1;結(jié)果顯示實驗十七AD驅(qū)動實驗通過本實驗的操作,我們將AD轉(zhuǎn)換器驅(qū)動起來并通過編寫測試程序,使其能夠?qū)⒛M信號量按照我們的要求轉(zhuǎn)換成數(shù)字信號量。為了更加清楚地理解AD轉(zhuǎn)換器的工作過程,請您再編寫一個測試程序,將UCB_ADC_INP_AD0換成其他通道,來觀察其他AD通道情況。補(bǔ)充代碼1voidshowversion(void){printk("%s\n",VERSION);}structucb1x00*ad_ucb;補(bǔ)充代碼2//READstaticssize_tadctl_read(structfile*file,char*buf,size_tcount,loff_t*offset){ #ifdefOURS_HELLO_DEBUG printk("read\n"); #endif returncount;}補(bǔ)充代碼3//WRITEssize_tadctl_write(structfile*file,constchar*buf,size_tcount,loff_t*offset){#ifdefOURS_HELLO_DEBUGprintk("write\n");#endif returncount;}補(bǔ)充代碼4//OPENssize_tadctl_open(structinode*inode,structfile*file){#ifdefOURS_HELLO_DEBUGprintk("open\n");#endif return0;}補(bǔ)充代碼5//RELEASE/CLOSEssize_tadctl_release(structinode*inode,structfile*file){#ifdefOURS_HELLO_DEBUGprintk("release\n");#endif return0;}補(bǔ)充代碼6staticstructfile_operationsadctl_ops={ read: adctl_read, write: adctl_write, ioctl: adctl_ioctl, open: adctl_open, release:adctl_release,};補(bǔ)充代碼7//INITstaticint__initHW_AD_CTL_init(void){ intret=-ENODEV; ret=devfs_register_chrdev(ADCTL_MAJOR,"adctl",&adctl_ops); showversion(); ad_ucb=ucb1x00_get(); if(ret<0) { printk("fail%d\n",ret); return0; } else { printk("adctldriverregistersuccess!\n"); } adctl_dev_handle=devfs_register(NULL,"ad_ctl",DEVFS_FL_DEFAULT,ADCTL_MAJOR,0,S_IFCHR,&adctl_ops,NULL);returnret;}補(bǔ)充代碼8staticint__initpxa270_AD_CTL_init(void){intret=-ENODEV; #ifdefOURS_HELLO_DEBUG printk("init\n"); #endifret=HW_AD_CTL_init();if(ret) returnret;return0;}補(bǔ)充代碼9staticvoid__exitcleanup_AD_ctl(void){ #ifdefOURS_HELLO_DEBUG printk("cleanup\n"); #endif devfs_unregister_chrdev(ADCTL_MAJOR,"ad_ctl"); devfs_unregister(adctl_dev_handle);}實驗十八DA驅(qū)動實驗通過本實驗的操作,我們使用示波器看到了通過DA轉(zhuǎn)換而輸出的波形。在此根底上,要求試寫一個實現(xiàn)輸出三角波的測試程序。補(bǔ)充代碼1#include<linux/config.h>#include<linux/kernel.h>#include<linux/sched.h>#include<linux/timer.h>#include<linux/init.h>#include<linux/module.h>#include<asm/hardware.h>#include<asm/io.h>補(bǔ)充代碼2voidshowversion(void){printk("*****************************\n"); printk("\t%s\t\n",VERSION); printk("*****************************\n");}staticlongioremap_addr;補(bǔ)充代碼3//READssize_tSIMPLE_DA_read(structfile*file,char*buf,size_tcount,loff_t*f_ops){#ifdefOURS_DA_DEBUG printk("SIMPLE_DA_read[--kernel--]\n"); #endif returncount;} 補(bǔ)充代碼4//WRITEssize_tSIMPLE_DA_write(structfile*file,constchar*buf,size_tcount,loff_t*f_ops){ #ifdefOURS_DA_DEBUGprintk("SIMPLE_DA_write[--kernel--]\n");#endif outb(buf[0],ioremap_addr);returncount;} 補(bǔ)充代碼5//IOCTLssize_tSIMPLE_DA_ioctl(structinode*inode,structfile*file,unsignedintcmd,longdata){#ifdefOURS_DA_DEBUGprintk("SIMPLE_DA_ioctl[--kernel--]\n");#endifreturn0;}補(bǔ)充代碼6//OPENssize_tSIMPLE_DA_open(structinode*inode,structfile*file){ #ifdefOURS_DA_DEBUG printk("SIMPLE_DA_open[--kernel--]\n");#endif MOD_INC_USE_COUNT; return0;} 補(bǔ)充代碼7/structfile_operationsDA_ctl_ops={read:SIMPLE_DA_read, write:SIMPLE_DA_write, ioctl:SIMPLE_DA_ioctl, release:SIMPLE_DA_release,};補(bǔ)充代碼8//INITstaticint__initHW_DA_CTL_init(void)
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度林木種植與農(nóng)業(yè)產(chǎn)業(yè)結(jié)構(gòu)調(diào)整合同4篇
- 二零二五版版權(quán)居間代理合同樣本3篇
- 2025年度企業(yè)培訓(xùn)中心場地租賃及配套服務(wù)協(xié)議4篇
- 2025年度儲煤場租賃與煤炭儲備應(yīng)急響應(yīng)合同4篇
- 二零二五版快遞企業(yè)快遞物品處理流程合同大全3篇
- 2025至2030年中國分線筒數(shù)據(jù)監(jiān)測研究報告
- 2025年財務(wù)專用打印機(jī)項目可行性研究報告
- 2025年玉米葡萄糖母液項目可行性研究報告
- 2025年水質(zhì)測試劑項目可行性研究報告
- 2025年木皮粘合劑項目可行性研究報告
- CNAS實驗室評審不符合項整改報告
- 農(nóng)民工考勤表(模板)
- 承臺混凝土施工技術(shù)交底
- 臥床患者更換床單-軸線翻身
- 計量基礎(chǔ)知識培訓(xùn)教材201309
- 中考英語 短文填詞、選詞填空練習(xí)
- 一汽集團(tuán)及各合資公司組織架構(gòu)
- 阿特拉斯基本擰緊技術(shù)ppt課件
- 初一至初三數(shù)學(xué)全部知識點(diǎn)
- 新課程理念下的班主任工作藝術(shù)
- (完整版)企業(yè)破產(chǎn)流程圖(四張)
評論
0/150
提交評論