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

下載本文檔

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

文檔簡(jiǎn)介

Linux設(shè)備驅(qū)動(dòng)程序Linux設(shè)備驅(qū)動(dòng)程序內(nèi)容設(shè)備分類設(shè)備驅(qū)動(dòng)程序的框架字符型設(shè)備網(wǎng)絡(luò)設(shè)備文件系統(tǒng)UserSpaceFileSystemUSB設(shè)備FrameBuffer例子和使用Debug原理和Debug方法常用設(shè)備/fb/ram/loopback/zero內(nèi)容設(shè)備分類2Linux設(shè)備驅(qū)動(dòng)程序課件3Linux設(shè)備驅(qū)動(dòng)程序課件4Linux設(shè)備驅(qū)動(dòng)程序課件5Linux設(shè)備驅(qū)動(dòng)程序課件6Linux設(shè)備驅(qū)動(dòng)程序課件7Linux設(shè)備驅(qū)動(dòng)程序課件8直接訪問(wèn)IO端口(/dev/port)port_fd

=

open("/dev/port",

O_RDWR);

lseek(port_fd,

port_addr,

SEEK_SET);

read(port_fd,

…);write(port_fd,

…);

close(port_fd);注意:不能用fopen/fread/fwrite/fclose因?yàn)樗鼈冇袛?shù)據(jù)緩沖,對(duì)讀寫操作不是立即完成的直接訪問(wèn)IO端口(/dev/port)port_fd

=

o9outb()/outw()/inb()/inw()函數(shù)#include<stdio.h>#include<unistd.h>#include<asm/io.h>#defineBASEPORT0x378//printerintmain(){

ioperm(BASEPORT,3,1)); //getaccesspermission

outb(0,BASEPORT);usleep(100000);printf("status:%d\n",inb(BASEPORT+1));

ioperm(BASEPORT,3,0)); //giveupexit(0);}ioperm(from,num,turn_on)用ioperm申請(qǐng)的操作端口地址在0x000~0x3FF,利用iopl()可以申請(qǐng)所有的端口地址必須以root運(yùn)行用“gcc-02–oxxx.elfxxx.c”編譯

outb(value,port);inb(port);//8-bitoutw(value,port);inw(port);//16-bit訪問(wèn)時(shí)間大約1usoutb()/outw()/inb()/inw()函數(shù)#in10設(shè)備驅(qū)動(dòng)程序內(nèi)訪問(wèn)設(shè)備地址設(shè)備驅(qū)動(dòng)程序可以通過(guò)指針訪問(wèn)設(shè)備地址設(shè)備驅(qū)動(dòng)程序接觸到的還是虛擬地址,但對(duì)于外界設(shè)備有固定的設(shè)備地址映射(設(shè)備的地址在移植Linux時(shí)候確定)物理內(nèi)存地址空間設(shè)備驅(qū)動(dòng)程序虛擬地址映射設(shè)備地址空間設(shè)備地址映射設(shè)備驅(qū)動(dòng)程序虛擬地址映射設(shè)備地址映射設(shè)備驅(qū)動(dòng)程序內(nèi)訪問(wèn)設(shè)備地址設(shè)備驅(qū)動(dòng)程序可以通過(guò)指針訪問(wèn)設(shè)備地11直接訪問(wèn)IO端口vs設(shè)備驅(qū)動(dòng)程序IO直接訪問(wèn)用戶態(tài)程序編寫/調(diào)試簡(jiǎn)單查詢模式,響應(yīng)慢設(shè)備共享管理困難設(shè)備驅(qū)動(dòng)訪問(wèn)核心態(tài)編程調(diào)試?yán)щy可用中斷模式訪問(wèn)、快設(shè)備共享管理簡(jiǎn)單(由內(nèi)核幫助完成)直接訪問(wèn)IO端口vs設(shè)備驅(qū)動(dòng)程序IO直接訪問(wèn)設(shè)備驅(qū)動(dòng)訪問(wèn)12設(shè)備分類字符設(shè)備鼠標(biāo)、串口、游戲桿塊設(shè)備磁盤、打印機(jī)網(wǎng)絡(luò)設(shè)備由BSDSocket訪問(wèn)設(shè)備分類字符設(shè)備13字符設(shè)備vs塊設(shè)備字符設(shè)備字符設(shè)備發(fā)出讀/寫請(qǐng)求時(shí),對(duì)應(yīng)的硬件I/O一般立即發(fā)生。數(shù)據(jù)緩沖可有可無(wú)ADC/DAC、按鈕、LED、傳感器等塊設(shè)備利用一塊系統(tǒng)內(nèi)存作緩沖區(qū),一般讀寫由緩沖區(qū)直接提供,盡量減少IO操作針對(duì)磁盤等慢速設(shè)備字符設(shè)備vs塊設(shè)備字符設(shè)備塊設(shè)備14可裝卸的設(shè)備驅(qū)動(dòng)程序和

靜態(tài)連接到內(nèi)核的設(shè)備驅(qū)動(dòng)程序靜態(tài)連接到內(nèi)核的設(shè)備驅(qū)動(dòng)程序修改配置文件、重新編譯和安裝內(nèi)核可裝卸的設(shè)備驅(qū)動(dòng)程序insmod 裝載rmmod

卸載lsmod

查詢可裝卸的設(shè)備驅(qū)動(dòng)程序和

靜態(tài)連接到內(nèi)核的設(shè)備驅(qū)動(dòng)程序靜態(tài)連接15Linux對(duì)硬件設(shè)備的抽象

設(shè)備文件Open/Close/Read/Write例子/dev/mouse/dev/lp0Linux對(duì)硬件設(shè)備的抽象 設(shè)備文件16驅(qū)動(dòng)程序與設(shè)備文件設(shè)備驅(qū)動(dòng)程序設(shè)備文件用mknod

命令創(chuàng)建用insmod命令安裝,或直接編譯到內(nèi)核中用戶程序用open/read/write/close等命令訪問(wèn)通過(guò)主設(shè)備號(hào)找到設(shè)備驅(qū)動(dòng)驅(qū)動(dòng)程序與設(shè)備文件設(shè)備驅(qū)動(dòng)程序設(shè)備用mknod

命令創(chuàng)建用i17驅(qū)動(dòng)程序代碼結(jié)構(gòu)驅(qū)動(dòng)程序注冊(cè)與注銷設(shè)備文件的操作函數(shù)(*open)()(*write)()(*flush)()(*llseek)()…中斷服務(wù)程序驅(qū)動(dòng)程序代碼結(jié)構(gòu)驅(qū)動(dòng)程序注冊(cè)與注銷設(shè)備文件的操作函數(shù)中斷服務(wù)18LED設(shè)備驅(qū)動(dòng)程序的例子CPULED設(shè)備驅(qū)動(dòng)程序的例子CPU19structfile_operationsLED_fops={read:LED_read,write:LED_write,open:LED_open,release:LED_release,};

intLED_init_module(void){SET_MODULE_OWNER(&LED_fops);LED_major=register_chrdev(0,"LED",&LED_fops);LED_off();

LED_status=0;return0;}

voidLED_cleanup_module(void){unregister_chrdev(LED_major,"LED");}

module_init(LED_init_module);module_exit(LED_cleanup_module);程序列表(1)structfile_operationsLED_fop20程序列表(2)intLED_open(structinode*inode,structfile*filp)

{printk("LED_open()\n");

MOD_INC_USE_COUNT;

return0;

}intLED_release(structinode*inode,structfile*filp)

{printk(“LED_release()\n“);

MOD_DEC_USE_COUNT;

return0;

}程序列表(2)intLED_open(structin21程序列表(3)ssize_tLED_read(structfile*filp,char*buf,size_tcount,loff_t*f_pos)

{inti;

for(i=0;i<count;i++)

*((char*)(buf+i))=LED_Status;

returncount;

}

ssize_tLED_write(structfile*filp,constchar*buf,size_tcount,loff_t*f_pos)

{inti;

for(i=0;i<count;i++)

if(*((char*)(buf+i)))

Data->LED_on();

elseData->LED_off();

returncount;

}(*((volatileunsignedint*)(0xXXXXXXXX)))|=MASK;

(*((volatileunsignedint*)(0xXXXXXXXX)))&=~MASK;程序列表(3)ssize_tLED_read(stru22#ifndef__KERNEL__

#define__KERNEL__

#endif

#ifndefMODULE

#defineMODULE

#endif

#include<linux/config.h>

#include<linux/module.h>

#include<linux/sched.h>

#include<linux/kernel.h>

#include<linux/malloc.h>

#include<linux/errno.h>

#include<linux/types.h>

#include<linux/interrupt.h>

#include<linux/in.h>

#include<linux/netdevice.h>

#include<linux/etherdevice.h>

#include<linux/ip.h>

#include<linux/tcp.h>

#include<linux/skbuff.h>

#include<sysdep.h>

#include<linux/ioctl.h>

#include<linux/in6.h>

#include<asm/checksum.h>

MODULE_AUTHOR("RendongYing");

intLED_major,LED_status;程序列表(4)頭文件#ifndef__KERNEL__

#de23程序編譯(Makefile)CC=arm-elf-linux-gccLD=arm-elf-linux-ldINCLUDE=/usr/local/src/bspLinux/includeLIB_INC=/usr/local/lib/gcc-lib/arm-elf-linux/2.95.3/includeCFLAGS=-O6-Wall-DCONFIG_KERNELD-DMODULE-D__KERNEL__

-DLinux-nostdinc-I--I.-I$(INCLUDE)

-idirafter$(LIB_INC)LED.o:LED.c $(CC)$(CFLAGS)-cLED.c

clean: rm-fLED.o生成o文件程序編譯(Makefile)CC=arm-elf-li24設(shè)備裝載和設(shè)備文件建立chmod+x/tmp/LED.o/sbin/insmod-f./LED.ocat/proc/devices得到裝入內(nèi)核的主設(shè)備號(hào)mknod/dev/LampcNum1Num2

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

Num2為次設(shè)備號(hào)強(qiáng)制安裝,忽略版本檢查設(shè)備裝載和設(shè)備文件建立chmod+x/tmp/LED.o25設(shè)備的測(cè)試和使用命令行echo8>/proc/sys/kernel/printkcat/dev/Lampcat>/dev/Lamp程序

voidmain()

{intfd=open(“/dev/Lamp,O_RDWR);

write(fd,&data,1);

close(fd);

}開啟printk,也可以從/var/log/messages看printk的記錄設(shè)備的測(cè)試和使用命令行開啟printk,也可以從/var/l26設(shè)備卸載/sbin/rmmodLED

rm-f/dev/LampFunctionofMOD_INC_USE_COUNT;MOD_DEC_USE_COUNT;設(shè)備卸載/sbin/rmmodLED

rm-f/dev27復(fù)雜的設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序注冊(cè)與注銷(注冊(cè)/注銷設(shè)備、中斷)設(shè)備文件的操作函數(shù)(*open)()(*write)()(*flush)()(*llseek)()…中斷服務(wù)程序內(nèi)核數(shù)據(jù)緩沖區(qū)用戶數(shù)據(jù)空間復(fù)雜的設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序注冊(cè)與注銷設(shè)備文件的操作函數(shù)中斷服28復(fù)雜設(shè)備驅(qū)動(dòng)程序的例子

(USBDevice)中斷資源申請(qǐng)和釋放if(request_irq(USB_INTR_SOURCE1,

usb_ep1_int,

SA_INTERRUPT,

"USBEP1",

0)<0)

printk("Int.req.failed!\n");free_irq(USB_INTR_SOURCE0,0);cat

/proc/interrupts復(fù)雜設(shè)備驅(qū)動(dòng)程序的例子

(USBDevice)中斷資源申請(qǐng)29中斷服務(wù)程序

沒(méi)有返回參數(shù)簡(jiǎn)短快速voidusb_ep1_int(intirq,

void*dev_id,

structpt_regs*regs)

{

//…

}中斷服務(wù)程序沒(méi)有返回參數(shù)30數(shù)據(jù)接收中斷服務(wù)程序voidusb_ep1_int(intirq,

void*dev_id,

structpt_regs*regs)

{

read_data_from_hardware_FIFO();

put_data_into_data_buffer();}數(shù)據(jù)接收中斷服務(wù)程序voidusb_ep1_int(int31數(shù)據(jù)發(fā)送中斷服務(wù)程序voidusb_ep2_int(intirq,

void*dev_id,

structpt_regs*regs)

{

read_data_from_buffer();

send_data_hardware_FIFO();}數(shù)據(jù)發(fā)送中斷服務(wù)程序voidusb_ep2_int(int32設(shè)備文件接口函數(shù)(read)ssize_tusb_ep1_read(structfile*filp,

char*buf,

size_tcount,

loff_t*f_pos)

{

if(data_buffer_empty())return0;

else

copy_data_to_user_space();

returndata_copyed;

}copy_to_user(user_buf,

device_driver_buf,

size);設(shè)備文件接口函數(shù)(read)ssize_tusb_ep1_33設(shè)備文件接口函數(shù)

(read,blockingmode)ssize_tusb_ep1_read(structfile*filp,

char*buf,

size_tcount,

loff_t*f_pos)

{

while(device_driver_buf_empty())

{if(wait_event_interruptible(q_ep2,

device_driver_buf_not_empty))return-ERESTARTSYS;}

copy_data_to_user_space();

returndata_copyed;

}wait_queue_head_trq_EP2;

init_waitqueue_head(&rq_EP2);設(shè)備文件接口函數(shù)

(read,blockingmode)34設(shè)備文件接口函數(shù)(write)ssize_tusb_ep2_write(structfile*filp,

char*buf,

size_tcount,

loff_t*f_pos)

{

if(data_buffer_full())return0;

else

copy_data_to_device_driver_buf();

if(no_transmission_now)

send_1st_data();

returndata_copyed;

}copy_from_user(device_driver_buf,

user_buf,

size);設(shè)備文件接口函數(shù)(write)ssize_tusb_ep235內(nèi)存申請(qǐng)malloc?Xkmallockfreevmallocvfree內(nèi)存申請(qǐng)malloc?X36禁止設(shè)備打開多次intLED_flag;

intLED_init_module(void)

{LED_flag=0;

…}

intLED_open(stru

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 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ì)用戶上傳內(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)論