版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
北京郵電大學(xué)嵌入式系統(tǒng)開(kāi)發(fā)實(shí)驗(yàn)報(bào)告學(xué)院:班級(jí):姓名:學(xué)號(hào):序號(hào):目錄一、 實(shí)驗(yàn)?zāi)康?1二、 實(shí)驗(yàn)設(shè)備 1三、 根底實(shí)驗(yàn)〔實(shí)驗(yàn)一~實(shí)驗(yàn)七〕 11. 實(shí)驗(yàn)五 12. 實(shí)驗(yàn)六 13. 實(shí)驗(yàn)七 1四、 驅(qū)動(dòng)程序 51. 設(shè)備驅(qū)動(dòng)程序的概念 52. 驅(qū)動(dòng)程序結(jié)構(gòu) 63. 設(shè)備注冊(cè)和初始化 74. 設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā)過(guò)程 8五、 根本接口實(shí)驗(yàn) 81. 實(shí)驗(yàn)十二簡(jiǎn)單設(shè)備驅(qū)動(dòng)程序 92. 實(shí)驗(yàn)十三CPUGPIO驅(qū)動(dòng)程序設(shè)計(jì) 93. 實(shí)驗(yàn)十四中斷實(shí)驗(yàn) 104. 實(shí)驗(yàn)十五數(shù)碼管顯示實(shí)驗(yàn) 125. 實(shí)驗(yàn)十六LED點(diǎn)陣驅(qū)動(dòng)程序設(shè)計(jì) 196. 實(shí)驗(yàn)十七AD驅(qū)動(dòng)實(shí)驗(yàn) 237. 實(shí)驗(yàn)十八DA驅(qū)動(dòng)實(shí)驗(yàn) 26六、 實(shí)驗(yàn)中遇到的問(wèn)題及解決方法 30七、 實(shí)驗(yàn)總結(jié)及心得 31實(shí)驗(yàn)?zāi)康耐ㄟ^(guò)實(shí)驗(yàn)熟悉Linux環(huán)境,并掌握一些根本接口驅(qū)動(dòng)的寫(xiě)法和用C語(yǔ)言編寫(xiě)簡(jiǎn)單的實(shí)驗(yàn)程序。學(xué)習(xí)LINUX開(kāi)發(fā)環(huán)境的搭建,通訊配置等。并熟練掌握LINUX驅(qū)動(dòng)程序的編寫(xiě)及開(kāi)發(fā)流程。對(duì)嵌入式系統(tǒng)有進(jìn)一步的了解。實(shí)驗(yàn)設(shè)備1.一套PXA270EP嵌入式實(shí)驗(yàn)箱2.安裝Redhat9的宿主PC機(jī),并且配置好ARMLinux的開(kāi)發(fā)環(huán)境根底實(shí)驗(yàn)〔實(shí)驗(yàn)一~實(shí)驗(yàn)七〕實(shí)驗(yàn)一~七為根底實(shí)驗(yàn),目的是為后續(xù)實(shí)驗(yàn)搭建好軟、硬件環(huán)境,配置好相關(guān)的協(xié)議、效勞,并通過(guò)編寫(xiě)最簡(jiǎn)單的HelloWorld程序進(jìn)行測(cè)試。由于后面的實(shí)驗(yàn)都要依靠前面實(shí)驗(yàn)的配置,故本段只著重表達(dá)實(shí)驗(yàn)七的具體實(shí)現(xiàn)。實(shí)驗(yàn)五實(shí)驗(yàn)五為宿主PC機(jī)配置了TFTP效勞。TFTP(TrivialFileTransferProtocol)是簡(jiǎn)單文件傳輸協(xié)議,由于特定開(kāi)發(fā)環(huán)境的制約,這一效勞是必須的。在配置完成后,每次重啟宿主PC機(jī)時(shí),都須先輸入命令:servicexinetdrestart,以啟動(dòng)TFTP效勞。實(shí)驗(yàn)六實(shí)驗(yàn)六為宿主PC機(jī)配置了NFS效勞。NFS(NetworkFileSystem)指網(wǎng)絡(luò)文件系統(tǒng),它實(shí)現(xiàn)了文件在不同的系統(tǒng)間使用。當(dāng)我們想用遠(yuǎn)端檔案時(shí),只需調(diào)用“mount〞就可以遠(yuǎn)端系統(tǒng)掛接在自己的檔案系統(tǒng)之下。每次重啟宿主PC機(jī)時(shí),都須先輸入命令:servicenfsrestart,以啟動(dòng)nfs效勞。實(shí)驗(yàn)七實(shí)驗(yàn)七通過(guò)用c語(yǔ)言編寫(xiě)的簡(jiǎn)單程序HelloWorld,測(cè)試前面幾個(gè)實(shí)驗(yàn)是否成功配置好環(huán)境,從超級(jí)終端可以看到HelloWorld程序的運(yùn)行結(jié)果。實(shí)驗(yàn)步驟如下:硬件連接:連接宿主PC機(jī)和一臺(tái)PXA270-RP目標(biāo)板。翻開(kāi)宿主PC機(jī)電源,進(jìn)入Linux操作系統(tǒng)。啟動(dòng)RedHat9.0的圖形界面,如以下圖,假設(shè)您是以root身份登陸在文本模式下,則輸入命令startx啟動(dòng)圖形界面。進(jìn)入RedHat9.0圖形界面后,翻開(kāi)一個(gè)終端窗〔Terminal〕。輸入minicom然后回車(chē),minicim設(shè)置為1152008NI無(wú)流控。 翻開(kāi)PXA270_RP目標(biāo)板電源,按目標(biāo)板上的BOOT鍵,在minicom中應(yīng)該會(huì)看到如以下圖:在minicom終端窗口中,如圖,輸入以下四條命令rootifconfigeth0upmount-onolock://mntcd/mnt此時(shí),先將該窗口最小化,在后面的第10操作步驟中還將會(huì)回到該窗口中進(jìn)行操作。宿主機(jī)上翻開(kāi)一個(gè)終端窗口〔Terminal〕,點(diǎn)擊【紅帽/SystemTools/Terminal】啟動(dòng)終端窗口,輸入以下4條命令:①cd/home②mkdirHW③cdHW④viHelloWorld.c/*請(qǐng)您輸入程序7.1程序清單*/此時(shí)會(huì)顯示一個(gè)空白的屏幕,這條命令的含義是,使用Vi編輯器,對(duì)一個(gè)名叫HelloWorld.c的文件進(jìn)行編輯,我們看到的空白窗口是對(duì)文件進(jìn)行編輯的窗口,如以下圖。就像在Windows系統(tǒng)下面使用寫(xiě)字板等一樣道理。在vi里面先單擊鍵盤(pán)A鍵,然后左下角會(huì)變成—INSER。輸入程序的時(shí)候和其他編輯器是一樣的,如以下圖。當(dāng)輸入程序完畢后,單擊鍵盤(pán)Esc鍵,然后按“:〞〔冒號(hào)〕此時(shí)左下角會(huì)出現(xiàn)冒號(hào)然后輸入“wq〞最后按“Enter〞確認(rèn)存盤(pán)退出vi編輯器,如以下圖。在上面同一個(gè)終端窗口中,輸入以下2條命令交叉編譯HelloWorld.c源程序,并查看生成的.o目標(biāo)文件,如圖7-10,圖7-11:①arm-linux-gcc–oHelloWorldHelloWorld.c②ls等到再次出現(xiàn)提示符,代表程序已經(jīng)正確編譯。如果此步出現(xiàn)錯(cuò)誤信息,請(qǐng)查看錯(cuò)誤信息,并且重新編輯原來(lái)的C文件,修改錯(cuò)誤。直到正確編譯。重新翻開(kāi)第7步最小化的開(kāi)有minicom的終端窗口,即到PXA270-RP目標(biāo)板的mnt目錄下,請(qǐng)您輸入以下3條命令,運(yùn)行HelloWorld編譯成功的HelloWorld目標(biāo)程序:①cdhome/HW/*回到minicom中目標(biāo)板的/mnt/home/HW目錄下*/②ls③./HelloWorld/*此時(shí)會(huì)看到如以下圖*/驅(qū)動(dòng)程序設(shè)備驅(qū)動(dòng)程序的概念設(shè)備驅(qū)動(dòng)程序?qū)嶋H是處理和操作硬件控制器的軟件,從本質(zhì)上講,是內(nèi)核中具有最高特權(quán)級(jí)的、駐留內(nèi)存的、可共享的底層硬件處理例程。驅(qū)動(dòng)程序是內(nèi)核的一局部,是操作系統(tǒng)內(nèi)核與硬件設(shè)備的直接接口,驅(qū)動(dòng)程序屏蔽了硬件的細(xì)節(jié),完成以下功能:對(duì)設(shè)備初始化和釋放;對(duì)設(shè)備進(jìn)行管理,包括實(shí)時(shí)參數(shù)設(shè)置,以及提供對(duì)設(shè)備的操作接口;讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù)或者回送應(yīng)用程序請(qǐng)求的數(shù)據(jù);檢測(cè)和處理設(shè)備出現(xiàn)的錯(cuò)誤。Linux操作系統(tǒng)將所有的設(shè)備全部看成文件,并通過(guò)文件的操作界面進(jìn)行操作。對(duì)用戶(hù)程序而言,設(shè)備驅(qū)動(dòng)程序隱藏了設(shè)備的具體細(xì)節(jié),對(duì)各種不同設(shè)備提供了一致的接口,一般來(lái)說(shuō),是把設(shè)備映射為一個(gè)特殊的設(shè)備文件,用戶(hù)程序可以像對(duì)其他文件一樣對(duì)此設(shè)備文件進(jìn)行操作。這意味著:由于每一個(gè)設(shè)備至少由文件系統(tǒng)的一個(gè)文件代表,因而都有一個(gè)“文件名〞。應(yīng)用程序通??梢酝ㄟ^(guò)系統(tǒng)調(diào)用open()翻開(kāi)設(shè)備文件,建立起與目標(biāo)設(shè)備的連接。翻開(kāi)了代表著目標(biāo)設(shè)備的文件,即建立起與設(shè)備的連接后,可以通過(guò)read()、write()、ioctl()等常規(guī)的文件操作對(duì)目標(biāo)設(shè)備進(jìn)行操作。設(shè)備文件的屬性由三局部信息組成:第一局部是文件的類(lèi)型,第二局部是一個(gè)主設(shè)備號(hào),第三局部是一個(gè)次設(shè)備號(hào)。其中類(lèi)型和主設(shè)備號(hào)結(jié)合在一起惟一地確定了設(shè)備文件驅(qū)動(dòng)程序及其界面,而次設(shè)備號(hào)則說(shuō)明目標(biāo)設(shè)備是同類(lèi)設(shè)備中的第幾個(gè)。由于Linux中將設(shè)備當(dāng)做文件處理,所以對(duì)設(shè)備進(jìn)行操作的調(diào)用格式與對(duì)文件的操作類(lèi)似,主要包括open()、read()、write()、ioctl()、close()等。應(yīng)用程序發(fā)出系統(tǒng)調(diào)用命令后,會(huì)從用戶(hù)態(tài)轉(zhuǎn)到核心態(tài),通過(guò)內(nèi)核將open()這樣的系統(tǒng)調(diào)用轉(zhuǎn)換成對(duì)物理設(shè)備的操作。驅(qū)動(dòng)程序結(jié)構(gòu)一個(gè)設(shè)備驅(qū)動(dòng)程序模塊的根本框架在系統(tǒng)內(nèi)部,I/O設(shè)備的存取通過(guò)一組固定的入口點(diǎn)來(lái)進(jìn)行,入口點(diǎn)也可以理解為設(shè)備的句柄,就是對(duì)設(shè)備進(jìn)行操作的根本函數(shù)。字符型設(shè)備驅(qū)動(dòng)程序提供如下幾個(gè)入口點(diǎn):open入口點(diǎn)。翻開(kāi)設(shè)備準(zhǔn)備I/O操作。對(duì)字符設(shè)備文件進(jìn)行翻開(kāi)操作,都會(huì)調(diào)用設(shè)備的open入口點(diǎn)。open子程序必須對(duì)將要進(jìn)行的I/O操作做好必要的準(zhǔn)備工作,如去除緩沖區(qū)等。如果設(shè)備是獨(dú)占的,即同一時(shí)刻只能有一個(gè)程序訪問(wèn)此設(shè)備,則open子程序必須設(shè)置一些標(biāo)志以表示設(shè)備處于忙狀態(tài)。close入口點(diǎn)。關(guān)閉一個(gè)設(shè)備。當(dāng)最后一次使用設(shè)備完成后,調(diào)用close子程序。獨(dú)占設(shè)備必須標(biāo)記設(shè)備方可再次使用。read入口點(diǎn)。從設(shè)備上讀數(shù)據(jù)。對(duì)于有緩沖區(qū)的I/O操作,一般是從緩沖區(qū)里讀數(shù)據(jù)。對(duì)字符設(shè)備文件進(jìn)行讀操作將調(diào)用read子程序。write入口點(diǎn)。往設(shè)備上寫(xiě)數(shù)據(jù)。對(duì)于有緩沖區(qū)的I/O操作,一般是把數(shù)據(jù)寫(xiě)入緩沖區(qū)里。對(duì)字符設(shè)備文件進(jìn)行寫(xiě)操作將調(diào)用write子程序。ioctl入口點(diǎn)。執(zhí)行讀、寫(xiě)之外的操作。select入口點(diǎn)。檢查設(shè)備,看數(shù)據(jù)是否可讀或設(shè)備是否可用于寫(xiě)數(shù)據(jù)。select系統(tǒng)調(diào)用在檢查與設(shè)備文件相關(guān)的文件描述符時(shí)使用select入口點(diǎn)。設(shè)備注冊(cè)和初始化設(shè)備的驅(qū)動(dòng)程序在加載的時(shí)候首先需要調(diào)用入口函數(shù)init_module(),該函數(shù)最重要的一個(gè)工作就是向內(nèi)核注冊(cè)該設(shè)備,對(duì)于字符設(shè)備調(diào)用register_chrdev()完成注冊(cè)。register_chrdev的定義為:intregister_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops);其中,major是為設(shè)備驅(qū)動(dòng)程序向系統(tǒng)申請(qǐng)的主設(shè)備號(hào),如果為0,則系統(tǒng)為此驅(qū)動(dòng)程序動(dòng)態(tài)分配一個(gè)主設(shè)備號(hào)。name是設(shè)備名,fops是對(duì)各個(gè)調(diào)用的入口點(diǎn)說(shuō)明。此函數(shù)返回0時(shí)表示成功;返回-EINVAL,表示申請(qǐng)的主設(shè)備號(hào)非法,主要原因是主設(shè)備號(hào)大于系統(tǒng)所允許的最大設(shè)備號(hào);返回-EBUSY,表示所申請(qǐng)的主設(shè)備號(hào)正在被其他設(shè)備程序使用。如果動(dòng)態(tài)分配主設(shè)備號(hào)成功,此函數(shù)將返回所分配的主設(shè)備號(hào)。如果register_chrdev()操作成功,設(shè)備名就會(huì)出現(xiàn)在/proc/dvices文件中。Linux在/dev目錄中為每個(gè)設(shè)備建立一個(gè)文件,用ls–l命令列出函數(shù)返回值,假設(shè)小于0,則表示注冊(cè)失??;返回0或者大于0的值表示注冊(cè)成功。注冊(cè)以后,Linux將設(shè)備名與主、次設(shè)備號(hào)聯(lián)系起來(lái)。當(dāng)有對(duì)此設(shè)備名的訪問(wèn)時(shí),Linux通過(guò)請(qǐng)求訪問(wèn)的設(shè)備名得到主、次設(shè)備號(hào),然后把此訪問(wèn)分發(fā)到對(duì)應(yīng)的設(shè)備驅(qū)動(dòng),設(shè)備驅(qū)動(dòng)再根據(jù)次設(shè)備號(hào)調(diào)用不同的函數(shù)。當(dāng)設(shè)備驅(qū)動(dòng)模塊從Linux內(nèi)核中卸載,對(duì)應(yīng)的主設(shè)備號(hào)必須被釋放。字符設(shè)備在cleanup_module()函數(shù)中調(diào)用unregister_chrdev()來(lái)完成設(shè)備的注銷(xiāo)。unregister_chrdev()的定義為:intunregister_chrdev(unsignedintmajor,constchar*name);包括設(shè)備注冊(cè)在內(nèi),設(shè)備驅(qū)動(dòng)的初始化函數(shù)主要完成的功能是有以下5項(xiàng)。〔1〕對(duì)驅(qū)動(dòng)程序管理的硬件進(jìn)行必要的初始化。對(duì)硬件存放器進(jìn)行設(shè)置。比方,設(shè)置中斷掩碼,設(shè)置串口的工作方式、并口的數(shù)據(jù)方向等。〔2〕初始化設(shè)備驅(qū)動(dòng)相關(guān)的參數(shù)。一般說(shuō)來(lái),每個(gè)設(shè)備都要定義一個(gè)設(shè)備變量,用以保存設(shè)備相關(guān)的參數(shù)。在這一步驟里對(duì)設(shè)備變量中的項(xiàng)進(jìn)行初始化。〔3〕在內(nèi)核注冊(cè)設(shè)備。調(diào)用register_chrdev()函數(shù)來(lái)注冊(cè)設(shè)備?!?〕注冊(cè)中斷。如果設(shè)備需要IRQ支持,則要使用request_irq()函數(shù)注冊(cè)中斷。〔5〕其他初始化工作。初始化局部一般還負(fù)責(zé)給設(shè)備驅(qū)動(dòng)程序申請(qǐng)包括內(nèi)存、時(shí)鐘、I/O端口等在內(nèi)的系統(tǒng)資源,這些資源也可以在open子程序或者其他地方申請(qǐng)。這些資源不用時(shí),應(yīng)該釋放,以利于資源的共享。假設(shè)驅(qū)動(dòng)程序是內(nèi)核的一局部,初始化函數(shù)則要按如下方式聲明:int__initchr_driver_init(void);其中__init是必不可少的,在系統(tǒng)啟動(dòng)時(shí)會(huì)由內(nèi)核調(diào)用chr_driver_init,完成驅(qū)動(dòng)程序的初始化。當(dāng)驅(qū)動(dòng)程序是以模塊的形式編寫(xiě)時(shí),則要按照如下方式聲明:intinit_module(void)當(dāng)運(yùn)行后面介紹的insmod命令插入模塊時(shí),會(huì)調(diào)用init_module函數(shù)完成初始化工作。設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā)過(guò)程由于嵌入式設(shè)備由于硬件種類(lèi)非常豐富,在默認(rèn)的內(nèi)核發(fā)布版中不一定包括所有驅(qū)動(dòng)程序。所以進(jìn)行嵌入式Linux系統(tǒng)的開(kāi)發(fā),很大的工作量是為各種設(shè)備編寫(xiě)驅(qū)動(dòng)程序。除非系統(tǒng)不使用操作系統(tǒng),程序直接操縱硬件。嵌入式Linux系統(tǒng)驅(qū)動(dòng)程序開(kāi)發(fā)與普通Linux開(kāi)發(fā)沒(méi)有區(qū)別??梢栽谟布a(chǎn)廠家或者Internet上尋找驅(qū)動(dòng)程序,也可以根據(jù)相近的硬件驅(qū)動(dòng)程序來(lái)改寫(xiě),這樣可以加快開(kāi)發(fā)速度。實(shí)現(xiàn)一個(gè)嵌入式Linux設(shè)備驅(qū)動(dòng)的大致流程如下?!?〕查看原理圖,理解設(shè)備的工作原理。一般嵌入式處理器的生產(chǎn)商提供參考電路,也可以根據(jù)需要自行設(shè)計(jì)?!?〕定義設(shè)備號(hào)。設(shè)備由一個(gè)主設(shè)備號(hào)和一個(gè)次設(shè)備號(hào)來(lái)標(biāo)識(shí)。主設(shè)備號(hào)惟一標(biāo)識(shí)了設(shè)備類(lèi)型,即設(shè)備驅(qū)動(dòng)程序類(lèi)型,它是塊設(shè)備表或字符設(shè)備表中設(shè)備表項(xiàng)的索引。次設(shè)備號(hào)僅由設(shè)備驅(qū)動(dòng)程序解釋?zhuān)瑓^(qū)分被一個(gè)設(shè)備驅(qū)動(dòng)控制下的某個(gè)獨(dú)立的設(shè)備?!?〕實(shí)現(xiàn)初始化函數(shù)。在驅(qū)動(dòng)程序中實(shí)現(xiàn)驅(qū)動(dòng)的注冊(cè)和卸載?!?〕設(shè)計(jì)所要實(shí)現(xiàn)的文件操作,定義file_operations結(jié)構(gòu)?!?〕實(shí)現(xiàn)所需的文件操作調(diào)用,如read、write等?!?〕實(shí)現(xiàn)中斷效勞,并用request_irq向內(nèi)核注冊(cè),中斷并不是每個(gè)設(shè)備驅(qū)動(dòng)所必需的。〔7〕編譯該驅(qū)動(dòng)程序到內(nèi)核中,或者用insmod命令加載模塊?!?〕測(cè)試該設(shè)備,編寫(xiě)應(yīng)用程序,對(duì)驅(qū)動(dòng)程序進(jìn)行測(cè)試。根本接口實(shí)驗(yàn)在完成了根本實(shí)驗(yàn)后,我們開(kāi)始著手根本接口實(shí)驗(yàn)。在這些實(shí)驗(yàn)中,我們學(xué)習(xí)如何編寫(xiě)設(shè)備驅(qū)動(dòng)程序,及如何用測(cè)試程序檢驗(yàn)驅(qū)動(dòng)程序是否正確,并通過(guò)改寫(xiě)測(cè)試程序正常地對(duì)驅(qū)動(dòng)程序進(jìn)行相關(guān)操作。實(shí)驗(yàn)十二 簡(jiǎn)單設(shè)備驅(qū)動(dòng)程序本次實(shí)驗(yàn)的任務(wù)是編寫(xiě)一個(gè)字符型設(shè)備驅(qū)動(dòng)程序,并學(xué)習(xí)在應(yīng)用程序中調(diào)用驅(qū)動(dòng)??紤]到我們初次接觸驅(qū)動(dòng)程序的編寫(xiě),對(duì)此還十分陌生,因此指導(dǎo)書(shū)中提供了本次實(shí)驗(yàn)所要用到的程序源代碼。雖然這樣一個(gè)字符型設(shè)備驅(qū)動(dòng)程序并沒(méi)有任何實(shí)際作用,但是它讓我們輕松掌握了嵌入式驅(qū)動(dòng)的編寫(xiě)過(guò)程,因?yàn)閺?fù)雜繁瑣的驅(qū)動(dòng),其骨架都是相同的。因此,看懂本實(shí)驗(yàn)的源代碼,學(xué)習(xí)并模仿其編寫(xiě)方法,對(duì)于后續(xù)實(shí)驗(yàn)有著非常重要的意義。實(shí)驗(yàn)十三 CPUGPIO驅(qū)動(dòng)程序設(shè)計(jì)在本實(shí)驗(yàn)中,我們要編寫(xiě)第一個(gè)針對(duì)實(shí)際硬件的驅(qū)動(dòng)程序。我們知道,但凡操作系統(tǒng)控制外部設(shè)備,即使是最簡(jiǎn)單的硬件電路,也是需要驅(qū)動(dòng)的。本實(shí)驗(yàn)涉及的外部硬件只有電阻和發(fā)光二極管。我們使用自己編寫(xiě)的驅(qū)動(dòng)程序與應(yīng)用程序控制GPIO96的電平,通過(guò)LED的亮滅來(lái)判斷,是否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,};實(shí)驗(yàn)作業(yè)要求在目標(biāo)板上LED閃爍產(chǎn)生亮7秒,滅2秒的效果在測(cè)試程序中有這樣一段代碼: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秒}實(shí)驗(yàn)十四 中斷實(shí)驗(yàn)在理論課中,我們學(xué)習(xí)了許多中斷方面的知識(shí),包括中斷向量、中斷優(yōu)先級(jí)、中斷過(guò)程等。在PXA270系統(tǒng)里,中斷控制器分外部設(shè)備和PXA270X處理器設(shè)備產(chǎn)生的兩個(gè)層次的中斷,前者是初級(jí)的中斷源,后者是次級(jí)中斷源,大量的次級(jí)中斷源通常被映射為一個(gè)初級(jí)中斷源。補(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,}; 解了硬件中斷腳與中斷的對(duì)應(yīng)關(guān)系以及中斷號(hào)與中斷處理程對(duì)應(yīng)關(guān),對(duì)于今后編寫(xiě)更為復(fù)雜的中斷程序打下根底。實(shí)驗(yàn)十五 數(shù)碼管顯示實(shí)驗(yàn)在此實(shí)驗(yàn)中,我們要編寫(xiě)針對(duì)74LV164的驅(qū)動(dòng)程序,并用其串并轉(zhuǎn)換功能來(lái)控制八段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);使用測(cè)試程序看到的測(cè)試結(jié)果是數(shù)碼管按0-9顯示輸出。實(shí)驗(yàn)作業(yè)要求在上述根底上,分別實(shí)現(xiàn)一下兩個(gè)功能:①要求您再編寫(xiě)一個(gè)測(cè)試程序,實(shí)現(xiàn)PXA270-EP目標(biāo)板上的LED數(shù)碼管循環(huán)顯示的數(shù)字9-0。②要求您再編寫(xiě)一個(gè)測(cè)試程序,實(shí)現(xiàn)PXA270-EP目標(biāo)板上的LED數(shù)碼管循環(huán)顯示的數(shù)字02468。由于在測(cè)試程序中定義了數(shù)組buf[10]分別存儲(chǔ)了0-9是個(gè)數(shù),因此上述功能的實(shí)現(xiàn)方法是,分別對(duì)測(cè)試程序做如下修改:原測(cè)試程序:while(1){ for(count=0;count<10;count++){ data[0]=buf[count];ret=write(fd,data,1);sleep(1);}}實(shí)現(xiàn)功能①:while(1){ for(count=9;count>=0;count--) //倒序顯示數(shù)字{ data[0]=buf[count];ret=write(fd,data,1);sleep(1);}}結(jié)果顯示實(shí)現(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é)果顯示通過(guò)更改顯數(shù)的順序,很容易實(shí)現(xiàn)實(shí)驗(yàn)作業(yè)里要求的功能。實(shí)驗(yàn)十六LED點(diǎn)陣驅(qū)動(dòng)程序設(shè)計(jì)通過(guò)本實(shí)驗(yàn)的操作,我們將8X8的點(diǎn)陣LED驅(qū)動(dòng)起來(lái)并通過(guò)編寫(xiě)測(cè)試程序,使其能夠按照您的意圖進(jìn)行顯示。要求您還編寫(xiě)更多的測(cè)試程序補(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ě)一個(gè)測(cè)試程序,實(shí)現(xiàn)按橫的方向隔行順序掃描LED點(diǎn)陣數(shù)碼管。②要求您再編寫(xiě)一個(gè)測(cè)試程序,實(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é)果顯示實(shí)驗(yàn)十七AD驅(qū)動(dòng)實(shí)驗(yàn)通過(guò)本實(shí)驗(yàn)的操作,我們將AD轉(zhuǎn)換器驅(qū)動(dòng)起來(lái)并通過(guò)編寫(xiě)測(cè)試程序,使其能夠?qū)⒛M信號(hào)量按照我們的要求轉(zhuǎn)換成數(shù)字信號(hào)量。為了更加清楚地理解AD轉(zhuǎn)換器的工作過(guò)程,請(qǐng)您再編寫(xiě)一個(gè)測(cè)試程序,將UCB_ADC_INP_AD0換成其他通道,來(lái)觀察其他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);}實(shí)驗(yàn)十八DA驅(qū)動(dòng)實(shí)驗(yàn)通過(guò)本實(shí)驗(yàn)的操作,我們使用示波器看到了通過(guò)DA轉(zhuǎn)換而輸出的波形。在此根底上,要求試寫(xiě)一個(gè)實(shí)現(xiàn)輸出三角波的測(cè)試程序。補(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. 本站所有資源如無(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 涵洞模板計(jì)算書(shū)
- 統(tǒng)計(jì)學(xué)原理試題及答案
- AI在智能養(yǎng)寵市場(chǎng)中的機(jī)遇與挑戰(zhàn)
- 企業(yè)員工忠誠(chéng)度與學(xué)生忠誠(chéng)度的激勵(lì)對(duì)比研究
- 人類(lèi)探索未知的故事在小學(xué)生中傳承科普文化
- 以學(xué)生為中心的創(chuàng)新教學(xué)方法在小學(xué)的應(yīng)用
- 以數(shù)據(jù)說(shuō)話量化學(xué)校優(yōu)勢(shì)的宣傳方式
- 創(chuàng)新型小學(xué)德育活動(dòng)的策劃與實(shí)施
- 從陌生到忠誠(chéng)客戶(hù)關(guān)系構(gòu)建全流程
- 電線電纜基礎(chǔ)知識(shí)培訓(xùn)
- JTG∕T F30-2014 公路水泥混凝土路面施工技術(shù)細(xì)則
- 公路工程資料整理-課件
- 交通銀行測(cè)評(píng)題庫(kù)答案大全
- 招投標(biāo)-招投標(biāo)管理
- 質(zhì)量管理與可靠性(可靠性)
- 口腔醫(yī)院器械培訓(xùn)課件
- 直腸癌患者術(shù)后護(hù)理
- 學(xué)年第一學(xué)期七年級(jí)信息科技期末測(cè)試卷附有答案
- 中考必考名著《西游記》整理+真題匯總
- 2024年專(zhuān)業(yè)技術(shù)人員繼續(xù)教育公需科目-綠色發(fā)展-節(jié)約資源和保護(hù)環(huán)境筆試歷年真題薈萃含答案
- 群眾性活動(dòng)安全管理培訓(xùn)模板
評(píng)論
0/150
提交評(píng)論