驅(qū)動(dòng)開(kāi)發(fā)實(shí)驗(yàn)指導(dǎo)書(shū)linux_第1頁(yè)
驅(qū)動(dòng)開(kāi)發(fā)實(shí)驗(yàn)指導(dǎo)書(shū)linux_第2頁(yè)
驅(qū)動(dòng)開(kāi)發(fā)實(shí)驗(yàn)指導(dǎo)書(shū)linux_第3頁(yè)
驅(qū)動(dòng)開(kāi)發(fā)實(shí)驗(yàn)指導(dǎo)書(shū)linux_第4頁(yè)
驅(qū)動(dòng)開(kāi)發(fā)實(shí)驗(yàn)指導(dǎo)書(shū)linux_第5頁(yè)
已閱讀5頁(yè),還剩200頁(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)介

目錄驅(qū)動(dòng)開(kāi)發(fā) 71Linux驅(qū)動(dòng)開(kāi)發(fā)概述 基本概念 7設(shè)備驅(qū)動(dòng)的作用 7設(shè)備驅(qū)動(dòng)的分類(lèi) 81.4Linux操作系統(tǒng)與驅(qū)動(dòng)的關(guān)系 91.5目錄驅(qū)動(dòng)開(kāi)發(fā) 71Linux驅(qū)動(dòng)開(kāi)發(fā)概述 基本概念 7設(shè)備驅(qū)動(dòng)的作用 7設(shè)備驅(qū)動(dòng)的分類(lèi) 81.4Linux操作系統(tǒng)與驅(qū)動(dòng)的關(guān)系 1.8用戶(hù)態(tài)和內(nèi)核態(tài) 10模塊機(jī)制 10編寫(xiě)設(shè)備驅(qū)動(dòng)程序需要了解的知識(shí) 11編寫(xiě)設(shè)備驅(qū)動(dòng)程序的注意事項(xiàng) 111.8.1應(yīng)用程序開(kāi)發(fā)與驅(qū)動(dòng)程序開(kāi)發(fā)的差異 122Linux的內(nèi)核模塊(module) 2.42.5實(shí)驗(yàn)?zāi)康?12實(shí)驗(yàn)內(nèi)容 12預(yù)備知識(shí) 12實(shí)驗(yàn)設(shè)備及工具 13基礎(chǔ)知識(shí) 132.6實(shí)驗(yàn)原理 ..4內(nèi)核模塊概述 13模塊機(jī)制的優(yōu)缺點(diǎn) 13內(nèi)核模塊函數(shù) 14內(nèi)核模塊編譯 142.7實(shí)驗(yàn)步驟 171、編寫(xiě)源程序代碼 172、編譯源碼 183、執(zhí)行程序 18字符設(shè)備驅(qū)動(dòng)模型 1933.1 LED驅(qū)動(dòng)開(kāi)發(fā)(IO內(nèi)存模型) 193.1.1實(shí)驗(yàn)?zāi)康?...73.1.8實(shí)驗(yàn)內(nèi)容 19預(yù)備知識(shí) 19實(shí)驗(yàn)設(shè)備及工具 20基礎(chǔ)知識(shí) 20實(shí)驗(yàn)原理...73.1.8實(shí)驗(yàn)內(nèi)容 19預(yù)備知識(shí) 19實(shí)驗(yàn)設(shè)備及工具 20基礎(chǔ)知識(shí) 20實(shí)驗(yàn)原理 21實(shí)驗(yàn)步驟 26實(shí)驗(yàn)現(xiàn)象 283.2LED驅(qū)動(dòng)開(kāi)發(fā)(老方法) 28實(shí)驗(yàn)?zāi)康?28實(shí)驗(yàn)內(nèi)容 28預(yù)備知識(shí) 28實(shí)驗(yàn)設(shè)備及工具 28基礎(chǔ)知識(shí) 29實(shí)驗(yàn)原理 30實(shí)驗(yàn)步驟 31實(shí)驗(yàn)現(xiàn)象 323.3LED驅(qū)動(dòng)開(kāi)發(fā)(新方法) 38實(shí)驗(yàn)?zāi)康?32實(shí)驗(yàn)內(nèi)容 33預(yù)備知識(shí) 33實(shí)驗(yàn)設(shè)備及工具 33基礎(chǔ)知識(shí) 33實(shí)驗(yàn)原理 34實(shí)驗(yàn)步驟 35實(shí)驗(yàn)現(xiàn)象 363.4PWM驅(qū)動(dòng)開(kāi)發(fā)(misc設(shè)備模型) 3..43.4.5實(shí)驗(yàn)?zāi)康?37實(shí)驗(yàn)內(nèi)容 37預(yù)備知識(shí) 37實(shí)驗(yàn)設(shè)備及工具 37基礎(chǔ)知識(shí) 37實(shí)驗(yàn)步驟 44實(shí)驗(yàn)結(jié)果 44按鍵中斷驅(qū)動(dòng)開(kāi)發(fā)(platform模型) 4...7實(shí)驗(yàn)?zāi)康?44實(shí)驗(yàn)內(nèi)容 45預(yù)備知識(shí)實(shí)驗(yàn)步驟 44實(shí)驗(yàn)結(jié)果 44按鍵中斷驅(qū)動(dòng)開(kāi)發(fā)(platform模型) 4...7實(shí)驗(yàn)?zāi)康?44實(shí)驗(yàn)內(nèi)容 45預(yù)備知識(shí) 45實(shí)驗(yàn)設(shè)備及工具 45基礎(chǔ)知識(shí) 45實(shí)驗(yàn)步驟 60實(shí)驗(yàn)結(jié)果 613.6IO內(nèi)存管理驅(qū)動(dòng)開(kāi)發(fā) 61是MMU? 61MMU的作用 613.6.3MMU轉(zhuǎn)換地址的61pagetable(頁(yè)表) 61的linux內(nèi)核中,頁(yè)表是如何創(chuàng)建的? 623.7LCD觸摸屏讀寫(xiě)實(shí)驗(yàn)驅(qū)動(dòng)開(kāi)發(fā)(輸模型) 6...63.7.8實(shí)驗(yàn)?zāi)康?65實(shí)驗(yàn)內(nèi)容 65預(yù)備知識(shí) 65實(shí)驗(yàn)設(shè)備及工具 65基礎(chǔ)知識(shí) 65實(shí)驗(yàn)步驟 67實(shí)驗(yàn)結(jié)果 703.8LCD顯示實(shí)驗(yàn)驅(qū)動(dòng)開(kāi)發(fā)(framebuffer模型) 70...6實(shí)驗(yàn)?zāi)康?70實(shí)驗(yàn)內(nèi)容 70預(yù)備知識(shí) 70實(shí)驗(yàn)設(shè)備及工具 70基礎(chǔ)知識(shí) 70實(shí)驗(yàn)步驟 803.8.7實(shí)驗(yàn)結(jié)果 803.9設(shè)備樹(shù) 87實(shí)驗(yàn)結(jié)果 803.9設(shè)備樹(shù) 8...63.9.7實(shí)驗(yàn)?zāi)康?81實(shí)驗(yàn)內(nèi)容 81預(yù)備知識(shí) 81實(shí)驗(yàn)設(shè)備及工具 81基礎(chǔ)知識(shí) 81實(shí)驗(yàn)步驟 100實(shí)驗(yàn)現(xiàn)象 1134塊設(shè)備 114塊設(shè)備操作 1...64.1.7實(shí)驗(yàn)?zāi)康?114實(shí)驗(yàn)內(nèi)容 114預(yù)備知識(shí) 114實(shí)驗(yàn)設(shè)備及工具 114基礎(chǔ)知識(shí) 114實(shí)驗(yàn)步驟 134塊設(shè)備驅(qū)動(dòng)總結(jié) 1355網(wǎng)絡(luò)設(shè)備 136網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)移植 1365.1wifi驅(qū)動(dòng)開(kāi)發(fā) 13...6實(shí)驗(yàn)?zāi)康?136實(shí)驗(yàn)內(nèi)容 136預(yù)備知識(shí) 136實(shí)驗(yàn)設(shè)備及工具 136基礎(chǔ)知識(shí) 137實(shí)驗(yàn)步驟 1406其他驅(qū)動(dòng) 143串口讀寫(xiě)驅(qū)動(dòng)開(kāi)發(fā) 143實(shí)驗(yàn)?zāi)康?143實(shí)驗(yàn)內(nèi)容 預(yù)備知識(shí) 143實(shí)驗(yàn)設(shè)備及工具 143基礎(chǔ)知識(shí) 1446.2USB設(shè)備加載驅(qū)動(dòng)開(kāi)發(fā) 1566.2.0USB驅(qū)動(dòng)程序概述 15..46.1.5預(yù)備知識(shí) 143實(shí)驗(yàn)設(shè)備及工具 143基礎(chǔ)知識(shí) 1446.2USB設(shè)備加載驅(qū)動(dòng)開(kāi)發(fā) 1566.2.0USB驅(qū)動(dòng)程序概述 15...76.2.8實(shí)驗(yàn)?zāi)康?156實(shí)驗(yàn)內(nèi)容 156預(yù)備知識(shí) 156實(shí)驗(yàn)設(shè)備及工具 156基礎(chǔ)知識(shí) 156實(shí)驗(yàn)原理 159實(shí)驗(yàn)步驟 1626.3繼電器驅(qū)動(dòng)開(kāi)發(fā) 16...66.3.7實(shí)驗(yàn)?zāi)康?164實(shí)驗(yàn)內(nèi)容 164預(yù)備知識(shí) 164實(shí)驗(yàn)設(shè)備及工具 164基礎(chǔ)知識(shí) 164實(shí)驗(yàn)原理 165實(shí)驗(yàn)步驟 1656.4溫濕度驅(qū)動(dòng)開(kāi)發(fā) 16...6實(shí)驗(yàn)?zāi)康?166實(shí)驗(yàn)內(nèi)容 166預(yù)備知識(shí) 166實(shí)驗(yàn)設(shè)備及工具 166基礎(chǔ)知識(shí) 166實(shí)驗(yàn)步驟 1706.5直流電機(jī)驅(qū)動(dòng)開(kāi)發(fā) 實(shí)驗(yàn)?zāi)康?178實(shí)驗(yàn)內(nèi)容 178預(yù)備知識(shí) 實(shí)驗(yàn)設(shè)備及工具 178基礎(chǔ)知識(shí) 178實(shí)驗(yàn)步驟 1826.6步進(jìn)電機(jī)驅(qū)動(dòng)開(kāi)發(fā) 18..56.6.6實(shí)驗(yàn)?zāi)康?實(shí)驗(yàn)設(shè)備及工具 178基礎(chǔ)知識(shí) 178實(shí)驗(yàn)步驟 1826.6步進(jìn)電機(jī)驅(qū)動(dòng)開(kāi)發(fā) 18..56.6.6實(shí)驗(yàn)?zāi)康?182實(shí)驗(yàn)內(nèi)容 182預(yù)備知識(shí) 182實(shí)驗(yàn)設(shè)備及工具 183基礎(chǔ)知識(shí) 1836.10.7實(shí)驗(yàn)原理 1836.6.8實(shí)驗(yàn)步驟 186氣體傳感器驅(qū)動(dòng)開(kāi)發(fā) 18..76.7.8實(shí)驗(yàn)?zāi)康?187實(shí)驗(yàn)內(nèi)容 187預(yù)備知識(shí) 187實(shí)驗(yàn)設(shè)備及工具 187基礎(chǔ)知識(shí) 187實(shí)驗(yàn)步驟 1916.8RFID驅(qū)動(dòng)開(kāi)發(fā) 實(shí)驗(yàn)?zāi)康?192實(shí)驗(yàn)內(nèi)容 192預(yù)備知識(shí) 1926.10.4實(shí)驗(yàn)設(shè)備及工具 基礎(chǔ)知識(shí) 192實(shí)驗(yàn)原理 200實(shí)驗(yàn)步驟 2056.9其它驅(qū)動(dòng)見(jiàn)粵嵌提供的驅(qū)動(dòng)文件夾 205驅(qū)動(dòng)開(kāi)發(fā)1Linux驅(qū)動(dòng)開(kāi)發(fā)概述設(shè)備驅(qū)動(dòng)程序是計(jì)算機(jī)硬件與應(yīng)用程序的接口,是軟件系統(tǒng)與硬件系統(tǒng)溝通的橋梁。如果沒(méi)有設(shè)備驅(qū)動(dòng)程序,那么硬件設(shè)備就只是一對(duì)廢鐵,沒(méi)有什么功能。1.1基本概念設(shè)備驅(qū)動(dòng)程序(DeviceDriver),簡(jiǎn)稱(chēng)驅(qū)動(dòng)程序(Driver)。它是一個(gè)計(jì)算機(jī)軟件與硬件交互的程序。這種程序建立了一個(gè)硬件與硬件,會(huì)硬件與軟件形成連接,這樣的連接是的硬件設(shè)備之間的成為可能。依據(jù)不同的計(jì)算機(jī)架構(gòu)與操作系統(tǒng)差異平臺(tái),驅(qū)動(dòng)程序可以是8位、16位(驅(qū)動(dòng)開(kāi)發(fā)1Linux驅(qū)動(dòng)開(kāi)發(fā)概述設(shè)備驅(qū)動(dòng)程序是計(jì)算機(jī)硬件與應(yīng)用程序的接口,是軟件系統(tǒng)與硬件系統(tǒng)溝通的橋梁。如果沒(méi)有設(shè)備驅(qū)動(dòng)程序,那么硬件設(shè)備就只是一對(duì)廢鐵,沒(méi)有什么功能。1.1基本概念設(shè)備驅(qū)動(dòng)程序(DeviceDriver),簡(jiǎn)稱(chēng)驅(qū)動(dòng)程序(Driver)。它是一個(gè)計(jì)算機(jī)軟件與硬件交互的程序。這種程序建立了一個(gè)硬件與硬件,會(huì)硬件與軟件形成連接,這樣的連接是的硬件設(shè)備之間的成為可能。依據(jù)不同的計(jì)算機(jī)架構(gòu)與操作系統(tǒng)差異平臺(tái),驅(qū)動(dòng)程序可以是8位、16位(16b)、32位(32b),64位(64b),這是為了windows32位64linuxwindows64位驅(qū)動(dòng)。1.2設(shè)備驅(qū)動(dòng)的作用設(shè)備驅(qū)動(dòng)程序是一種可以使計(jì)算機(jī)與設(shè)備進(jìn)行通信的特殊程序,可以說(shuō)相硬件設(shè)備的工作。假如某設(shè)備的驅(qū)動(dòng)程序未能正確安裝,是不能正常工作。正因?yàn)檫@個(gè),驅(qū)動(dòng)程序在系統(tǒng)中的地位十分重要。一般操作系統(tǒng)安裝完畢后,首要的便是安裝硬件設(shè)備的驅(qū)動(dòng)程序。、攝像頭、Modem等就需要安裝驅(qū)動(dòng)程序,另外,不同版本的操作系統(tǒng)對(duì)IDE支持也是不同的。一般情況下,版本越高所支持的硬件設(shè)備也越多。設(shè)備驅(qū)動(dòng)程序用來(lái)將硬件本身的功能高速操作系統(tǒng),完成硬件設(shè)備電子信號(hào)與操作系統(tǒng)及軟件的高級(jí)編程語(yǔ)言之間的相互翻譯。當(dāng)操作系統(tǒng)需要使用某個(gè)硬件時(shí),例如讓聲卡音樂(lè),它會(huì)先相應(yīng)指令到聲卡驅(qū)動(dòng)程序。聲卡驅(qū)動(dòng)程序接收到后,馬上將其翻譯成聲卡才能聽(tīng)懂的電子信號(hào)命令,從而讓聲卡音樂(lè)。所以簡(jiǎn)單地說(shuō),驅(qū)動(dòng)程序是提供硬件到操作系統(tǒng)的一個(gè)接口,并且協(xié)調(diào)二者之間的關(guān)系。而因?yàn)轵?qū)動(dòng)程序有如此重要的作用,所以人們都稱(chēng)“驅(qū)動(dòng)程序是硬件的”、“硬件的主宰”,同時(shí)驅(qū)動(dòng)程序也被形象地稱(chēng)為“硬件和系統(tǒng)之間的橋梁”。1.3設(shè)備驅(qū)動(dòng)的分類(lèi)計(jì)算機(jī)系統(tǒng)的主要硬件有CPU、器和外部設(shè)備組成,驅(qū)動(dòng)程序的對(duì)象一般是器和外部設(shè)備。隨著制造工藝的提高,為了節(jié)約成本,通常將嵌入到CPU內(nèi)部。所以現(xiàn)在的驅(qū)動(dòng)程序應(yīng)該支持CPU中的嵌入 大類(lèi),分別是字符設(shè)備、塊設(shè)備、網(wǎng)絡(luò)設(shè)備。1、字符設(shè)備字符設(shè)備是指那些能一個(gè)字節(jié)一個(gè)字節(jié)數(shù)據(jù)的設(shè)備,如LED卡音樂(lè)。所以簡(jiǎn)單地說(shuō),驅(qū)動(dòng)程序是提供硬件到操作系統(tǒng)的一個(gè)接口,并且協(xié)調(diào)二者之間的關(guān)系。而因?yàn)轵?qū)動(dòng)程序有如此重要的作用,所以人們都稱(chēng)“驅(qū)動(dòng)程序是硬件的”、“硬件的主宰”,同時(shí)驅(qū)動(dòng)程序也被形象地稱(chēng)為“硬件和系統(tǒng)之間的橋梁”。1.3設(shè)備驅(qū)動(dòng)的分類(lèi)計(jì)算機(jī)系統(tǒng)的主要硬件有CPU、器和外部設(shè)備組成,驅(qū)動(dòng)程序的對(duì)象一般是器和外部設(shè)備。隨著制造工藝的提高,為了節(jié)約成本,通常將嵌入到CPU內(nèi)部。所以現(xiàn)在的驅(qū)動(dòng)程序應(yīng)該支持CPU中的嵌入 大類(lèi),分別是字符設(shè)備、塊設(shè)備、網(wǎng)絡(luò)設(shè)備。1、字符設(shè)備字符設(shè)備是指那些能一個(gè)字節(jié)一個(gè)字節(jié)數(shù)據(jù)的設(shè)備,如LED燈,鍵盤(pán)、鼠標(biāo)等。字符設(shè)備一般需要在驅(qū)動(dòng)層實(shí)現(xiàn)open()、close()、read()、、ioctl()等函數(shù)。這些函數(shù)最終將被文件中的相關(guān)函數(shù)調(diào)用。內(nèi)核為字符設(shè)備對(duì)應(yīng)一個(gè)文件,如字符設(shè)備文件/dev/console。對(duì)字符設(shè)備的操作可以通過(guò)字符設(shè)備文件/dev/console來(lái)進(jìn)行。這些字符設(shè)備文件與普通文件沒(méi)有太大的差別,差別之處是字符設(shè)備一般不支持尋址,但特殊情況下,有很多字符設(shè)備也是支持尋址的。2、塊設(shè)備Linux系統(tǒng)中,進(jìn)行塊設(shè)備讀寫(xiě)時(shí),每次只能傳輸一個(gè)或多個(gè)塊。Linux可以讓?xiě)?yīng)用程序像字符設(shè)備一樣塊塊設(shè)備能完成一個(gè)字節(jié)。所以塊設(shè)備從本質(zhì)上更像一個(gè)字符設(shè)備的擴(kuò)展,的工作,例如傳輸一塊數(shù)據(jù)。Linux內(nèi)核中,與字符驅(qū)動(dòng)相比,塊設(shè)備驅(qū)動(dòng)程序具API接口。3、網(wǎng)絡(luò)設(shè)備計(jì)算機(jī)連接到互聯(lián)網(wǎng)需要一個(gè)網(wǎng)絡(luò)設(shè)備,網(wǎng)絡(luò)設(shè)備主要負(fù)責(zé)主機(jī)之間的數(shù)Linux操作系統(tǒng)中是一種非常特殊的設(shè)備,其沒(méi)有實(shí)read()、write()、ioctl()等函數(shù)。網(wǎng)絡(luò)設(shè)備實(shí)現(xiàn)了一種套接字接口,任何網(wǎng)絡(luò)數(shù)據(jù)傳輸都可以通過(guò)套接字來(lái)完成。1.4Linux操作系統(tǒng)與驅(qū)動(dòng)的關(guān)系Linux操作系統(tǒng)與設(shè)備驅(qū)動(dòng)之間的關(guān)系1.1所示。用戶(hù)空間包括應(yīng)用系統(tǒng)調(diào)用兩層。應(yīng)用程序一般依賴(lài)于庫(kù)函數(shù)庫(kù),而函數(shù)庫(kù)是調(diào)用來(lái)編寫(xiě)的,所以應(yīng)用程序間接地一倆調(diào)用。系統(tǒng)調(diào)用層是內(nèi)和空間和用戶(hù)空間的接口層。通過(guò)這個(gè)系統(tǒng)調(diào)用層,應(yīng)用程序不需要直接內(nèi)核空間的程序,增加了內(nèi)核的安。同時(shí),應(yīng)用程序也不能硬件設(shè)備,只能通過(guò)系統(tǒng)調(diào)用層來(lái)硬件設(shè)備。如果應(yīng)用程序需要硬件設(shè)備,那么應(yīng)用程序先系統(tǒng)調(diào)用層,調(diào)用層去性,也內(nèi)核層的設(shè)備驅(qū)動(dòng)程序。這樣的設(shè)的安全。計(jì),保證了各個(gè)模塊的功能Linux內(nèi)核中,包含很多實(shí)現(xiàn)具體功能的模塊。這些模塊包括文件系統(tǒng)、網(wǎng)絡(luò)協(xié)議棧、設(shè)備驅(qū)動(dòng)、內(nèi)核調(diào)度、內(nèi)存管理、進(jìn)程,都屬于系統(tǒng)內(nèi)核空間。最底層是硬件層,這一層是實(shí)際硬件設(shè)備的抽象。設(shè)備驅(qū)動(dòng)程序的功能就在沒(méi)有操作系統(tǒng)的情況下。如果只需要實(shí)現(xiàn)一些建檔的設(shè)備的操作,那么可以不適用操作系統(tǒng)。如果系統(tǒng)完成的功能比較復(fù)雜,則往往需要操作系統(tǒng)來(lái)幫忙。大多數(shù)操作系統(tǒng)都具有多任務(wù)的特性,所以對(duì)于設(shè)備驅(qū)動(dòng)read()、write()、ioctl()等函數(shù)。網(wǎng)絡(luò)設(shè)備實(shí)現(xiàn)了一種套接字接口,任何網(wǎng)絡(luò)數(shù)據(jù)傳輸都可以通過(guò)套接字來(lái)完成。1.4Linux操作系統(tǒng)與驅(qū)動(dòng)的關(guān)系Linux操作系統(tǒng)與設(shè)備驅(qū)動(dòng)之間的關(guān)系1.1所示。用戶(hù)空間包括應(yīng)用系統(tǒng)調(diào)用兩層。應(yīng)用程序一般依賴(lài)于庫(kù)函數(shù)庫(kù),而函數(shù)庫(kù)是調(diào)用來(lái)編寫(xiě)的,所以應(yīng)用程序間接地一倆調(diào)用。系統(tǒng)調(diào)用層是內(nèi)和空間和用戶(hù)空間的接口層。通過(guò)這個(gè)系統(tǒng)調(diào)用層,應(yīng)用程序不需要直接內(nèi)核空間的程序,增加了內(nèi)核的安。同時(shí),應(yīng)用程序也不能硬件設(shè)備,只能通過(guò)系統(tǒng)調(diào)用層來(lái)硬件設(shè)備。如果應(yīng)用程序需要硬件設(shè)備,那么應(yīng)用程序先系統(tǒng)調(diào)用層,調(diào)用層去性,也內(nèi)核層的設(shè)備驅(qū)動(dòng)程序。這樣的設(shè)的安全。計(jì),保證了各個(gè)模塊的功能Linux內(nèi)核中,包含很多實(shí)現(xiàn)具體功能的模塊。這些模塊包括文件系統(tǒng)、網(wǎng)絡(luò)協(xié)議棧、設(shè)備驅(qū)動(dòng)、內(nèi)核調(diào)度、內(nèi)存管理、進(jìn)程,都屬于系統(tǒng)內(nèi)核空間。最底層是硬件層,這一層是實(shí)際硬件設(shè)備的抽象。設(shè)備驅(qū)動(dòng)程序的功能就在沒(méi)有操作系統(tǒng)的情況下。如果只需要實(shí)現(xiàn)一些建檔的設(shè)備的操作,那么可以不適用操作系統(tǒng)。如果系統(tǒng)完成的功能比較復(fù)雜,則往往需要操作系統(tǒng)來(lái)幫忙。大多數(shù)操作系統(tǒng)都具有多任務(wù)的特性,所以對(duì)于設(shè)備驅(qū)動(dòng)說(shuō),應(yīng)該充分考慮并發(fā)、阻塞等問(wèn)題。1.1設(shè)備驅(qū)動(dòng)程序與操作系統(tǒng)的關(guān)系1.5用戶(hù)態(tài)和內(nèi)核態(tài)Linux操作系統(tǒng)分為用戶(hù)態(tài)和內(nèi)核態(tài)。用戶(hù)態(tài)處理器上層的軟件工作。內(nèi)交互,所以工作在內(nèi)核態(tài)。Linux操作系統(tǒng)分為兩個(gè)狀態(tài)的主要是,為應(yīng)用程序提供一個(gè)統(tǒng)一的計(jì)算機(jī)硬件抽象。工作在用戶(hù)態(tài)的應(yīng)用程序完全可以不考慮底層的硬件操作,這些操作有內(nèi)核態(tài)完成。這些內(nèi)核態(tài)程序大部分是設(shè)備驅(qū)動(dòng)程序。一個(gè)好的操作系統(tǒng)的驅(qū)動(dòng)程序?qū)τ脩?hù)態(tài)應(yīng)用程序應(yīng)該是透明的,也就是說(shuō),應(yīng)用程序可以在不了解硬件工作原理的情況下,很好地操作硬件設(shè)備,同時(shí)使硬狀態(tài)。Linux操作系統(tǒng)很好的做到了這一點(diǎn)。工作在用戶(hù)態(tài)的應(yīng)用程序不能因?yàn)橐恍╁e(cuò)誤而破壞內(nèi)核態(tài)的程序?,F(xiàn)代處理已經(jīng)充分考慮了這個(gè)問(wèn)題。處理器提供了一些指令,分為指令和驅(qū)動(dòng)指令。指令只有在內(nèi)核態(tài)下才能使用;普通指令既可以在內(nèi)核態(tài)使用,也可用戶(hù)態(tài)和內(nèi)核態(tài)是可以相互轉(zhuǎn)換的。每當(dāng)應(yīng)用程序件中斷掛起時(shí),Linux1.1設(shè)備驅(qū)動(dòng)程序與操作系統(tǒng)的關(guān)系1.5用戶(hù)態(tài)和內(nèi)核態(tài)Linux操作系統(tǒng)分為用戶(hù)態(tài)和內(nèi)核態(tài)。用戶(hù)態(tài)處理器上層的軟件工作。內(nèi)交互,所以工作在內(nèi)核態(tài)。Linux操作系統(tǒng)分為兩個(gè)狀態(tài)的主要是,為應(yīng)用程序提供一個(gè)統(tǒng)一的計(jì)算機(jī)硬件抽象。工作在用戶(hù)態(tài)的應(yīng)用程序完全可以不考慮底層的硬件操作,這些操作有內(nèi)核態(tài)完成。這些內(nèi)核態(tài)程序大部分是設(shè)備驅(qū)動(dòng)程序。一個(gè)好的操作系統(tǒng)的驅(qū)動(dòng)程序?qū)τ脩?hù)態(tài)應(yīng)用程序應(yīng)該是透明的,也就是說(shuō),應(yīng)用程序可以在不了解硬件工作原理的情況下,很好地操作硬件設(shè)備,同時(shí)使硬狀態(tài)。Linux操作系統(tǒng)很好的做到了這一點(diǎn)。工作在用戶(hù)態(tài)的應(yīng)用程序不能因?yàn)橐恍╁e(cuò)誤而破壞內(nèi)核態(tài)的程序。現(xiàn)代處理已經(jīng)充分考慮了這個(gè)問(wèn)題。處理器提供了一些指令,分為指令和驅(qū)動(dòng)指令。指令只有在內(nèi)核態(tài)下才能使用;普通指令既可以在內(nèi)核態(tài)使用,也可用戶(hù)態(tài)和內(nèi)核態(tài)是可以相互轉(zhuǎn)換的。每當(dāng)應(yīng)用程序件中斷掛起時(shí),Linux操作系統(tǒng)都會(huì)從用戶(hù)態(tài)切到內(nèi)核態(tài)。調(diào)用或者被硬調(diào)用完成或1.6模塊機(jī)制Linux一個(gè)很好的特性。這個(gè)特性使內(nèi)核可以很容易地?cái)U(kuò)大或者縮小,一方面擴(kuò)大內(nèi)核可以增加內(nèi)核的功能,另一方面縮小內(nèi)核可以減小內(nèi)核的大小。Linux內(nèi)核支持很多種模塊,驅(qū)動(dòng)程序就是其中最重要的一種,甚至人間insmodrmmod命令將一個(gè)未使用的模塊從內(nèi)核中刪除。試圖刪除一個(gè)正在使用的模塊,見(jiàn)識(shí)不的。模塊在內(nèi)核啟動(dòng)時(shí)裝載稱(chēng)為靜態(tài)裝載,在內(nèi)核已經(jīng)運(yùn)行時(shí)裝載稱(chēng)為動(dòng)態(tài)裝載。模塊可以擴(kuò)充內(nèi)核所期望的任何功能,但通常用于實(shí)現(xiàn)設(shè)備驅(qū)動(dòng)程序。一個(gè)模塊的最基本框架代碼如下:1.7編寫(xiě)設(shè)備驅(qū)動(dòng)程序需要了解的知識(shí)Linux操作系統(tǒng)有三、四百萬(wàn)行代碼,其中驅(qū)動(dòng)程序代碼就有四分之三左者需要掌握如下一些知識(shí):1、驅(qū)動(dòng)開(kāi)發(fā)應(yīng)該有良好的C語(yǔ)言基礎(chǔ),并能靈活地應(yīng)用C語(yǔ)言的結(jié)LinuxCGNUCGNU1.7編寫(xiě)設(shè)備驅(qū)動(dòng)程序需要了解的知識(shí)Linux操作系統(tǒng)有三、四百萬(wàn)行代碼,其中驅(qū)動(dòng)程序代碼就有四分之三左者需要掌握如下一些知識(shí):1、驅(qū)動(dòng)開(kāi)發(fā)應(yīng)該有良好的C語(yǔ)言基礎(chǔ),并能靈活地應(yīng)用C語(yǔ)言的結(jié)LinuxCGNUCGNUCC語(yǔ)言也應(yīng)該所了解。2、驅(qū)動(dòng)開(kāi)發(fā)應(yīng)該具有良好的硬件基礎(chǔ)。雖然不要求驅(qū)動(dòng)開(kāi)發(fā)具有設(shè)計(jì)電路的原理,但也應(yīng)該對(duì)手冊(cè)上描述的接口設(shè)備有清楚的認(rèn)識(shí)。常用、Flash、UART、IIC、USB等。3、驅(qū)動(dòng)開(kāi)發(fā) 如一些重要的數(shù)據(jù)結(jié)構(gòu)和函數(shù)等。4、驅(qū)動(dòng)開(kāi)發(fā)應(yīng)該有人文物程序設(shè)計(jì)的能力,同時(shí)驅(qū)動(dòng)中也會(huì)使用大量的自旋鎖、互斥鎖、信號(hào)量等。1.8編寫(xiě)設(shè)備驅(qū)動(dòng)程序的注意事項(xiàng)中。下面給出編寫(xiě)驅(qū)動(dòng)程序的一些注意事項(xiàng),希望引起讀者注意。#include<linux/kernel.h>#include<linux/module.h>#include<linux/init.h>intinit {/*模塊加載時(shí)的初始化工作*/return0;}voidexit _exit(void){/*模塊卸載時(shí)的銷(xiāo)毀工作*/}module_init( _init);/*指定模塊的初始化函數(shù)的宏*/module_exit( _exit);/*指定模塊的卸載函數(shù)的宏*/1.8.1應(yīng)用程序開(kāi)發(fā)與驅(qū)動(dòng)程序開(kāi)發(fā)的差異上的程序開(kāi)發(fā)一般分為兩種,一種是內(nèi)核及驅(qū)動(dòng)程序開(kāi)發(fā),另一Linux的兩種狀態(tài),分別是內(nèi)核態(tài)和層的軟件工作。驅(qū)動(dòng)程序與底層的硬件交互,所以工作在內(nèi)核態(tài)。重要的差異包括以下幾點(diǎn):1、內(nèi)核及驅(qū)動(dòng)程序開(kāi)發(fā)時(shí)不能CC庫(kù)是使用內(nèi)核中的系統(tǒng)調(diào)用來(lái)實(shí)現(xiàn)的,而且是在用戶(hù)空間實(shí)現(xiàn)的。1.8.1應(yīng)用程序開(kāi)發(fā)與驅(qū)動(dòng)程序開(kāi)發(fā)的差異上的程序開(kāi)發(fā)一般分為兩種,一種是內(nèi)核及驅(qū)動(dòng)程序開(kāi)發(fā),另一Linux的兩種狀態(tài),分別是內(nèi)核態(tài)和層的軟件工作。驅(qū)動(dòng)程序與底層的硬件交互,所以工作在內(nèi)核態(tài)。重要的差異包括以下幾點(diǎn):1、內(nèi)核及驅(qū)動(dòng)程序開(kāi)發(fā)時(shí)不能CC庫(kù)是使用內(nèi)核中的系統(tǒng)調(diào)用來(lái)實(shí)現(xiàn)的,而且是在用戶(hù)空間實(shí)現(xiàn)的。GNUCLinux操作系統(tǒng)從一開(kāi)碼做大量的修改??套⒁馔胶筒l(fā)。4、內(nèi)核只有一個(gè)很小的定長(zhǎng)堆棧。開(kāi)發(fā)時(shí)必須時(shí)5、內(nèi)核及驅(qū)動(dòng)程序開(kāi)發(fā)時(shí)缺乏像用戶(hù)空間那樣的內(nèi)存保護(hù)機(jī)制。6、內(nèi)核及驅(qū)動(dòng)程序開(kāi)發(fā)時(shí)浮點(diǎn)數(shù)很難使用,應(yīng)該使用整型數(shù)。是不兼容的。2Linux的內(nèi)核模塊(module)2.1實(shí)驗(yàn)?zāi)康牧私鈨?nèi)核模塊的概念。掌握基本的驅(qū)動(dòng)程序設(shè)計(jì)。2.2實(shí)驗(yàn)內(nèi)容文件。并調(diào)試驅(qū)動(dòng)模塊。2.3預(yù)備知識(shí)C語(yǔ)言基礎(chǔ)知識(shí)。Linux下常用vim編輯器的使用。程序調(diào)試的基礎(chǔ)知識(shí)和方法。ARM應(yīng)用程序的基本框架結(jié)構(gòu)2.4實(shí)驗(yàn)設(shè)備及工具硬件:GEC6818開(kāi)發(fā)平臺(tái)軟件:PC操作系統(tǒng)Ubuntu14.04、、arm-linu2.5基礎(chǔ)知識(shí)硬件原理:無(wú)。2.6實(shí)驗(yàn)原理2.6.1內(nèi)核模塊概述LinuxC語(yǔ)言基礎(chǔ)知識(shí)。Linux下常用vim編輯器的使用。程序調(diào)試的基礎(chǔ)知識(shí)和方法。ARM應(yīng)用程序的基本框架結(jié)構(gòu)2.4實(shí)驗(yàn)設(shè)備及工具硬件:GEC6818開(kāi)發(fā)平臺(tái)軟件:PC操作系統(tǒng)Ubuntu14.04、、arm-linu2.5基礎(chǔ)知識(shí)硬件原理:無(wú)。2.6實(shí)驗(yàn)原理2.6.1內(nèi)核模塊概述Linux內(nèi)核是整體式結(jié)構(gòu),各個(gè)子系統(tǒng)緊密,作為一個(gè)大程序在內(nèi)核空間運(yùn)行。太多的設(shè)備驅(qū)動(dòng)內(nèi)核功能集成在內(nèi)核中,內(nèi)核過(guò)于龐大。如何解決?Linux內(nèi)核引入內(nèi)核模塊制。通過(guò)動(dòng)態(tài)加載內(nèi)核模塊,使得在運(yùn)行過(guò)擴(kuò)展內(nèi)核的功能。不需要的時(shí)候。卸載該內(nèi)核模塊。什么是內(nèi)核模塊??jī)?nèi)核模塊式一種沒(méi)有經(jīng)過(guò),不能運(yùn)行的目標(biāo)文件,是在內(nèi)核空間中運(yùn)行的程序。經(jīng)過(guò)裝載到內(nèi)核里面成為內(nèi)核的一部分,可以?xún)?nèi)核的公用符)內(nèi)核模塊可以讓操作系統(tǒng)內(nèi)核在需要是載入和執(zhí)行,在不需要時(shí)由操作系統(tǒng)卸載。它們擴(kuò)展了操作系統(tǒng)訥河的功能卻不需要重新啟動(dòng)系的內(nèi)核鏡像來(lái)加入新的功能。還意味著一個(gè)臃腫的內(nèi)核。內(nèi)核模塊是如何被調(diào)入內(nèi)核工作的?當(dāng)操作系統(tǒng)內(nèi)核需要的擴(kuò)展功能不存在時(shí),內(nèi)核模塊管理守護(hù)進(jìn)程kmod執(zhí)行modprobe去加載內(nèi)核模塊。modprobe遍歷文件/lib/modules/version/modules.dep來(lái)是否有其它內(nèi)核模塊需要在該模塊加載前被加載。最后modprobe調(diào)用insmod先加載被依賴(lài)的模塊,然后加載該被內(nèi)核要求的模塊。2.6.2模塊機(jī)制的優(yōu)缺點(diǎn)模塊機(jī)制的優(yōu)點(diǎn):減小內(nèi)核映像,增加系統(tǒng)靈活性;節(jié)省開(kāi)發(fā)時(shí)間;修改內(nèi)核,不必重新編譯整個(gè)內(nèi)核。模塊的目標(biāo)代碼一旦被鏈入內(nèi)核,作用和靜態(tài)的內(nèi)核目標(biāo)代碼完全等價(jià)。模塊機(jī)制的缺點(diǎn):對(duì)系統(tǒng)性能有一定損失;使用不當(dāng)時(shí)會(huì)導(dǎo)致系統(tǒng)。2.6.3內(nèi)核模塊函數(shù)module_init(),在模塊加載到內(nèi)核時(shí)被調(diào)用。module_init()要么向內(nèi)核某個(gè)內(nèi)核函數(shù)。它可以處理的事物,要么用的代碼替代module_exit()cleanup_module(),在內(nèi)核模塊被卸載時(shí)被調(diào)用,干一些收尾module_init()做的事,保證(linux/module.h)printk(函數(shù):printk內(nèi)核中定義并且對(duì)模塊可用,為內(nèi)核提供日志功能,內(nèi)核信息或用來(lái)給出警告。與標(biāo)準(zhǔn)C模塊機(jī)制的優(yōu)點(diǎn):減小內(nèi)核映像,增加系統(tǒng)靈活性;節(jié)省開(kāi)發(fā)時(shí)間;修改內(nèi)核,不必重新編譯整個(gè)內(nèi)核。模塊的目標(biāo)代碼一旦被鏈入內(nèi)核,作用和靜態(tài)的內(nèi)核目標(biāo)代碼完全等價(jià)。模塊機(jī)制的缺點(diǎn):對(duì)系統(tǒng)性能有一定損失;使用不當(dāng)時(shí)會(huì)導(dǎo)致系統(tǒng)。2.6.3內(nèi)核模塊函數(shù)module_init(),在模塊加載到內(nèi)核時(shí)被調(diào)用。module_init()要么向內(nèi)核某個(gè)內(nèi)核函數(shù)。它可以處理的事物,要么用的代碼替代module_exit()cleanup_module(),在內(nèi)核模塊被卸載時(shí)被調(diào)用,干一些收尾module_init()做的事,保證(linux/module.h)printk(函數(shù):printk內(nèi)核中定義并且對(duì)模塊可用,為內(nèi)核提供日志功能,內(nèi)核信息或用來(lái)給出警告。與標(biāo)準(zhǔn)C庫(kù)函數(shù)printf的行為相似。每個(gè)printk()都會(huì)帶一個(gè)優(yōu)先級(jí)。內(nèi)核總共定義了八個(gè)優(yōu)先級(jí)的宏,DEFAULT_MESSAGE_LOGLEVEL/var/log/messages,可直接查看,或者用命令X-windowsinsmod一個(gè)模塊,日志信息只會(huì)件中,而不在終端打印。dmesg查在日志文2.6.4內(nèi)核模塊編譯順利編譯并且加載第一個(gè)“helloworld”模塊有時(shí)就會(huì)比較Linux。強(qiáng)烈建議的版本經(jīng)常給內(nèi)核打一些非標(biāo)準(zhǔn)的補(bǔ)丁,這種情況會(huì)導(dǎo)致一些問(wèn)題的發(fā)生。保證系統(tǒng)Documentation/Changes列出了需要的工具版本。用錯(cuò)誤的工具版本建立一個(gè)內(nèi)核(包括模塊),可能導(dǎo)致一些奇怪復(fù)雜的問(wèn)題。內(nèi)核模塊編譯:為3.4.39版本內(nèi)核構(gòu)造模塊,首先需要有配置并構(gòu)建好的3.4.39內(nèi)核源代碼樹(shù)。而且最好運(yùn)行和模塊對(duì)應(yīng)的內(nèi)核。3.4.39內(nèi)核的模塊要和內(nèi)核源代碼樹(shù)中的目標(biāo)文件連接。3.4.39kbuild,使得內(nèi)核Hello.cMakefile文件:obj-m+=hello.ohello.ohello.ko。執(zhí)行以下命令編譯模塊:建立,kbuild從該目標(biāo)文件建立內(nèi)改變目錄到用-C選項(xiàng)提供的內(nèi)核源碼目錄,在那里找到內(nèi)核的頂層makefileHello.cMakefile文件:obj-m+=hello.ohello.ohello.ko。執(zhí)行以下命令編譯模塊:建立,kbuild從該目標(biāo)文件建立內(nèi)改變目錄到用-C選項(xiàng)提供的內(nèi)核源碼目錄,在那里找到內(nèi)核的頂層makefile。M= 選項(xiàng)使makefile在試圖建立模塊目標(biāo)前,回到模塊源碼目錄。3.4.39內(nèi)核引入新的內(nèi)核模塊命名規(guī)范:內(nèi)核模塊使用.ko的文件后綴(代.o后綴),從而內(nèi)核模塊區(qū)別于普通的目標(biāo)文件。多個(gè)文件的內(nèi)核模塊:Makefile會(huì)幫我們完成編譯和連接的工作。start.cstop.c,則;Makefile這樣寫(xiě):obj-m+=startstop.ostartstop-objs:=start.ostop.o跟單個(gè)文件模塊的編譯方式一樣,內(nèi)核編譯系統(tǒng)會(huì)將所有的目標(biāo)文件連接內(nèi)核模塊是如何開(kāi)始和結(jié)束的:main()module_init()指定的函數(shù)調(diào)用開(kāi)始。這就是內(nèi)核模塊的函數(shù)。初始化函數(shù)的任務(wù),為以后內(nèi)核調(diào)用模塊函數(shù)做準(zhǔn)備。模塊的展功能。函數(shù)則在模塊別卸載之前調(diào)用,撤銷(xiāo)“初始化函數(shù)”的擴(kuò)模塊可調(diào)用的函數(shù):應(yīng)用程序可以調(diào)用它沒(méi)有定義的函數(shù)(函數(shù)庫(kù)中的函數(shù))。因?yàn)樵谶B接階。內(nèi)核模塊是連接到內(nèi)核,它能夠調(diào)用的函數(shù)和變量是內(nèi)核公開(kāi)的函數(shù)和變量,沒(méi)有庫(kù)來(lái)連接??梢栽趦?nèi)核模塊中使用的函數(shù)只能來(lái)自?xún)?nèi)核本身。make-C/usr/src/linux-`uname-r`M=$PWDmodules管理內(nèi)核模塊令lsmod列出已經(jīng)掛載的內(nèi)核模塊smod是列出目前系統(tǒng)中已加載的模塊的名稱(chēng)及大小等less/proc/modules查看模塊一樣。modinfo查看模塊信息modinfo可以查看模塊的信息,通過(guò)查看模塊信息來(lái)判定這個(gè)模塊的用途。modinfo模塊名管理內(nèi)核模塊令modprobemodprobe同時(shí)掛載。modprobe管理內(nèi)核模塊令lsmod列出已經(jīng)掛載的內(nèi)核模塊smod是列出目前系統(tǒng)中已加載的模塊的名稱(chēng)及大小等less/proc/modules查看模塊一樣。modinfo查看模塊信息modinfo可以查看模塊的信息,通過(guò)查看模塊信息來(lái)判定這個(gè)模塊的用途。modinfo模塊名管理內(nèi)核模塊令modprobemodprobe同時(shí)掛載。modprobe掛載新模塊以及新模塊相依賴(lài)的模塊模塊名,在掛載該內(nèi)核模塊的同時(shí),這個(gè)模塊所依賴(lài)的模塊也被manmodprobe。例如:modprobel是列出內(nèi)核中所有的模塊,包括已掛載和未掛載的,的模塊列表就位于/lib/modules/‘uname-r’目錄中。rmmod移除已掛載模塊用法:rmmod模塊名(不帶后綴)等同于:modprobe-r模塊名insmod掛載模塊insmod需要給出模塊所在目錄的絕對(duì)路徑,以及要帶有模塊文件名后綴(.o或.ko)insmod **.ko功能上沒(méi)有modprobe強(qiáng)。depmod創(chuàng)建模塊依賴(lài)關(guān)系的列表Linux版所用的內(nèi)核是2.6x版本,是自動(dòng)解決依賴(lài)關(guān)系。depmod-a為所有列在/etc/modprobe.conf或/etc/modules.conf 所有模塊創(chuàng)建依賴(lài)關(guān)系,并且寫(xiě)入到modules.dep文件depmod–e列出已掛載但不可用的模塊。注意事項(xiàng)使用insmod./hello.ko命令加載該模塊。/proc/modules被加載的內(nèi)核模塊。rmmodhello卸載模塊module_init()返回值非零,重新編譯再加載,觀察結(jié)果發(fā)生了什么變化?非0返回值表示初始化內(nèi)核模塊失敗,模塊不能加載。Linux2.4之后,可以為模塊的“初始化”和“卸載”函數(shù)起init_module()cleanup_module()的名字。rmmodhello卸載模塊module_init()返回值非零,重新編譯再加載,觀察結(jié)果發(fā)生了什么變化?非0返回值表示初始化內(nèi)核模塊失敗,模塊不能加載。Linux2.4之后,可以為模塊的“初始化”和“卸載”函數(shù)起init_module()cleanup_module()的名字。module_init()module_exit()linux/init.h中定義。module_init(hello_2_init);module_exit(hello_2_exit);函數(shù)必須在宏的使用前定義,否則編譯會(huì)報(bào)錯(cuò)。initexit宏init的使用會(huì)在初始化如果該模塊被編譯進(jìn)內(nèi)核,宏exit將忽略“收尾”的函數(shù)。linux/init.h定義,用來(lái)內(nèi)核占用的內(nèi)存。例如啟動(dòng)時(shí)所占用空間時(shí)的打印信息。這些函數(shù)2.7實(shí)驗(yàn)步驟1、編寫(xiě)源程序代碼#include<linux/kernel.h>#include<linux/module.h>staticintinitGEC6818_hello_module_init(void)//初始化{printk(“<0>”"Hello,GEC6818moduleisinstalled!\n");return0;}staticvoidexitGEC6818_hello_module_cleanup(void)//卸載{printk(“<0>”"Good-bye,GEC6818modulewasremoved!\n");}makefile文件2、編譯源碼hello.cmakefilemakefile文件2、編譯源碼hello.cmakefilemake命令,即可生成目標(biāo)文件hello.ko。如:在ubuntu主機(jī)的終端輸入:3、執(zhí)行程序hello.ko6818板子的/tmp/下,6818arm板子的終端輸入:mkdir/home/gec/hello_test/cd/home/gec/hello_test/makeINSTALLDIR=/home/zr/nfs/driver/dirverifneq($(KERNELRELEASE),)obj-m:=Hello.oelseKERNELDIR:=/home/zr/kernel/6818/kernel4.8/bin/arm-eabi-PWD:=$(shellpwd)default:$(MAKE)ARCH=arm PILE=$( PILE)-C$(KERNELDIR)M=$(PWD)modulesclean:rm-rf*.o*.order.*.cmd*.ko*.mod.c*.symversendifinstall:Hello.komkdir-p$(INSTALLDIR)cp--target-dir=$(INSTALLDIR)Hello.komodule_init(GEC6818_hello_module_init);module_exit(GEC6818_hello_module_cleanup);MODULE_LICENSE("GPL");注意事項(xiàng):若在向內(nèi)核加入模塊時(shí)發(fā)現(xiàn)insmod:errorinserting'hello.ko':-1Invalidmoduleformat與當(dāng)前系統(tǒng)的內(nèi)核版本是否一致。3 字符設(shè)備驅(qū)動(dòng)模型3.1 LED驅(qū)動(dòng)開(kāi)發(fā)(IO注意事項(xiàng):若在向內(nèi)核加入模塊時(shí)發(fā)現(xiàn)insmod:errorinserting'hello.ko':-1Invalidmoduleformat與當(dāng)前系統(tǒng)的內(nèi)核版本是否一致。3 字符設(shè)備驅(qū)動(dòng)模型3.1 LED驅(qū)動(dòng)開(kāi)發(fā)(IO內(nèi)存模型)3.1.1實(shí)驗(yàn)?zāi)康?、掌握基本的字符設(shè)備的驅(qū)動(dòng)程序設(shè)計(jì)。2、掌握基本的文件操作。3、掌握在操作系統(tǒng)下對(duì)普通IO端口的內(nèi)存使用方法。3.1.2實(shí)驗(yàn)內(nèi)容1S5P6818的2、編寫(xiě)LED應(yīng)用程序。Makefile文件。,熟悉GPIO端口的原理。4、并調(diào)試LED跑馬燈應(yīng)用程序。3.1.3預(yù)備知識(shí)1、C語(yǔ)言基礎(chǔ)知識(shí)。vim編輯器的使用。3、程序調(diào)試的基礎(chǔ)知識(shí)和方法。insmodhello.ko顯示:Hello,GEC6818moduleisinstalled!lsmod|grephello顯示:hello 605 0rmmodhello顯示:Good-bye,GEC6818modulewasremoved!4、ARM應(yīng)用程序的基本架構(gòu)。3.1.4實(shí)驗(yàn)設(shè)備及工具1、硬件:GEC6818開(kāi)發(fā)平臺(tái)。Ubuntu14.04、、arm-linu叉開(kāi)發(fā)環(huán)境。3.1.5基礎(chǔ)知識(shí)4、ARM應(yīng)用程序的基本架構(gòu)。3.1.4實(shí)驗(yàn)設(shè)備及工具1、硬件:GEC6818開(kāi)發(fā)平臺(tái)。Ubuntu14.04、、arm-linu叉開(kāi)發(fā)環(huán)境。3.1.5基礎(chǔ)知識(shí)1、硬件原理3-1所示:圖3-1GEC6818LED燈的GPIOE13,GPIOC17,GPIOC7GPIO管腳,讓管腳為輸出端口,實(shí)現(xiàn)亮滅。LED燈的2、寄存器原理設(shè)置輸出電平:設(shè)置為輸出模式:3.1.6實(shí)驗(yàn)原理1、IOIO端口IO內(nèi)存(統(tǒng)一編址)我們外設(shè)的地址和內(nèi)存的地址是統(tǒng)一編址的,例如:arm平臺(tái)我們?cè)O(shè)置為輸出模式:3.1.6實(shí)驗(yàn)原理1、IOIO端口IO內(nèi)存(統(tǒng)一編址)我們外設(shè)的地址和內(nèi)存的地址是統(tǒng)一編址的,例如:arm平臺(tái)我們SFR與內(nèi)存是同樣的方法。平臺(tái):如:ARM、powerpc、MIPS[root@GEC6818~]#cat/proc/iomem40000000-7fffffff:SystemRAM40008000-40a5418f:Kernelcode40a94000-40d0e407:Kerneldatac0000000-c0000fff:pl08xdmac.0c0000000-c0000fff:pl08xdmacc0001000-c0001fffc0001000-c0001fffc0019000-c00193ffc0019000-c00193ffc0030000-c00300ffc0040000-c0050fffc0040000-c0050fffc0001000-c0001fffc0001000-c0001fffc0019000-c00193ffc0019000-c00193ffc0030000-c00300ffc0040000-c0050fffc0040000-c0050fffc0053000-c00533ffc0053000-c00533ffc0060000-c0061fffc0060000-c0061fffc0062000-c0062fffc0068000-c0068fffc0069000-c0069fffc006d000-c006d040c0070000-c0070100c0071000-c0071200c0072000-c0072100c0073000-c0073100c0074000-c0074100c0075000-c0075100c0076000-c0076100c0077000-c0077100c0078000-c0079100c007a000-c007b100c007c000-c007d100c007e000-c007f100c00a0000-c00a0040c00a1000-c00a1040c00a2000-c00a2040c00a3000-c00a3040c00a5000-c00a5fffc00a5000-c00a5fffc00a6000-c00a6fffc00a6000-c00a6fff:::::::::::::::::::::::::::::::::::pl08xdmac.1pl08xdmacnxp-wdtnxp-wdtnxp-ehcidwc_otgdwc_otgnxp-adcnxp-adcstmmacethstmmacethdw_mmc.0dw_mmc.1dw_mmc.2nx Vr_GPVr_L2Vr_PMUVr_GP_MMUVr_PP0_MMUVr_PP1_MMUVr_PP2_MMUVr_PP3_MMUVr_PP0Vr_PP1Vr_PP2Vr_PP3nxnxnxnxrt.1rt.0rt.2rt.3s3c2440-i2c.1s3c2440-i2cs3c2440-i2c.2s3c2440-i2c[root@GEC6818~]#cat/proc/ioports00000000-00000020:00000000-00000020nxp-gpio.4:nxp-gpio.300000000-00000020:nxp-gpio.200000000-00000020:nxp-gpio.100000000-00000020:nxp-gpio.000000000-00000006:nxp-gpio.5[root@GEC6818~]#2、IO端口(IO編址)外設(shè)是沒(méi)有地址,外設(shè)與內(nèi)存并不在同一地址空間內(nèi),我們使用端外設(shè)。去3、在linux中,IO內(nèi)存的使用思路:驅(qū)動(dòng)安裝>申請(qǐng)IO內(nèi)存 物理地址的>得到虛擬地址>虛外設(shè)硬件解除地址3.1IO2、IO端口(IO編址)外設(shè)是沒(méi)有地址,外設(shè)與內(nèi)存并不在同一地址空間內(nèi),我們使用端外設(shè)。去3、在linux中,IO內(nèi)存的使用思路:驅(qū)動(dòng)安裝>申請(qǐng)IO內(nèi)存 物理地址的>得到虛擬地址>虛外設(shè)硬件解除地址3.1IO內(nèi)存的>IO內(nèi)存參數(shù)說(shuō)明:resource_size_tstart:IO內(nèi)存的開(kāi)始地址,該地址是一個(gè)物理地址resource_size_tn:IO內(nèi)存constchar*name:IO內(nèi)存返回值:structresource*:的大小的名字3.2、IO內(nèi)存3.3、IO內(nèi)存(物理地址-->虛擬地址)voidiomem*ioremap(unsignedlongphys_addr,size_tsize)/*releaseapreviously resourceregion@start:resourcestartaddress@n:resourceregionsize*/voidrelease_mem_region(resource_size_tstart,resource_size_tn)/*createanewbusyresourceregion@start:resourcestartaddress@n:resourceregionsize@name:reservingcaller'sIDstring*/structresource*request_mem_region(resource_size_tstart,resource_size_tn,constchar*name)參數(shù)說(shuō)明:unsignedlongphys_addr:準(zhǔn)備的物理內(nèi)存區(qū)開(kāi)始地址size_tsize:準(zhǔn)備3.4IO內(nèi)存的物理內(nèi)存區(qū)大小。注意:在linux系統(tǒng)中,是不能直接物理地址的,只能虛擬地址。如果要物理地址,需要通過(guò)IO內(nèi)存得到該物理地址的虛擬地址,再虛擬地址。4、IO內(nèi)存參數(shù)說(shuō)明:unsignedlongphys_addr:準(zhǔn)備的物理內(nèi)存區(qū)開(kāi)始地址size_tsize:準(zhǔn)備3.4IO內(nèi)存的物理內(nèi)存區(qū)大小。注意:在linux系統(tǒng)中,是不能直接物理地址的,只能虛擬地址。如果要物理地址,需要通過(guò)IO內(nèi)存得到該物理地址的虛擬地址,再虛擬地址。4、IO內(nèi)存外設(shè)(GPIO)的方ED燈的驅(qū)動(dòng))4.1、IO內(nèi)存的申請(qǐng)GPIOE13_LED=request_mem_region(GPIOEOUT_PA,8,"LED_IO");#include<linux/module.h>#include<linux/kernel.h>#include<linux/cdev.h>#include<linux/uaccess.h>#include<linux/fs.h>#include<linux/ioport.h>#include<linux/io.h>#include<linux/ioctl.h>#defineGPIOEOUT_PA 0xC001E000 外設(shè)的物理地址#defineBUF_SIZE 256structcdevchrdev_test;dev_tndev;intTestMajor=0; 備號(hào)intTestMinor=0; //此設(shè)備號(hào)chardrv_name[]="chrtest";charkbuf[BUF_SIZE];charwbuf[BUF_SIZE];unsignedint*GPIOEOUT_VA;//0xC001E000unsignedint*GPIOEOUTENB_VA;//0xC001E004structresource*GPIOE13_LED;iounmap(volatilevoidiomem*addr)4.2、IO內(nèi)存的動(dòng)態(tài)4.3、物理地址的虛擬地址4.4、虛擬地址。進(jìn)而外設(shè)GPIOE13配置成輸出2)014.5、IO內(nèi)存的4.6、IO內(nèi)存的解除4.74.2、IO內(nèi)存的動(dòng)態(tài)4.3、物理地址的虛擬地址4.4、虛擬地址。進(jìn)而外設(shè)GPIOE13配置成輸出2)014.5、IO內(nèi)存的4.6、IO內(nèi)存的解除4.7、應(yīng)用程序設(shè)計(jì)#include<stdio.h>#include<stdlib.h>#include<unistd.h>iounmap(GPIOEOUT_PA);release_mem_region(GPIOEOUT_PA,8);staticlongtest_ioctl(structfile*file,unsignedintcmd,unsignedintargs){switch(cmd){case0:*GPIOEOUT_VA=(0<<13);printk("<0>""cmd=0,argsisnotquest\n");break;case1:*GPIOEOUT_VA=(1<<13);printk("<0>""cmd=1,argsisnotquest\n");break;default:printk("<0>""commandiserror!\n");break;}return0;}*GPIOEOUTENB_VA(113); //設(shè)置為輸出模式GPIOEOUTENB_VA=GPIOEOUT_VA+1;GPIOEOUT_VA=(unsignedint*)ioremap(GPIOEOUT_PA,8);3.1.7實(shí)驗(yàn)步驟1PC機(jī)中,創(chuàng)建兩個(gè)文件夾,分別為driver和3.1.7實(shí)驗(yàn)步驟1PC機(jī)中,創(chuàng)建兩個(gè)文件夾,分別為driver和test2PCdriverled_drv.cMakefile兩個(gè)文件#touchled_io.cMakefiel#mkdirdrivertest#include<sys/ioctl.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>intmain(void){intfd,ret;fd=open("/dev/gec_led",O_RDWR);if(fd<0){perror("open:");return-1;}while(1){ret=ioctl(fd,1,1);//LEDOFFif(ret<0){perror("ioctl:");return-1;}sleep(1);ret=ioctl(fd,0,1);//LEDOFFif(ret<0){perror("ioctl:");return-1;}sleep(1);}close(fd);return0;}3_1_led_iodriver中的文件編寫(xiě)Makefile文件。3PC機(jī)中的driver目錄的終端中,編譯文件生成led_io.ko文件4PC3_1_led_iodriver中的文件編寫(xiě)Makefile文件。3PC機(jī)中的driver目錄的終端中,編譯文件生成led_io.ko文件4PCtestled_test.cMakefile兩個(gè)文件1-led_iotest中的文件編寫(xiě)Makefile文件。5PCtest目錄的終端中,編譯文件生成led_test文件6、在arm板子的終端中加載驅(qū)動(dòng)加載驅(qū)動(dòng)之前需要先卸載led預(yù)裝的驅(qū)動(dòng)。此時(shí),我們可以在/proc/devices找到我們申請(qǐng)的主設(shè)備號(hào)和設(shè)備名命令如下:結(jié)果顯示:7、在arm板子中創(chuàng)建設(shè)備文件的節(jié)點(diǎn)命令如下:mknod/dev/gec_ledc2430命令解釋?zhuān)簃knod/dev/gec_led243chrtestcat/proc/deviceslsmod ledrmmodled ledinsmodled_io.ko //加載我們編譯的驅(qū)動(dòng)#maketouchled_iotest.cMakefile#make8、在arm板子中執(zhí)行程序3.1.8實(shí)驗(yàn)現(xiàn)象開(kāi)發(fā)板上的一個(gè)LED等在閃爍。3.2LED驅(qū)動(dòng)開(kāi)發(fā)(老方法)3.2.1實(shí)驗(yàn)?zāi)康?、掌握基本的字符設(shè)備的驅(qū)動(dòng)程序設(shè)計(jì)(老方法)。2、掌握基本的文件操作。3、掌握在操作系統(tǒng)下對(duì)普通IO端口的設(shè)計(jì)。3.2.2實(shí)驗(yàn)內(nèi)容18、在arm板子中執(zhí)行程序3.1.8實(shí)驗(yàn)現(xiàn)象開(kāi)發(fā)板上的一個(gè)LED等在閃爍。3.2LED驅(qū)動(dòng)開(kāi)發(fā)(老方法)3.2.1實(shí)驗(yàn)?zāi)康?、掌握基本的字符設(shè)備的驅(qū)動(dòng)程序設(shè)計(jì)(老方法)。2、掌握基本的文件操作。3、掌握在操作系統(tǒng)下對(duì)普通IO端口的設(shè)計(jì)。3.2.2實(shí)驗(yàn)內(nèi)容1S5P6818的2、編寫(xiě)LED應(yīng)用程序。Makefile文件。,熟悉GPIO端口的原理。4、并調(diào)試LED跑馬燈應(yīng)用程序。3.2.3預(yù)備知識(shí)1、C語(yǔ)言基礎(chǔ)知識(shí)。vim編輯器的使用。3、程序調(diào)試的基礎(chǔ)知識(shí)和方法。4、ARM應(yīng)用程序的基本架構(gòu)。3.2.4實(shí)驗(yàn)設(shè)備及工具1、硬件:GEC6818開(kāi)發(fā)平臺(tái)Ubuntu14.04、、arm-linu叉開(kāi)發(fā)環(huán)境。./led_iotestc //表示字符設(shè)備243 //剛剛我們查看到的主設(shè)備號(hào)0 2553.2.5基礎(chǔ)知識(shí)1、硬件原理3-2所示:3-2GEC6818LED燈的GPIOE13,3.2.5基礎(chǔ)知識(shí)1、硬件原理3-2所示:3-2GEC6818LED燈的GPIOE13,GPIOC17,GPIOC7GPIO管腳,讓管腳為輸出端口,實(shí)現(xiàn)亮滅。LED燈的2、寄存器原理設(shè)置輸出電平:設(shè)置為輸出模式:3.2.6實(shí)驗(yàn)原理1、 字符設(shè)備參數(shù)說(shuō)明:intmajormajor=0,系統(tǒng)會(huì)自動(dòng)分配一個(gè)主設(shè)備major!=0,靜態(tài)constchar*name主設(shè)備號(hào)。設(shè)備名稱(chēng)conststructfile_operations設(shè)置為輸出模式:3.2.6實(shí)驗(yàn)原理1、 字符設(shè)備參數(shù)說(shuō)明:intmajormajor=0,系統(tǒng)會(huì)自動(dòng)分配一個(gè)主設(shè)備major!=0,靜態(tài)constchar*name主設(shè)備號(hào)。設(shè)備名稱(chēng)conststructfile_operations*fops文件操作集。返回值:0失敗,返回一個(gè)負(fù)數(shù)的錯(cuò)誤碼將設(shè)備號(hào)申請(qǐng)、字符設(shè)備的初始化、字符設(shè)備的2、注銷(xiāo)字符設(shè)備使用一個(gè)函數(shù)實(shí)現(xiàn)。register_chrdev族函數(shù)+創(chuàng)建設(shè)備類(lèi)、文件的函數(shù):這種方法是2.4版本流行的舊方法。優(yōu)點(diǎn)是簡(jiǎn)單;缺點(diǎn)是無(wú)法4、register_chrdev族函數(shù)是形成驅(qū)動(dòng)設(shè)備的設(shè)備號(hào)。。register_chrdev的作用是申請(qǐng)并一個(gè)設(shè)備號(hào)、構(gòu)建一個(gè)字符設(shè)備體、向內(nèi)核此字符設(shè)備。majormajor參數(shù)設(shè)(這種做法比較可靠、方便)。register_chrdevstaticinlinevoidunregister_chrdev(unsignedintmajor,constchar*name)staticinlineintregister_chrdev(unsignedintmajor,constchar*name,conststructfile_operations*fops)unregister_chrdev注銷(xiāo)函數(shù),注銷(xiāo)函數(shù)需要主設(shè)備號(hào)來(lái)作為參數(shù)。unregister_chrdev函數(shù),與這里的register_chrdev對(duì)應(yīng),只不過(guò)負(fù)責(zé)的是注銷(xiāo)。udev(mdev)來(lái)創(chuàng)建一個(gè)位于/dev的設(shè)備文件。這一unregister_chrdev注銷(xiāo)函數(shù),注銷(xiāo)函數(shù)需要主設(shè)備號(hào)來(lái)作為參數(shù)。unregister_chrdev函數(shù),與這里的register_chrdev對(duì)應(yīng),只不過(guò)負(fù)責(zé)的是注銷(xiāo)。udev(mdev)來(lái)創(chuàng)建一個(gè)位于/dev的設(shè)備文件。這一APPAPI操作設(shè)備文件file_operations內(nèi)的函數(shù))class_create先實(shí)例化新建device_create正式創(chuàng)建設(shè)備文件3.2.7實(shí)驗(yàn)步驟1PC機(jī)中,創(chuàng)建兩個(gè)文件夾,分別為driver和test2PCdriverled_old.cMakefile兩個(gè)文件3_2_led_olddriver中的文件編寫(xiě)Makefile文件。3PC機(jī)中的driver目錄的終端中,編譯文件生成led_old.ko文件4PCtestled_oldtest.cMakefile兩個(gè)文件1-led_iotest中的文件編寫(xiě)Makefile文件。5PCtest目錄的終端中,編譯文件生成led_test文件6、在arm板子的終端中加載驅(qū)動(dòng)加載驅(qū)動(dòng)之前需要先卸載led預(yù)裝的驅(qū)動(dòng)。#maketouchled_oldtest.cMakefile#make#touchled_old.cMakefiel#mkdirdrivertest此時(shí),我們可以在/proc/devices找到我們申請(qǐng)的主設(shè)備號(hào)和設(shè)備名命令如下:結(jié)果顯示:7、在arm板子中創(chuàng)建設(shè)備文件的節(jié)點(diǎn)命令如下:8、在arm板子中執(zhí)行程序3.2.8實(shí)驗(yàn)現(xiàn)象開(kāi)發(fā)板上的一個(gè)LED此時(shí),我們可以在/proc/devices找到我們申請(qǐng)的主設(shè)備號(hào)和設(shè)備名命令如下:結(jié)果顯示:7、在arm板子中創(chuàng)建設(shè)備文件的節(jié)點(diǎn)命令如下:8、在arm板子中執(zhí)行程序3.2.8實(shí)驗(yàn)現(xiàn)象開(kāi)發(fā)板上的一個(gè)LED等在閃爍。3.3 LED驅(qū)動(dòng)開(kāi)發(fā)(新方法)3.3.1實(shí)驗(yàn)?zāi)康?、掌握基本的字符設(shè)備的驅(qū)動(dòng)程序設(shè)計(jì)(新方法)。2、掌握基本的文件操作。3、掌握在操作系統(tǒng)下對(duì)普通IO端口的設(shè)計(jì)。./led_oldtestmknod/dev/gec_ledc2430命令解釋?zhuān)簃knod/dev/gec_ledc //表示字符設(shè)備243 //剛剛我們查看到的主設(shè)備號(hào)0 255243chrtestcat/proc/deviceslsmod ledrmmodled ledinsmodled_old.ko //加載我們編譯的驅(qū)動(dòng)3.3.2實(shí)驗(yàn)內(nèi)容1S5P6818的2、編寫(xiě)LED應(yīng)用程序。Makefile文件。,熟悉GPIO端口的原理。4、并調(diào)試LED跑馬燈應(yīng)用程序。.2實(shí)驗(yàn)內(nèi)容1S5P6818的2、編寫(xiě)LED應(yīng)用程序。Makefile文件。,熟悉GPIO端口的原理。4、并調(diào)試LED跑馬燈應(yīng)用程序。3.3.3預(yù)備知識(shí)1、C語(yǔ)言基礎(chǔ)知識(shí)。vim編輯器的使用。3、程序調(diào)試的基礎(chǔ)知識(shí)和方法。4、ARM應(yīng)用程序的基本架構(gòu)。3.3.4實(shí)驗(yàn)設(shè)備及工具1、硬件:GEC6818開(kāi)發(fā)平臺(tái)。Ubuntu14.04、、arm-linu叉開(kāi)發(fā)環(huán)境。3.3.5基礎(chǔ)知識(shí)1、硬件原理3-3所示:圖3-3原理圖GEC6818LED燈的GPIOE13,GPIOC17,GPIOC7GPIO管腳,讓管腳為輸出端口,實(shí)現(xiàn)亮滅。LED燈的2GEC6818LED燈的GPIOE13,GPIOC17,GPIOC7GPIO管腳,讓管腳為輸出端口,實(shí)現(xiàn)亮滅。LED燈的2、寄存器原理設(shè)置輸出電平:設(shè)置為輸出模式:3.3.6實(shí)驗(yàn)原理1、register_chrdev_region族+cdev族+創(chuàng)建設(shè)備類(lèi)、文件的函數(shù):這種方法2.6版本推薦的新方法。優(yōu)點(diǎn)是可以設(shè)置主次設(shè)備號(hào);缺點(diǎn)是比較復(fù)雜。2、關(guān)于分配主次設(shè)備號(hào),register_chrdev_region是用戶(hù)自定義設(shè)備號(hào)的申(即次設(shè)備號(hào))MKDEV這個(gè)宏獲得,它可以通過(guò)主設(shè)備號(hào)和次設(shè)備號(hào)來(lái)計(jì)算設(shè)備號(hào)。其實(shí)更方便的做讓內(nèi)核給我們自動(dòng)分配一個(gè),這樣就備號(hào)之間重復(fù)。導(dǎo)致設(shè)cdev_alloccdev分配內(nèi)存。使用cdev_del時(shí)內(nèi)核會(huì)為我們自動(dòng)cdev占用的空間,而如果我們malloc的話就要了。file_operations填充進(jìn)cdev_init()的,而是手動(dòng)去填充,例如mydev_pcdevcdev_alloccdev分配內(nèi)存。使用cdev_del時(shí)內(nèi)核會(huì)為我們自動(dòng)cdev占用的空間,而如果我們malloc的話就要了。file_operations填充進(jìn)cdev_init()的,而是手動(dòng)去填充,例如mydev_pcdevownerTHIS_MODULE;mydev_pcdevops&mydev_fops;說(shuō)cdev_init()其實(shí)就相當(dāng)于上面兩句cdev_add將設(shè)備體與設(shè)備號(hào)綁定,并向內(nèi)核一個(gè)字符設(shè)備6udev(mdev)來(lái)創(chuàng)建一個(gè)位于/dev的設(shè)備文件。這一步其APIAPPAPI操作設(shè)備文件(即調(diào)用內(nèi)的函數(shù))class_create先實(shí)例化新建一個(gè)device_create正式創(chuàng)建設(shè)備文件3.3.7實(shí)驗(yàn)步驟1PC機(jī)中,創(chuàng)建兩個(gè)文件夾,分別為driver和test2PCdriverled_new.cMakefile兩個(gè)文件3_3_led_newdriver中的文件編寫(xiě)Makefile文件。3PC機(jī)中的driver目錄的終端中,編譯文件生成led_new.ko文件led_newtest.cMakefile兩個(gè)文件1-led_iotest中的文件編寫(xiě)Makefile文件。5PCtest目錄的終端中,編譯文件生成led_test文件#maketouchled_newtest.cMakefile#make#touchled_new.cMakefiel#mkdirdrivertest6、在arm板子的終端中加載驅(qū)動(dòng)加載驅(qū)動(dòng)之前需要先卸載led預(yù)裝的驅(qū)動(dòng)。此時(shí),我們可以在/proc/devices找到我們申請(qǐng)的主設(shè)備號(hào)和設(shè)備名命令如下:結(jié)果顯示:7、在arm板子中創(chuàng)建設(shè)備文件的節(jié)點(diǎn)命令如下:8、在6、在arm板子的終端中加載驅(qū)動(dòng)加載驅(qū)動(dòng)之前需要先卸載led預(yù)裝的驅(qū)動(dòng)。此時(shí),我們可以在/proc/devices找到我們申請(qǐng)的主設(shè)備號(hào)和設(shè)備名命令如下:結(jié)果顯示:7、在arm板子中創(chuàng)建設(shè)備文件的節(jié)點(diǎn)命令如下:8、在arm板子中執(zhí)行程序3.3.8實(shí)驗(yàn)現(xiàn)象開(kāi)發(fā)板上的一個(gè)LED等在閃爍。./led_newtestmknod/dev/gec_ledc2430命令解釋?zhuān)簃knod/dev/gec_ledc //表示字符設(shè)備243 //剛剛我們查看到的主設(shè)備號(hào)0 255243chrtestcat/proc/deviceslsmod ledrmmodled ledinsmodled_new.ko //加載我們編譯的驅(qū)動(dòng)3.4 PWM驅(qū)動(dòng)開(kāi)發(fā)(misc設(shè)備模型)3.4.1實(shí)驗(yàn)?zāi)康?、掌握基本的字符設(shè)備的驅(qū)動(dòng)程序設(shè)計(jì)。2、掌握基本的文件操作。3.4.2實(shí)驗(yàn)內(nèi)容1S5P68182、編寫(xiě)應(yīng)用程序。Makefile文件。,熟悉其工作原理。43.4 PWM驅(qū)動(dòng)開(kāi)發(fā)(misc設(shè)備模型)3.4.1實(shí)驗(yàn)?zāi)康?、掌握基本的字符設(shè)備的驅(qū)動(dòng)程序設(shè)計(jì)。2、掌握基本的文件操作。3.4.2實(shí)驗(yàn)內(nèi)容1S5P68182、編寫(xiě)應(yīng)用程序。Makefile文件。,熟悉其工作原理。4、并調(diào)試輸出的應(yīng)用程序。3.4.3預(yù)備知識(shí)1、C語(yǔ)言基礎(chǔ)知識(shí)。vim編輯器的使用。3、程序調(diào)試的基礎(chǔ)知識(shí)和方法。4、ARM應(yīng)用程序的基本架構(gòu)。3.4.4實(shí)驗(yàn)設(shè)備及工具硬件:GEC6818開(kāi)發(fā)平臺(tái)。軟件:PCUbuntu14.04、、arm-linu叉編譯環(huán)。3.4.5基礎(chǔ)知識(shí)1、硬件原理3-4所示:3-4PWM根據(jù)S5P6818GPIOC14。2、寄存器簡(jiǎn)介3-4PWM根據(jù)S5P6818GPIOC14。2、寄存器簡(jiǎn)介3、實(shí)驗(yàn)原理PWM輸出腳,默認(rèn)為低電平,PWMTCNTn的TCNTBnTCNTnTCMPBn的值時(shí),PWM輸PWM0時(shí),輸出又變?yōu)榈碗娖?,如此周而?fù)始。ioctl函數(shù)來(lái)設(shè)置相關(guān)寄存器PWM波形的輸出與驅(qū)動(dòng)代碼分析:(詳細(xì)代碼請(qǐng)查看附件)#include<linux/module.h>#include<linux/kernel.h>#include<linux/cdev.h>#include#include#include#include#include#include#include#include#include#include#include#include#include#include<linux/uaccess.h><linux/fs.h><linux/ioport.h><linux/miscdevice.h><linux/ioctl.h>#include#include#include#include#include#include#include#include#include#include#include#include#include#include<linux/uaccess.h><linux/fs.h><linux/ioport.h><linux/miscdevice.h><linux/ioctl.h><linux/delay.h><linux/gpio.h><cfg_type.h><linux/platform_device.h><linux/err.h><linux/io.h><linux/init.h><linux/pwm.h><linux/slab.h>#include#include#include<mach/platform.h><mach/devices.h><mach/soc.h>#defineDEVICE_NAME"pwm"#define#definePWM_IOCTL_SET_FREQ1PWM_IOCTL_STOP0#defineNS_IN_1HZ(1000000000UL)#define#defineBUZZER_PWM_ID 2BUZZER_PMW_GPIO(PAD_GPIO_C+14)staticstructpwm_device*pwm2buzzer;staticstructsemaphorelock;staticvoidpwm_set_freq(unsignedlongfreq){intperiod_ns=NS_IN_1HZ/freq;pwm_config(pwm2buzzer,period_ns/pwm_enable(pwm2buzzer);2,period_ns);}staticvoidpwm_stop(void){pwm_config(pwm2buzzer,0,NS_IN_1HZ/100);pwm_disable(pwm2buzzer);}staticintgec6818_pwm_open(structinode*inode,structfile*file){if(!down_trylock(&lock))returnelsereturn0;-EBUSY;}staticintgec6818_pwm_close(structinodepwm_disable(pwm2buzzer);}staticintgec6818_pwm_open(structinode*inode,structfile*file){if(!down_trylock(&lock))returnelsereturn0;-EBUSY;}staticintgec6818_pwm_close(structinode*inode,structfile*file){up(&lock);return0;}staticlonggec6818_pwm_ioctl(structunsignedlongarg){switch(cmd){casePWM_IOCTL_SET_FREQ:if(arg==0)return-EINVAL;pwm_set_freq(arg);break;file*filep,unsignedintcmd,casePWM_IOCTL_STOP:default:pwm_stop();break;}return0;}staticstruct.owner.open.releasefile_operationsgec6818_pwm_ops={==THIS_MODULE,gec6818_pwm_open,=gec6818_pwm_close,.unlocked_ioctl=gec6818_pwm_ioctl,};staticstructmiscdevicegec6818_misc_dev={.minor=MISC_DYNAMIC_MINOR,makefile請(qǐng)參面幾章編寫(xiě)測(cè)試代碼簡(jiǎn)析(詳細(xì)代碼請(qǐng)查看附件) intmain(intargcmakefile請(qǐng)參面幾章編寫(xiě)測(cè)試代碼簡(jiǎn)析(詳細(xì)代碼請(qǐng)查看附件) intmain(intargc,char**argv) .name=DEVICE_NAME,.fops=&gec6818_pwm_ops,};staticintinitgec6818_pwm_dev_init(void){intret;ret=gpio_request(BUZZER_PMW_GPIO,DEVICE_NAME);if(ret){printk("requestGPIO%dforpwmfailed\n",BUZZER_PMW_GPIO);returnret;}gpio_direction_output(BUZZER_PMW_GPIO,0);pwm2buzzer=pwm_request(BUZZER_PWM_ID,DEVICE_NAME);if(IS_ERR(pwm2buzzer)){printk("requestpwm%dfor%sfailed\n",BUZZER_PWM_ID,DEVICE_NAME);return-ENODEV;}pwm_stop();gpio_free(BUZZER_PMW_GPIO);same_init(&lock,1);ret=misc_register(&gec6818_misc_dev);printk(DEVICE_NAME"\tinitialized\n");returnret;}staticvoidexitgec6818_pwm_dev_exit(void){pwm_stop();misc_deregister(&gec6818_misc_dev);}module_init(gec6818_pwm_dev_init);module_exit(gec6818_pwm_dev_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("GECInc.");MODULE_DESCRIPTION("S5P6818PWMDriver");{intbuzzer_fd;unsignedlongfreq;char*endstr,*str;printf("Usage:%s{intbuzzer_fd;unsignedlongfreq;char*endstr,*str;printf("Usage:%s<on/off><freq>\n","./buzzer");if(argc==3){buzzer_fd=open("/dev/pwm",O_RDWR);if(buzzer_fd<0){perror("opendevice:");exit(1);}str=argv[2];errno=0;freq=strtol(str,&endstr,0);if((errno==ERANGE&&(freq==LONG_MAX||freq==LONG_MIN))||(errno==0)){perror("freq:");exit(EXIT_FAILURE);}if(endstr==str){fprintf(stderr,"Pleaseinputadigitsforfreq\n");exit(EXIT_FAILURE);}!=0&&freqif(!strncmp(argv[1],"on",2)){ioctl(buzzer_fd,BUZZER_IOCTL_SET_FREQ,freq);}elseif(!strncmp(argv[1],"off",3)){ioctl(buzzer_fd,BUZZER_IOCTL_STOP,freq);}else{close(buzzer_fd);exit(EXIT_FAILURE);}}elseif(argc==2){buzzer_fd=open("/dev/pwm",O_RDWR);if(buzzer_fd<0){perror("opendevice:");exit(1);}編寫(xiě)測(cè)試程序makefile文件(可參面幾章makefile文件編寫(xiě)),以下編寫(xiě)一個(gè)較為通用的makefile編寫(xiě)測(cè)試程序makefile文件(可參面幾章makefile文件編寫(xiě)),以下編寫(xiě)一個(gè)較為通用的makefile,在后面章節(jié)中讀者只需將TARGET修改為相應(yīng)的目標(biāo)文件即可INSTALLDIR=/home/zr/nfs/driver/driverifneq($(KERNELRELEASE),)obj-m:=gec6818_beep.oelseKERNELDIR:=/home/zr/kernel/6818/kernel4.8/bin/arm-eabi-PWD:=$

溫馨提示

  • 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)論