第5章:Linux-驅(qū)動(dòng)程序設(shè)計(jì)課件_第1頁
第5章:Linux-驅(qū)動(dòng)程序設(shè)計(jì)課件_第2頁
第5章:Linux-驅(qū)動(dòng)程序設(shè)計(jì)課件_第3頁
第5章:Linux-驅(qū)動(dòng)程序設(shè)計(jì)課件_第4頁
第5章:Linux-驅(qū)動(dòng)程序設(shè)計(jì)課件_第5頁
已閱讀5頁,還剩142頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

2023/7/22第5章:Linux驅(qū)動(dòng)程序設(shè)計(jì)2023/7/225.1Linux驅(qū)動(dòng)程序概述

5.2虛擬字符設(shè)備Demo驅(qū)動(dòng)程序設(shè)計(jì)

5.3A/D驅(qū)動(dòng)程序設(shè)計(jì)5.4步進(jìn)電機(jī)驅(qū)動(dòng)程序設(shè)計(jì)第5章:Linux驅(qū)動(dòng)程序設(shè)計(jì)2023/7/225.1Linux驅(qū)動(dòng)程序概述

5.2虛擬字符設(shè)備Demo驅(qū)動(dòng)程序設(shè)計(jì)

5.3A/D驅(qū)動(dòng)程序設(shè)計(jì)5.4步進(jìn)電機(jī)驅(qū)動(dòng)程序設(shè)計(jì)第5章:Linux驅(qū)動(dòng)程序設(shè)計(jì)2023/7/22Linux驅(qū)動(dòng)程序的知識(shí)結(jié)構(gòu):

1、Linux驅(qū)動(dòng)設(shè)計(jì)規(guī)范(50%)

2、內(nèi)核相關(guān)知識(shí)(25%)

3、硬件相關(guān)知識(shí)(25%)Linux驅(qū)動(dòng)程序的學(xué)習(xí)方法:理論實(shí)驗(yàn)碰到問題理論實(shí)驗(yàn)

2023/7/225.1.1設(shè)備驅(qū)動(dòng)原理5.1.2設(shè)備分類

5.1.3設(shè)備文件接口5.1.4驅(qū)動(dòng)程序的加載方法5.1.5驅(qū)動(dòng)程序的重要數(shù)據(jù)結(jié)構(gòu)5.1.6驅(qū)動(dòng)程序常用函數(shù)介紹5.1Linux驅(qū)動(dòng)程序概述

2023/7/225.1.1設(shè)備驅(qū)動(dòng)原理

2023/7/22(1)什么是驅(qū)動(dòng)程序?驅(qū)動(dòng)程序是指揮硬件工作的軟件。它是應(yīng)用程序與硬件之間的一個(gè)中層軟件層,為應(yīng)用程序屏蔽硬件的細(xì)節(jié)。2023/7/22(2)驅(qū)動(dòng)程序的功能是什么?驅(qū)動(dòng)程序的功能包括3部分:對(duì)設(shè)備初始化和釋放。檢測和處理設(shè)備出現(xiàn)的錯(cuò)誤。為應(yīng)用程序提供統(tǒng)一的接口,用于數(shù)據(jù)傳送。2023/7/22(3)驅(qū)動(dòng)程序的組成驅(qū)動(dòng)程序的組成通常包括3部分:自動(dòng)配置和初始化子程序。服務(wù)于I/O請(qǐng)求的子程序,又稱驅(qū)動(dòng)程序的上半部分。中斷服務(wù)子程序,又稱驅(qū)動(dòng)程序的下半部分。2023/7/22(4)驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別?第一:主動(dòng)與被動(dòng)的區(qū)別。應(yīng)用程序有一個(gè)main函數(shù),總是從些函數(shù)開始主動(dòng)執(zhí)行一個(gè)任務(wù),而驅(qū)動(dòng)程序安裝之后,便停止工作,并等待被應(yīng)用程序調(diào)用。第二:使用的庫函數(shù)不同。第三:程序運(yùn)行的區(qū)域不同。驅(qū)動(dòng)程序工作在內(nèi)核態(tài);應(yīng)用程序工作在用戶態(tài)。2023/7/225.1.2設(shè)備分類

2023/7/22Linux將設(shè)備分為3類:字符設(shè)備(characterdevices)(重點(diǎn))塊設(shè)備(blockdevices)網(wǎng)絡(luò)設(shè)備(networkdevices)2023/7/221、應(yīng)用程序?qū)Σ煌愋驮O(shè)備的操作有一些差別2023/7/222、字符設(shè)備

字符設(shè)備是指數(shù)據(jù)處理以字節(jié)為單位,并按順序進(jìn)行訪問的設(shè)備。

如:簡單按鍵、觸摸屏、AD轉(zhuǎn)換。2023/7/22初始化字符設(shè)備時(shí),字符設(shè)備驅(qū)動(dòng)程序向Linux登記,并在字符設(shè)備向量表chrdevs中增加一個(gè)device_struct數(shù)據(jù)結(jié)構(gòu)條目,這個(gè)設(shè)備的主設(shè)備號(hào)用做這個(gè)向量表的索引,即chrdevs[]數(shù)組的下標(biāo)值就是主設(shè)備號(hào)2023/7/223、塊設(shè)備塊設(shè)備是指在輸入/輸出時(shí)數(shù)據(jù)處理以塊為單位的設(shè)備,它一般都采用緩存技術(shù),支持?jǐn)?shù)據(jù)的隨機(jī)讀寫。

典型的塊設(shè)備有:硬盤、U盤、內(nèi)存、Flash、CD-ROM等2023/7/22在大部分Unix系統(tǒng),塊設(shè)備不能按字節(jié)處理數(shù)據(jù),只能一次傳送一個(gè)或多個(gè)長度是512字節(jié)(或一個(gè)更大的2次冪的數(shù))的整塊數(shù)據(jù)??梢噪S機(jī)訪問。而Linux允許塊設(shè)備一次傳送任意數(shù)目的字節(jié)。2023/7/22Linux用blkdevs向量表維護(hù)已經(jīng)登記的塊設(shè)備文件。它像chrdevs向量表一樣,使用設(shè)備的主設(shè)備號(hào)作為索引。2023/7/22塊設(shè)備又分若干種類型,例如:SCSI類和IDE類。類向Linux內(nèi)核登記并向內(nèi)核提供文件操作。一種塊設(shè)備類的設(shè)備驅(qū)動(dòng)程序向這種類提供和類相關(guān)的接口。例如,SCSI設(shè)備驅(qū)動(dòng)程序必須向SCSI子系統(tǒng)提供接口,讓SCSI子系統(tǒng)來對(duì)內(nèi)核提供這種設(shè)備的文件操作。2023/7/22字符設(shè)備和塊設(shè)備的區(qū)別?最小訪問單元不同。訪問方式不同(順序、隨機(jī))。2023/7/224、網(wǎng)絡(luò)接口設(shè)備網(wǎng)絡(luò)設(shè)備,又稱網(wǎng)絡(luò)接口(networkinterfaces),用于網(wǎng)絡(luò)通信。通常它們指的是硬件設(shè)備,但有時(shí)也可以是一個(gè)純軟件設(shè)備(如回環(huán)接口loopback)。網(wǎng)絡(luò)接口由內(nèi)核中網(wǎng)絡(luò)子系統(tǒng)驅(qū)動(dòng),負(fù)責(zé)發(fā)送和接收數(shù)據(jù)包,而且它并不需要了解每一項(xiàng)事務(wù)是如何映射到實(shí)際傳送的數(shù)據(jù)包。2023/7/22它們的數(shù)據(jù)傳送往往不是面向數(shù)據(jù)流(少數(shù)是,如telnet和FTP是面向數(shù)據(jù)流),所以不容易把它們映射到一個(gè)文件系統(tǒng)的節(jié)點(diǎn)上。在Linux中,采用給網(wǎng)絡(luò)接口設(shè)備分配一個(gè)唯一的名字的方法來訪問該設(shè)備。如:eth0eth1lo2023/7/225、設(shè)備號(hào)在傳統(tǒng)方式的設(shè)備管理中,除了設(shè)備類型以外,內(nèi)核還需要一對(duì)參數(shù)才能唯一標(biāo)識(shí)設(shè)備,這對(duì)參數(shù)就是主設(shè)備號(hào)(majornumber)和次設(shè)備號(hào)(minornumber)。2023/7/22(1)什么是設(shè)備號(hào)?

設(shè)備號(hào)用于區(qū)分具體的設(shè)備。設(shè)備號(hào)包括主設(shè)備號(hào)(majornumber)和次設(shè)備號(hào)(minornumber)。

標(biāo)識(shí)設(shè)備要作用3個(gè)參數(shù):設(shè)備類型主設(shè)備號(hào)次設(shè)備號(hào)2023/7/22

主設(shè)備號(hào)用于標(biāo)識(shí)設(shè)備對(duì)應(yīng)的驅(qū)動(dòng)程序,主設(shè)備號(hào)相同的設(shè)備使用相同的設(shè)備驅(qū)動(dòng)程序。(主設(shè)備號(hào)用于區(qū)分設(shè)備的類型)

次設(shè)備號(hào)是用來區(qū)分具體設(shè)備的實(shí)例(次設(shè)備號(hào)用于區(qū)分同類型的設(shè)備)。crw-------1rootroot5,64Jan100:00cua0crw-------1rootroot5,65Jan100:00cua1crw-------1rootroot4,64Jan100:11ttyS0crw-------1rootroot4,65Jan100:00ttyS12023/7/22

設(shè)備文件、主設(shè)備號(hào)和驅(qū)動(dòng)程序之間的關(guān)系?

2023/7/22應(yīng)用程序如何使用設(shè)備文件?設(shè)備文件與驅(qū)動(dòng)程序如何建立聯(lián)系?2023/7/22使用文件名主設(shè)備號(hào)2023/7/22應(yīng)用程序fd=open(“/dev/ad_0”,O_RDWR)ad_0設(shè)備文件C600(1)安裝驅(qū)動(dòng),注冊(cè)主設(shè)備號(hào)(2)創(chuàng)建設(shè)備文件,指向該設(shè)備類型,及主次設(shè)備號(hào)。(3)應(yīng)用程序,調(diào)用設(shè)備文件。2023/7/22

有靜態(tài)申請(qǐng)和動(dòng)態(tài)申請(qǐng)2種方法。(2)Linux內(nèi)核如何給設(shè)備分配主設(shè)備號(hào)?2023/7/22(1)查找沒有使用的主設(shè)備號(hào)(cat/proc/devices)(2)在驅(qū)動(dòng)程序中,使用register_chrdev函數(shù)向內(nèi)核注冊(cè)主設(shè)備號(hào)。靜態(tài)申請(qǐng)分配主設(shè)備號(hào)(由人工分配)優(yōu)點(diǎn):簡單缺點(diǎn):如果驅(qū)動(dòng)程序被廣泛使用,有可能導(dǎo)致設(shè)備號(hào)沖突。(1)在驅(qū)動(dòng)程序中,使用alloc_chrdev_region函數(shù)向內(nèi)核申請(qǐng)動(dòng)態(tài)分配,并注冊(cè)主設(shè)備號(hào)。動(dòng)態(tài)申請(qǐng)分配主設(shè)備號(hào)(由內(nèi)核分配)優(yōu)點(diǎn):方便驅(qū)動(dòng)程序推廣。缺點(diǎn):無法在安裝驅(qū)動(dòng)程序之前創(chuàng)建設(shè)備文件(因?yàn)榘惭b之前還沒有分配主設(shè)備號(hào))。解決辦法:安裝后,使用命令cat/proc/devices查看分配到的設(shè)備號(hào)2023/7/22設(shè)備類型的表示方法:字符設(shè)備用C表示塊設(shè)備用B表示網(wǎng)絡(luò)設(shè)備沒有2023/7/22

主設(shè)備號(hào)用于標(biāo)識(shí)設(shè)備對(duì)應(yīng)的驅(qū)動(dòng)程序,主設(shè)備號(hào)相同的設(shè)備使用相同的設(shè)備驅(qū)動(dòng)程序。一個(gè)主設(shè)備號(hào)可能有多個(gè)設(shè)備與之對(duì)應(yīng),這些設(shè)備在驅(qū)動(dòng)程序內(nèi)通過次設(shè)備號(hào)來進(jìn)一步區(qū)分。

例如,軟驅(qū)的主設(shè)備號(hào)是2,

IDE硬盤的主設(shè)備號(hào)是3,

并口的主設(shè)備號(hào)是62023/7/22次設(shè)備號(hào)是用來區(qū)分具體設(shè)備的實(shí)例(instance)。例如:如果一臺(tái)計(jì)算機(jī)上配有2個(gè)軟驅(qū),則2個(gè)軟驅(qū)的主設(shè)備號(hào)都是2,但次設(shè)備號(hào)不同,

第一個(gè)軟驅(qū)的次設(shè)備號(hào)為0,

第二個(gè)軟驅(qū)的次設(shè)備號(hào)為1。2023/7/22#cat/proc/devicesCharacterdevices:1mem2pty3ttyp4ttyS…..Blockdevices:1ramdisk2fd3sd……2023/7/226、設(shè)備文件設(shè)備類型、主設(shè)備號(hào)、次設(shè)備號(hào)是內(nèi)核與驅(qū)動(dòng)程序通信時(shí)所使用的,但是對(duì)于開發(fā)應(yīng)用程序的用戶來說難于理解和記憶,所以Linux使用了設(shè)備文件的概念來統(tǒng)一對(duì)設(shè)備的訪問接口。2023/7/222023/7/22

Linux應(yīng)用程序是通過設(shè)備文件(又名:設(shè)備節(jié)點(diǎn))來使用驅(qū)動(dòng)程序操作字符設(shè)備和塊設(shè)備。2023/7/22/dev目錄是用于存放設(shè)備文件的crw-------1rootroot5,64Jan100:00cua0crw-------1rootroot5,65Jan100:00cua1crw-------1rootroot4,64Jan100:11ttyS0crw-------1rootroot4,65Jan100:00ttyS1字符設(shè)備用c表示;塊設(shè)備用b表示2023/7/22設(shè)備文件的命名方法設(shè)備文件有時(shí)也稱為設(shè)備節(jié)點(diǎn),一般存放在/dev目錄下。正常情況下,/dev目錄下的每一個(gè)設(shè)備文件對(duì)應(yīng)一個(gè)設(shè)備(包括虛擬設(shè)備),設(shè)備文件的命名一般為“設(shè)備名+數(shù)字或字母”,其中,數(shù)字或字母用于表示設(shè)備的子類,例如:/dev/hda1、/dev/hda2分別表示第一個(gè)IDE硬盤的第一個(gè)分區(qū)和第二個(gè)分區(qū)。2023/7/22設(shè)備文件新命令方法

Linux-2.4版本內(nèi)核中引入了設(shè)備文件系統(tǒng),所有的設(shè)備文件作為一個(gè)可以掛裝的文件,這樣就可以被文件系統(tǒng)進(jìn)行統(tǒng)一管理,從而設(shè)備文件就可以掛裝到任何需要的地方。設(shè)備文件命名規(guī)則也發(fā)生了變化,一般將主設(shè)備建立一個(gè)目錄,再將具體的子設(shè)備文件建立在此目錄下。例如:UP-NETARM2410-S中的

MTD設(shè)備文件保存在/dev/mtdblock目錄下,該目錄有2個(gè)設(shè)備文件0和1。2023/7/22設(shè)備文件的創(chuàng)建方法設(shè)備文件的創(chuàng)建方式有2種,即自動(dòng)創(chuàng)建和手動(dòng)創(chuàng)建。2023/7/22ad_0設(shè)備文件C600(1)手工創(chuàng)建(mknod)(2)自動(dòng)創(chuàng)建(安裝驅(qū)動(dòng)程序時(shí))2023/7/22(1)手動(dòng)創(chuàng)建mknod的語法如下:#mknodnametypemajorminor例如:創(chuàng)建一個(gè)字符設(shè)備文件,主設(shè)備號(hào)是100,次設(shè)備號(hào)是0,設(shè)備文件名是/dev/demo,則創(chuàng)建的命令如下:#mknod/dev/demoC10002023/7/22(2)自動(dòng)創(chuàng)建是指在驅(qū)動(dòng)程序中,通過函數(shù)調(diào)用,在安裝驅(qū)動(dòng)程序時(shí),自動(dòng)創(chuàng)建設(shè)設(shè)備文件。

2023/7/225.1.3設(shè)備文件接口

2023/7/22Linux應(yīng)用程序可以通過設(shè)備文件的一組固定的入口點(diǎn)來訪問驅(qū)動(dòng)程序,這組入口點(diǎn)是由每個(gè)設(shè)備的設(shè)備驅(qū)動(dòng)程序提供的。2023/7/22[程序5.1]編寫應(yīng)用程序?qū)崿F(xiàn)向串口發(fā)送字符串“ATD2109992”。intmain(){intfd,n;charbuf[MAX]="ATD2109992";fd=open("/dev/ttyS0",O_RDWR);//open入口點(diǎn),ttyS0是設(shè)備文件

if(fd<0){perror("Unableopen/dev/ttyS0\n"); return1;}n=write(fd,buf,strlen(buf));//write入口點(diǎn)if(n<0) printf("write()of%dbytesfailed!\n",strlen(buf));else printf("write()of%dbytesok!\n",strlen(buf));close(fd);

//close入口點(diǎn)

}[程序5.2]直流電機(jī)控制程序intmain(intargc,char**argv){inti=0,status=1,setpwm=0,factor=DCM_TCNTB0/1024;if((dcm_fd=open(=“/dev/dcm/0raw”,O_WRONLY))<0){

printf(“Erroropening%sdevice\n”,DCM_DEV);

return1;}for(;;){for(i=-512;i<=512;i++){

if(status==1)

setpwm=i;

else

setpwm=-i;

ioctl(dcm_fd,DCM_IOCTRL_SETPWM,(setpwm*factor));

Delay(500);

printf(“setpwm=%d\n”,setpwm);

}

status=-status;

}

close(dcm_fd);

return0;}常用入口點(diǎn)函數(shù)intopen(char*filename,intaccess);intclose(inthandle);intread(inthandle,void*buf,intcount);intwrite(inthandle,void*buf,intcount);intioctl(intfd,intcmd,…);intioctl(intfd,intcmd,char*argp);2023/7/225.1.4驅(qū)動(dòng)程序的加載方法

2023/7/22Linux驅(qū)動(dòng)程序的安裝有2種方式:直接編譯進(jìn)內(nèi)核,又稱靜態(tài)連接。模塊方式,又稱動(dòng)態(tài)連接。

2023/7/22設(shè)備驅(qū)動(dòng)模塊化編程一般分為加載、系統(tǒng)調(diào)用和卸載等3個(gè)過程2023/7/22①lsmod命令功能:列出當(dāng)前動(dòng)態(tài)加載的模塊清單。例:#lsmodModuleSizeUsedbyov511671400(unused)videodev58240[ov511]

//被ov511模塊使用motor16081

//被一個(gè)應(yīng)用程序使用ad17120(unus注:模塊是指設(shè)備驅(qū)動(dòng)程序名如:驅(qū)動(dòng)程序motor.o,安裝后的模塊名是:motor2023/7/22②insmod功能:將驅(qū)動(dòng)模塊加載到操作系統(tǒng)內(nèi)核例:將數(shù)碼管驅(qū)動(dòng)程序(tube.o)加載到內(nèi)核。#insmodtube.oUsingtube.oWarning:loadingtubewilltaintsthekernel:no3icenseSeehctp://www.tux.or2/lkml/#export-t4intedforinfor1ationabouttaintedmodules0-numerictube:Dprintkdeviceopens3c2410-hc595initialized#2023/7/22#lsmodModuleSizeUsedbytube20720(unused)ov511671400(unused)videodev58240[ov511]motor16081ad17120(unused)#2023/7/22③rmmod功能:將驅(qū)動(dòng)模塊從內(nèi)核中刪除例:請(qǐng)將上一例子中的tube模塊刪除了。#rmmodtubes3c2410-hc595unloaded#以上顯示是刪除過程的提示信息。2023/7/225.1.5設(shè)備驅(qū)動(dòng)的重要數(shù)據(jù)結(jié)構(gòu)

2023/7/22

在Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)中,有3個(gè)非常重要的數(shù)據(jù)結(jié)構(gòu):structfilestructinodestructfile_operations設(shè)備驅(qū)動(dòng)的重要數(shù)據(jù)結(jié)構(gòu)2023/7/22

代表一個(gè)打開的文件。系統(tǒng)中每個(gè)打開的文件在內(nèi)核空間都有一個(gè)關(guān)聯(lián)的structfile。它由內(nèi)核在打開文件時(shí)創(chuàng)建,在文件關(guān)閉后釋放。重要成員loff_t_pos/*文件讀寫位置*/structfile_operations*f_op(1)structfile2023/7/22

用來記錄文件的物理上的信息。一個(gè)文件可以對(duì)應(yīng)多個(gè)file結(jié)構(gòu),但只有一個(gè)inode結(jié)構(gòu)。重要成員dev_ti_rdev:設(shè)備號(hào)(2)structinode2023/7/22

一個(gè)函數(shù)指針的集合,定義能在設(shè)備上進(jìn)行的操作。結(jié)構(gòu)中的成員指向驅(qū)動(dòng)中的函數(shù),這些函數(shù)實(shí)現(xiàn)一個(gè)特另的操作,對(duì)于不支持的操作保留為NULL。(3)structfile_operations2023/7/22structfile_operations{ structmodule*owner; loff_t(*llseek)(structfile*,loff_t,int); ssize_t(*read)(structfile*,char*,size_t,loff_t*); ssize_t(*write)(structfile*,constchar*,size_t,loff_t*); int(*readdir)(structfile*,void*,filldir_t); unsignedint(*poll)(structfile*,structpoll_table_struct*); int(*ioctl)(structinode*,structfile*,unsignedint,unsignedlong); int(*mmap)(structfile*,structvm_area_struct*); int(*open)(structinode*,structfile*); int(*flush)(structfile*); int(*release)(structinode*,structfile*); int(*fsync)(structfile*,structdentry*,intdatasync); int(*fasync)(int,structfile*,int); int(*lock)(structfile*,int,structfile_lock*);… };2023/7/22目前對(duì)此結(jié)構(gòu)體采用“標(biāo)記化”方法進(jìn)行賦值,下面是對(duì)此結(jié)構(gòu)體變量s3c44b0_fops用“標(biāo)記化”方法進(jìn)行賦值的實(shí)例。staticstructfile_operationss3c440_fops={ owner:THIS_MODULE,

open:s3c2410_ts_open,

read:s3c2410_ts_read,

write:s3c2410_ts_write,

release:s3c2410_ts_release,};2023/7/225.1.6驅(qū)動(dòng)程序常用函數(shù)

2023/7/221.字符設(shè)備注冊(cè)及注銷函數(shù)字符設(shè)備驅(qū)動(dòng)程序可通過register_chrdev函數(shù)向內(nèi)核注冊(cè)設(shè)備,又可通過unregister_chrdev函數(shù)向內(nèi)核注銷設(shè)備。intregister_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops);voidunregister_chrdev(unsignedintmajor,constchar*name);2023/7/222.中斷申請(qǐng)和釋放函數(shù)設(shè)備驅(qū)動(dòng)程序可通過request_irq函數(shù)向內(nèi)核申請(qǐng)中斷,又可通過free_irq函數(shù)釋放中斷。它們的定義如下:intrequest_irq(unsignedintirq, void(*handler)(int,void*,structpt_regs*), unsignedlongflags,

constchar*dev_name,

void*dev_id);voidfree_irq(unsignedint

irq,void*dev_id);3.阻塞型I/O操作函數(shù)當(dāng)對(duì)設(shè)備進(jìn)行read和write操作時(shí),如果驅(qū)動(dòng)程序無法立刻滿足請(qǐng)求時(shí),應(yīng)當(dāng)如何響應(yīng)?驅(qū)動(dòng)程序應(yīng)當(dāng)(缺省地)阻塞進(jìn)程,使它進(jìn)入睡眠直到請(qǐng)求可繼續(xù),即阻塞型I/O操作。可以通過調(diào)用以下函數(shù)讓進(jìn)程進(jìn)入睡眠狀態(tài)。voidsleep_on(structwait_queue**q);voidinterrutible_sleep_on(structwait_queue**q);又可以通過調(diào)用以下函數(shù)喚醒進(jìn)程。voidwake_up(structwait_queue**q);voidwake_up_interrutible(structwait_queue**q);4.并發(fā)處理函數(shù)在編寫驅(qū)動(dòng)程序時(shí),需要考慮進(jìn)程并發(fā)處理。當(dāng)一個(gè)進(jìn)程請(qǐng)求內(nèi)核驅(qū)動(dòng)程序模塊服務(wù)時(shí),如果此時(shí)內(nèi)核模塊正忙,則可以將進(jìn)程放入睡眠狀態(tài)直到驅(qū)動(dòng)程序模塊空閑??梢酝ㄟ^調(diào)用以下函數(shù)完成并發(fā)處理。voidup(structsemaphore*sem);voiddown(structsemaphore*sem);intdown_interruptible(structsemaphore*sem);5.內(nèi)核空間和用戶空間的數(shù)據(jù)傳遞函數(shù)Linux運(yùn)行在兩種模式下:內(nèi)核模式和用戶模式,又叫內(nèi)核態(tài)和用戶態(tài)。內(nèi)核模式對(duì)應(yīng)于內(nèi)核空間,用戶模式對(duì)應(yīng)于用戶空間。unsignedlongcopy_to_user(void*to,constvoid*from,unsignedlongcount);unsignedlongcopy_from_user(void*to,constvoid*from,unsignedlongcount);6.設(shè)備文件自動(dòng)創(chuàng)建函數(shù)可通過devfs_register函數(shù)完成設(shè)備的注冊(cè),以及設(shè)備文件的自動(dòng)創(chuàng)建。函數(shù)的定義如下:devfs_register(devfs_handle_tdir,constchar*name,unsignedintflags,unsignedintmajor,unsignedintminor,umode_tmode,void*ops,void*info);2023/7/22小結(jié):1、Linux系統(tǒng)將設(shè)備分3類。字符、塊和網(wǎng)絡(luò)。2、驅(qū)動(dòng)程序的安裝分2種方式。模塊和直接編譯到內(nèi)核。3、驅(qū)動(dòng)程序的使用。字符設(shè)備和塊設(shè)備是通過設(shè)備文件來使用驅(qū)動(dòng)程序;網(wǎng)絡(luò)設(shè)備是通過套接字來使用網(wǎng)絡(luò)驅(qū)動(dòng)程序的。2023/7/225.1Linux驅(qū)動(dòng)程序概述

5.2虛擬字符設(shè)備Demo驅(qū)動(dòng)程序設(shè)計(jì)

5.3A/D驅(qū)動(dòng)程序設(shè)計(jì)5.4步進(jìn)電機(jī)驅(qū)動(dòng)程序設(shè)計(jì)第5章:Linux驅(qū)動(dòng)程序設(shè)計(jì)2023/7/225.1Linux驅(qū)動(dòng)程序概述

5.2虛擬字符設(shè)備Demo驅(qū)動(dòng)程序設(shè)計(jì)

5.3A/D驅(qū)動(dòng)程序設(shè)計(jì)5.4步進(jìn)電機(jī)驅(qū)動(dòng)程序設(shè)計(jì)第5章:Linux驅(qū)動(dòng)程序設(shè)計(jì)2023/7/225.1Linux驅(qū)動(dòng)程序概述

5.2虛擬字符設(shè)備Demo驅(qū)動(dòng)程序設(shè)計(jì)

5.3A/D驅(qū)動(dòng)程序設(shè)計(jì)5.4步進(jìn)電機(jī)驅(qū)動(dòng)程序設(shè)計(jì)第5章:Linux驅(qū)動(dòng)程序設(shè)計(jì)2023/7/22驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別?2023/7/22一、DEMO介紹1、Demo字符設(shè)備簡介設(shè)有一個(gè)簡單的虛擬字符設(shè)備Demo,該設(shè)備只在內(nèi)核空間開辟一個(gè)40個(gè)字節(jié)的緩沖區(qū)(drv_buf)。要求為該設(shè)備設(shè)計(jì)一個(gè)驅(qū)動(dòng)程序,它能夠?yàn)閼?yīng)用程序提供讀、寫兩種操作。2023/7/222、Demo驅(qū)動(dòng)程序的功能說明如下:(1)將驅(qū)動(dòng)程序編譯成模塊,以模塊方式動(dòng)態(tài)加載。(2)模塊加載時(shí),完成設(shè)備的注冊(cè)。設(shè)備名為demo,主設(shè)備號(hào)為249,次設(shè)備號(hào)為0。(3)打開設(shè)備時(shí),完成對(duì)緩沖區(qū)的初始化。(4)讀操作時(shí),將內(nèi)核緩沖區(qū)中的數(shù)據(jù)讀出。(5)寫操作時(shí),將數(shù)據(jù)寫入內(nèi)核緩沖區(qū)。(5)模塊卸載時(shí),完成設(shè)備的注銷。2023/7/223、Demo設(shè)備驅(qū)動(dòng)程序的結(jié)構(gòu)(動(dòng)畫)2023/7/224、驅(qū)動(dòng)程序的框架:S3c2410_adc_open(){…..}S3c2410_adc_release(){…..}S3c2410_adc_read(){…..}S3c2410_adc_write(){…..}staticstructfile_operationss3c2410_fops={

open: s3c2410_adc_open,

read: s3c2410_adc_read,

write:s3c2410_adc_write,

release:s3c2410_adc_release,};S3c2410_adc_init(){…..}S3c2410_adc_exit(){…..}module_init(S3c2410_adc_init);module_exit(S3c2410_adc_exit);2023/7/22二、驅(qū)動(dòng)程序介紹實(shí)例:編寫一個(gè)最簡單的驅(qū)動(dòng)程序demo.c

在內(nèi)核空間開一個(gè)40個(gè)字節(jié)的緩存區(qū)drv_buf,請(qǐng)問應(yīng)用如何訪問它?用戶區(qū)內(nèi)核區(qū)drv_buf

要求設(shè)計(jì)2個(gè)函數(shù),read用于讀出緩存區(qū)的內(nèi)容,write用于更新緩存區(qū)的內(nèi)容。設(shè)備文件名:/dev/demo/0

主設(shè)備號(hào)為:249

次設(shè)備號(hào)為:02023/7/22demo_open(){…..}demo_release(){…..}demo_read(){…..}demo_write(){…..}staticstructfile_operationsdemo_fops={

open: demo_open,

read: demo_read,

write:demo_write,

release:demo_release,};demo_init(){…..}demo_exit(){…..}module_init(demo_init);module_exit(demo_exit);1、demo驅(qū)動(dòng)程序的框架:2023/7/222、驅(qū)動(dòng)程序函數(shù)初始化函數(shù)的主要功能是什么?demo_init(){…..}module_init(demo_init);設(shè)備驅(qū)動(dòng)在加載時(shí)首先調(diào)用入口函數(shù)module_init()完成設(shè)備驅(qū)動(dòng)的初始化工作,比如寄存器置位、結(jié)構(gòu)體賦值、申請(qǐng)中斷等。向內(nèi)核注冊(cè)本設(shè)備。注冊(cè)成功后,該設(shè)備獲得了系統(tǒng)分配的主設(shè)備號(hào)、自定義的次設(shè)備號(hào),并建立起與文件系統(tǒng)的關(guān)聯(lián)。2023/7/22staticint__initdemo_init(void){#ifdefCONFIG_DEVFS_FSdevfs_demo_dir=devfs_mk_dir(NULL,"demo",NULL);devfs_demoraw=devfs_register(devfs_demo_dir,"0",DEVFS_FL_DEFAULT, demo_MAJOR,demo_MINOR,S_IFCHR|S_IRUSR|S_IWUSR, &demo_fops,NULL);#elseintresult;SET_MODULE_OWNER(&demo_fops);result=register_chrdev(demo_MAJOR,"demo",&demo_fops);if(result<0)returnresult;#endifprintk(DEVICE_NAME"initialized\n");return0;}如果配置了設(shè)備文件系統(tǒng),交叉編譯環(huán)境配了注冊(cè)設(shè)備文件/dev/demo/0驅(qū)動(dòng)程序接口變量給設(shè)備文件系統(tǒng)創(chuàng)建目錄/dev/demo用gcc編譯時(shí),會(huì)運(yùn)行這一段。它只在系統(tǒng)中注冊(cè)主設(shè)備號(hào),不會(huì)生成設(shè)備文件。mknod/dev/democ24902023/7/22demo_open(){…..}demo_release(){…..}demo_read(){…..}demo_write(){…..}demo_init(){…..}demo_exit(){…..}module_init(demo_init);module_exit(demo_exit);demo驅(qū)動(dòng)程序的框架:staticstructfile_operationsdemo_fops={

open: demo_open,

read: demo_read,

write:demo_write,

release:demo_release,};2023/7/22demo_open(){…..}demo_release(){…..}demo_read(){…..}demo_write(){…..}demo_init(){…..}demo_exit(){…..}module_init(demo_init);module_exit(demo_exit);demo驅(qū)動(dòng)程序的框架:staticstructfile_operationsdemo_fops={

open: demo_open,

read: demo_read,

write:demo_write,

release:demo_release,};這是給結(jié)構(gòu)賦值staticstructfile_operationsdemo_fops={

open: demo_open,

read: demo_read,

write:demo_write,

release:demo_release,};2023/7/22staticintdemo_open(structinode*inode,structfile*file){ MOD_INC_USE_COUNT; sprintf(drv_buf,"deviceopensucess!\n"); printk("deviceopensucess!\n"); return0;}staticintdemo_release(structinode*inode,structfile*filp){ MOD_DEC_USE_COUNT; printk("devicerelease\n"); return0;}模塊計(jì)數(shù)器+1,表示增加了一個(gè)模塊。模塊計(jì)數(shù)器-1,表示減少了一個(gè)模塊。2023/7/22staticssize_tdemo_write(structfile*filp,constchar*buffer,size_tcount){ copy_from_user(drv_buf,buffer,count); printk("userwritedatatodriver\n"); returncount;}staticssize_tdemo_read(structfile*filp,char*buffer,size_tcount,loff_t*ppos){ if(count>MAX_BUF_LEN) count=MAX_BUF_LEN; copy_to_user(buffer,drv_buf,count); printk("userreaddatafromdriver\n"); returncount;}將用戶態(tài)的數(shù)據(jù)復(fù)制到內(nèi)核態(tài)將內(nèi)核態(tài)的數(shù)據(jù)復(fù)制到用戶態(tài)2023/7/223、驅(qū)動(dòng)程序編譯過程驅(qū)動(dòng)程序一般采用make工具進(jìn)行編譯。使用make工具的關(guān)鍵是編寫Makefile文件。以下是編譯成x86平臺(tái)上的Makefile文件內(nèi)容:KERNELDIR=/usr/src/linuxINCLUDEDIR=$(KERNELDIR)/includeCROSS_COMPILE=CC=$(CROSS_COMPILE)gccCFLAGS+=-I..CFLAGS+=-Wall-O-D__KERNEL__-DMODULE-I$(INCLUDEDIR)TARGET=demo.oOBJS=demo.c$(TARGET):$(OBJS) $(CC)-c$(CFLAGS)$^-o$@clean: rm-f*.o*~core.depend2023/7/22如果需要編譯成ARM平臺(tái)上的驅(qū)動(dòng)程序,只需修改Makefile中KERNELDIR和CROSS_COMPILE變量即可,例如修改如下:#KERNELDIR=/usr/src/linuxKERNELDIR=/arm2410s/kernel-2410s

INCLUDEDIR=$(KERNELDIR)/include

#CROSS_COMPILE=CROSS_COMPILE=/opt/host/arm/bin/arm-linux-CC=$(CROSS_COMPILE)gccCFLAGS+=-I..CFLAGS+=-Wall-O-D__KERNEL__-DMODULE-I$(INCLUDEDIR)TARGET=demo.oOBJS=demo.c$(TARGET):$(OBJS) $(CC)-c$(CFLAGS)$^-o$@clean: rm-f*.o*~core.depend2023/7/22運(yùn)行make命令后,就會(huì)生成驅(qū)動(dòng)程序demo.o2023/7/224、驅(qū)動(dòng)程序加載和設(shè)備文件創(chuàng)建加載驅(qū)動(dòng)程序可以使用insmod命令,如下:#insmoddemo.o驅(qū)動(dòng)程序加載時(shí),如果系統(tǒng)支持設(shè)備文件系統(tǒng),則系統(tǒng)會(huì)自動(dòng)創(chuàng)建設(shè)備文件,否則需要手動(dòng)創(chuàng)建。手動(dòng)創(chuàng)建可使用mknod命令,如下:#mknod/dev/demo/0c24902023/7/22編寫一個(gè)應(yīng)用程序來測試驅(qū)動(dòng)程序是否正確,要求測試程序test_demo.c的功能是:首先從設(shè)備上讀出數(shù)據(jù),并將數(shù)據(jù)顯示在屏幕上,這時(shí)讀到的數(shù)據(jù)為初始化值。然后向設(shè)備寫入數(shù)據(jù),再從設(shè)備上讀出數(shù)據(jù),又將數(shù)據(jù)顯示在屏幕上,這時(shí)讀到的數(shù)據(jù)應(yīng)為上一步寫入的數(shù)據(jù)三、應(yīng)用程序2023/7/22intmain(){

intfd;

inti;

charbuf[255];

fd=open("/dev/demo",O_RDWR);//打開設(shè)備文件

if(fd<0){

printf("####DEMOdeviceopenfail####\n");

return(-1);

}

read(fd,buf,40);//從設(shè)備讀取數(shù)據(jù)

printf("Fristreaddata:%s\n",buf);

printf("Pleaseinputstring\n"); scanf("%s",buf); write(fd,buf,40);//向設(shè)備寫數(shù)據(jù)

read(fd,buf,40);//從設(shè)備讀取數(shù)據(jù) printf("Secondreaddata:%s\n",buf);

close(fd);//關(guān)閉設(shè)備 return0;

}運(yùn)行的結(jié)果如何?2023/7/222.編譯和運(yùn)行(1)編譯測試程序?qū)y試程序編譯成x86平臺(tái)上運(yùn)行的可執(zhí)行程序,命令如下:#gcctest_demo.c-otest_demo將測試程序編譯成ARM平臺(tái)上運(yùn)行的可執(zhí)行程序,命令如下:#arm-linux-gcctest_demo.c-otest_demo2023/7/22(2)運(yùn)行測試程序測試程序運(yùn)行結(jié)果如下:#./test_demoFristreaddata:deviceopensucess!PleaseinputstringNanchangSecondreaddata:Nanchang2023/7/225.1Linux驅(qū)動(dòng)程序概述

5.2虛擬字符設(shè)備Demo驅(qū)動(dòng)程序設(shè)計(jì)

5.3A/D驅(qū)動(dòng)程序設(shè)計(jì)5.4步進(jìn)電機(jī)驅(qū)動(dòng)程序設(shè)計(jì)第5章:Linux驅(qū)動(dòng)程序設(shè)計(jì)2023/7/225.3.1A/D轉(zhuǎn)換的基礎(chǔ)理論5.3.2A/D轉(zhuǎn)換的驅(qū)動(dòng)程序分析5.3.3A/D轉(zhuǎn)換應(yīng)用程序分析5.3A/D驅(qū)動(dòng)和測試程序設(shè)計(jì)2023/7/221、A/D是什么?A是analog的縮寫,D是digital的縮寫。A/D是將模擬信號(hào)轉(zhuǎn)換成數(shù)字信號(hào)的意思。5.3.1A/D轉(zhuǎn)換的基礎(chǔ)理論2023/7/222、A/D的具體應(yīng)用?(1)測試溫度。(2)測試冒霧濃度(煤氣濃度\CO2)。(3)壓力5.3.1A/D轉(zhuǎn)換的基礎(chǔ)理論2023/7/223、A/D轉(zhuǎn)換器是什么?

是模擬信號(hào)源與CPU之間的接口,它的任務(wù)是將連續(xù)變化的模擬信號(hào)轉(zhuǎn)換成數(shù)字信號(hào)。2023/7/224、A/D轉(zhuǎn)換器的類型有那些?A/D轉(zhuǎn)換器的類型有:逐位比較型(逐次逼近型)、積分型、計(jì)數(shù)型、并行比較型、電壓—頻率型等。用戶應(yīng)根據(jù)使用的場合的具體要求,來決定選擇那一種類型的轉(zhuǎn)換器。2023/7/225、逐次逼近型A/D轉(zhuǎn)換器的工作原理

設(shè)轉(zhuǎn)換器最大可檢測的電壓值為4.096V,轉(zhuǎn)換器的寄存器有效位為10位(即最大值為1024),則最小單位1表示的電壓值為4.096/1024=0.004V。原理動(dòng)畫演示2023/7/22逐次逼近型A/D轉(zhuǎn)換器的工作原理轉(zhuǎn)換開始,先設(shè)定SAR寄存器的最高位為“1”,其余位為“0”,將試探值經(jīng)D/A轉(zhuǎn)換成電壓Vc,然后將Vc與模擬輸入電壓Vx比較。如果Vx≥Vc,說明SAR最高位的“1”應(yīng)予保留;如果Vx<Vc,說明SAR該位應(yīng)予清零。然后再對(duì)SAR寄存器的次高位置“1”,依上述方法進(jìn)行D/A轉(zhuǎn)換和比較。如此重復(fù)上述過程,直至確定SAR寄存器的最低位為止。最后,逐次逼近寄存器SAR中的內(nèi)容就是與輸入模擬量V相對(duì)應(yīng)的二進(jìn)制數(shù)字量。2023/7/226、A/D轉(zhuǎn)換器的電路圖

ARMS3C2410芯片自帶一個(gè)8路10位A/D轉(zhuǎn)換器,并且支持觸摸屏功能。ARM2410開發(fā)板只用作3路A/D轉(zhuǎn)換器。2023/7/22ARMS3C2410芯片自帶一個(gè)8路10位A/D轉(zhuǎn)換器,并且支持觸摸屏功能。2023/7/222023/7/22IO有控制、數(shù)據(jù)和狀態(tài)寄存器,它們的功能是什么?2023/7/22A/D轉(zhuǎn)換器的主要寄存器寄存器地址描述ADCCON0x58000000ADC轉(zhuǎn)換控制寄存器ADCDAT00x58000000ADC轉(zhuǎn)換數(shù)據(jù)寄存器2023/7/22ADCCON控制寄存器ADCCON位描述ECFLG[15]Endofconversionflag(readonly)0=A/Dconversioninprocess1=EndofA/DconversionPRSCEN[14]A/Dconversionprescalerenable0=Disable1=EnablePRSCVL[13:6]A/Dconverterprescalervalue.Datavalue:1–255Notethatdivisionfactoris(N+1)whentheprescalervalueisN.SEL—MUX[5:3]Analoginputchannelselect.000=AIN0001=AIN1010=AIN2011=AIN3100=AIN4101=AIN5110=AIN6111=AIN72023/7/22ADCCON控制寄存器ADCCON位描述STDBM[2]Standbymodeselect0=Normaloperationmode1=StandbymodeREAD_START[1]A/Dconversionstartbyread0=Disablestartbyreadoperation1=EnablestartbyreadoperationENABLE_START[0]A/Dconverterstartbysettingthisbit.IfREAD_STARTisenabled,thisvalueisnotvalid.0=Nooperation1=A/Dconversionstartsandthisbitisclearedafterthestart-up.2023/7/22A/D轉(zhuǎn)換器接口輸入電路圖2023/7/22A/D轉(zhuǎn)換器接口輸入電路圖工作流程動(dòng)畫演示2023/7/224.1A/D轉(zhuǎn)換的基礎(chǔ)理論4.2A/D轉(zhuǎn)換的驅(qū)動(dòng)程序分析4.3A/D轉(zhuǎn)換應(yīng)用程序分析5.4A/D驅(qū)動(dòng)和測試程序設(shè)計(jì)2023/7/225、驅(qū)動(dòng)程序分析驅(qū)動(dòng)程序的框架:S3c2410_adc_open(){…..}S3c2410_adc_release(){…..}S3c2410_adc_read(){…..}S3c2410_adc_write(){…..}staticstructfile_operationss3c2410_fops={

open: s3c2410_adc_open,

read: s3c2410_adc_read,

write:s3c2410_adc_write,

release:s3c2410_adc_release,};S3c2410_adc_init(){…..}S3c2410_adc_exit(){…..}2023/7/22驅(qū)動(dòng)程序設(shè)計(jì)的總體構(gòu)思定義一個(gè)數(shù)據(jù)結(jié)構(gòu)typedefstruct{

structsemaphorelock;

wait_queue_head_twait;

intchannel;存放具體操作的A/D通道

intprescale;操作時(shí)的比例因子值}ADC_DEV;

staticADC_DEVadcdev;read()函數(shù)的功能是:讀取數(shù)據(jù)結(jié)構(gòu)中,channal指向的A/D通道值。Write()函數(shù)的功能是向數(shù)據(jù)結(jié)構(gòu)寫A/D通道值和比例因子值。2023/7/22驅(qū)動(dòng)程序設(shè)計(jì)的總體構(gòu)思typedefstruct{

structsemaphorelock;

wait_queue_head_twait;

intchannel;intprescale;}ADC_DEV;

staticADC_DEVadcdev;S3c2410_adc_open(){…..}S3c2410_adc_release(){…..}S3c2410_adc_read(){…..}S3c2410_adc_write(){…..}staticstructfile_operationss3c2410_fops={

open: s3c2410_adc_open,

read: s3c2410_adc_read,

write:s3c2410_adc_write,

release:s3c2410_adc_release,};S3c2410_adc_init(){…..}S3c2410_adc_exit(){…..}2023/7/22驅(qū)動(dòng)程序各函數(shù)的功能這個(gè)函數(shù)在什么時(shí)候運(yùn)行?1、S3c2410_adc_init(){…..}安裝驅(qū)動(dòng)程序時(shí),運(yùn)行這個(gè)函數(shù)。設(shè):生成的驅(qū)動(dòng)程序的文件名為:adc.o則在運(yùn)行insmodadc.o時(shí)執(zhí)行此函數(shù)。2023/7/22驅(qū)動(dòng)程序各函數(shù)的功能這個(gè)函數(shù)的主要功能是什么?1、S3c2410_adc_init(){…..}(1)申請(qǐng)中斷,使用request_irq()函數(shù)。(2)申請(qǐng)主設(shè)備號(hào),使用register_chrdev()函數(shù)。

(3)創(chuàng)建設(shè)備文件的目錄和設(shè)備文件。使用devfs_mk_dir()和devfs_register()函數(shù)。

2023/7/22驅(qū)動(dòng)程序各函數(shù)的功能這個(gè)函數(shù)什么時(shí)候運(yùn)行?2、S3c2410_adc_exit(){…..}卸除驅(qū)動(dòng)程序時(shí),運(yùn)行這個(gè)函數(shù)。設(shè):在運(yùn)行insmodadc.o時(shí),生成一個(gè)名為adc的模塊驅(qū)動(dòng)程序(可以用lsmod來查看)。則在運(yùn)行rmmodadc時(shí)執(zhí)行此函數(shù),這是刪除已經(jīng)安裝的驅(qū)動(dòng)程序。2023/7/22驅(qū)動(dòng)程序各函數(shù)的功能這個(gè)函數(shù)的主要功能是什么?2、S3c2410_adc_exit(){…..}(3)刪除已申請(qǐng)中斷,使用free_irq()函數(shù)。(2)刪除已申請(qǐng)主設(shè)備號(hào),使用unregister_chrdev()函數(shù)。

(1)刪除設(shè)備文件的文件和目錄。使用devfs_unregister()函數(shù)。

2023/7/22驅(qū)動(dòng)程序各函數(shù)的功能這個(gè)函數(shù)的主要功能是什么?3、S3c2410_adc_open(){…..}初始化數(shù)據(jù)結(jié)構(gòu)typedefstruct{

structsemaphorelock;

wait_queue_head_twait;

intchannel; intprescale;}ADC_DEV;

staticADC_DEVadcdev;2023/7/22驅(qū)動(dòng)程序各函數(shù)的功能這個(gè)函數(shù)的主要功能是什么?4、S3c2410_adc_release{…..}可以理解成,未做什么。設(shè)想成空函數(shù)2023/7/22驅(qū)動(dòng)程序各函數(shù)的功能這個(gè)函數(shù)的主要功能是什么?5、S3c2410_adc_write{…..}

將應(yīng)用程序傳來的a/d通道和比例因子信息,保存到數(shù)據(jù)結(jié)構(gòu)中。思考:write(指針,數(shù)據(jù)指針,數(shù)據(jù)長度),每次只能傳送一個(gè)數(shù)據(jù),如何傳送2個(gè)數(shù)據(jù)(a/d通道和比例因子)?“a/d通道”+“比例因子”=新的數(shù)新的數(shù)“a/d通道”+“比例因子”2023/7/22驅(qū)動(dòng)程序各函數(shù)的功能這個(gè)函數(shù)的主要功能是什么?6、S3c2410_adc_read{…..}

讀出a/d的模擬電壓值,有3個(gè)通道,讀那一個(gè)?由數(shù)據(jù)結(jié)構(gòu)中的值來決定。思考:a/d轉(zhuǎn)換的幾個(gè)過程?2023/7/22驅(qū)動(dòng)程序各函數(shù)的功能A/d轉(zhuǎn)換的步驟:(1)給數(shù)據(jù)結(jié)構(gòu)加鎖。不準(zhǔn)改變數(shù)據(jù)結(jié)構(gòu)中元素的數(shù)據(jù)。(3)向ADC控制寄存器寫數(shù)據(jù),告訴A/D轉(zhuǎn)換開始工作。(4)A/D轉(zhuǎn)換要花費(fèi)時(shí)間,所以在A/D開始轉(zhuǎn)換后,程序進(jìn)入休眠狀態(tài),讓CPU去做其它工作。(2)向ADC控制寄存器寫數(shù)據(jù),告訴選擇那一個(gè)A/D轉(zhuǎn)換通過道。2023/7/22驅(qū)動(dòng)程序各函數(shù)的功能A/d轉(zhuǎn)換的步驟:(5)A/D轉(zhuǎn)換完成后,喚醒程序繼續(xù)執(zhí)行。(6)ADC數(shù)據(jù)寄存器的低10位就是模擬信息對(duì)應(yīng)的數(shù)值。(因?yàn)镾3C2410內(nèi)部是10

溫馨提示

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

評(píng)論

0/150

提交評(píng)論