Linux設備驅(qū)動程序課件_第1頁
Linux設備驅(qū)動程序課件_第2頁
Linux設備驅(qū)動程序課件_第3頁
Linux設備驅(qū)動程序課件_第4頁
Linux設備驅(qū)動程序課件_第5頁
已閱讀5頁,還剩73頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

Linux設備驅(qū)動程序docin/sundae_mengLinux設備驅(qū)動程序docin/sundae_meng1內(nèi)容設備分類設備驅(qū)動程序的框架字符型設備網(wǎng)絡設備文件系統(tǒng)UserSpaceFileSystemUSB設備FrameBuffer例子和使用Debug原理和Debug方法常用設備/fb/ram/loopback/zero內(nèi)容設備分類2設備驅(qū)動程序的任務設備初始化硬件操作和管理外部硬件和內(nèi)核空間的數(shù)據(jù)傳遞內(nèi)核空間和用戶空間的數(shù)據(jù)傳遞設備驅(qū)動程序的任務設備初始化3設備驅(qū)動程序的功能外部硬件設備驅(qū)動程序用戶程序存儲緩沖用戶空間內(nèi)核空間設備驅(qū)動程序的功能外部硬件設備驅(qū)動程序用戶程序存儲緩沖用戶空4用戶態(tài)程序vs內(nèi)核態(tài)程序用戶程序權限受限虛擬運行環(huán)境邏輯地址關鍵資源訪問受監(jiān)管函數(shù)調(diào)用由用戶控制內(nèi)核程序最高權限實際的運行環(huán)境物理地址可訪問所有資源函數(shù)由內(nèi)核直接調(diào)用可以運行驅(qū)動程序設備操作和管理能運行在用戶態(tài)嗎?用戶態(tài)程序vs內(nèi)核態(tài)程序用戶程序內(nèi)核程序設備操作和管理能5地址映射與物理地址訪問物理地址空間用戶進程1用戶進程2用戶進程3虛擬地址映射用戶利用指針訪問的是虛地址,不是物理地址,IO設備的物理地址可能是用戶進程不可觸及的虛擬地址映射虛擬地址映射地址映射與物理地址訪問物理地址空間用戶進程1用戶進程2用戶進6直接訪問內(nèi)核內(nèi)存(/dev/kmem)kmfd

=

open("/dev/kmem",

O_RDONLY

);

lseek(

kmfd,

offset,

SEEK_SET

);

read(

kmfd,

byteArray,

byteArrayLen

);

close(kmfd);直接訪問內(nèi)核地址(內(nèi)核態(tài)的虛地址)一般內(nèi)核地址起始于0xC0000000直接訪問內(nèi)核內(nèi)存(/dev/kmem)kmfd

=

open7直接訪問物理地址(/dev/mem)mem_fd

=

open("/dev/mem",

O_RDONLY

);

b=mmap(0,0x10000,

PROT_READ|PROT_WRITE,MAP_SHARED,

mem_fd,0xA0000)…close(memfd);0xA00000xB0000Pointerbmmap將文件中的數(shù)據(jù)映射成數(shù)組這里是將物理內(nèi)存(由特殊文件/dev/mem訪問)映射成指針b指向的數(shù)組。注意,指針b的值不一定是0xA0000,它是和物理地址0xA0000對應的用戶態(tài)的虛擬地址Linux中/dev/mem主要是用于設備內(nèi)存的訪問(比如顯卡內(nèi)存),而不是普通存儲器直接訪問物理地址(/dev/mem)mem_fd

=

ope8直接訪問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因為它們有數(shù)據(jù)緩沖,對讀寫操作不是立即完成的直接訪問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申請的操作端口地址在0x000~0x3FF,利用iopl()可以申請所有的端口地址必須以root運行用“gcc-02–oxxx.elfxxx.c”編譯

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

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

卸載lsmod

查詢可裝卸的設備驅(qū)動程序和

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

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

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

命令創(chuàng)建用i17驅(qū)動程序代碼結(jié)構驅(qū)動程序注冊與注銷設備文件的操作函數(shù)(*open)()(*write)()(*flush)()(*llseek)()…中斷服務程序驅(qū)動程序代碼結(jié)構驅(qū)動程序注冊與注銷設備文件的操作函數(shù)中斷服務18LED設備驅(qū)動程序的例子CPULED設備驅(qū)動程序的例子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設備裝載和設備文件建立chmod+x/tmp/LED.o/sbin/insmod-f./LED.ocat/proc/devices得到裝入內(nèi)核的主設備號mknod/dev/LampcNum1Num2

Num1為主設備號

Num2為次設備號強制安裝,忽略版本檢查設備裝載和設備文件建立chmod+x/tmp/LED.o25設備的測試和使用命令行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的記錄設備的測試和使用命令行開啟printk,也可以從/var/l26設備卸載/sbin/rmmodLED

rm-f/dev/LampFunctionofMOD_INC_USE_COUNT;MOD_DEC_USE_COUNT;設備卸載/sbin/rmmodLED

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

(USBDevice)中斷資源申請和釋放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復雜設備驅(qū)動程序的例子

(USBDevice)中斷資源申請29中斷服務程序

沒有返回參數(shù)簡短快速voidusb_ep1_int(intirq,

void*dev_id,

structpt_regs*regs)

{

//…

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

void*dev_id,

structpt_regs*regs)

{

read_data_from_hardware_FIFO();

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

void*dev_id,

structpt_regs*regs)

{

read_data_from_buffer();

send_data_hardware_FIFO();}數(shù)據(jù)發(fā)送中斷服務程序voidusb_ep2_int(int32設備文件接口函數(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ù)(read)ssize_tusb_ep1_33設備文件接口函數(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ù)

(read,blockingmode)34設備文件接口函數(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ù)(write)ssize_tusb_ep235內(nèi)存申請malloc?Xkmallockfreevmallocvfree內(nèi)存申請malloc?X36禁止設備打開多次intLED_flag;

intLED_init_module(void)

{LED_flag=0;

…}

intLED_open(structinode*inode,structfile*filp)

{if(LED_flag=0)

{LED_flag=1;

MOD_INC_USE_COUNT;

return0;

}

elsereturn-ENODEV;

}

intLED_release(structinode*inode,structfile*filp)

{LED_flag=0;

MOD_DEC_USE_COUNT;

return0;

}禁止設備打開多次intLED_flag;

intLED_37同一設備驅(qū)動管理幾個接口SerialPort

DeviceDriverUART0UART0應用程序同一設備驅(qū)動管理幾個接口SerialPort

Devic38同一設備驅(qū)動管理幾個接口intdev_open(structinode*inode,

structfile*filp)

{intminor=MINOR(inode->i_rdev);

filp->private_data=sub_dev_dat[minor];

}ssize_tdev_write(structfile*filp,

constchar*buf,

size_tcount,

loff_t*f_pos)

{

switch(*(filp->private_data))

{…}}同一設備驅(qū)動管理幾個接口intdev_open(struc39Linux設備驅(qū)動程序docin/sundae_mengLinux設備驅(qū)動程序docin/sundae_meng40內(nèi)容設備分類設備驅(qū)動程序的框架字符型設備網(wǎng)絡設備文件系統(tǒng)UserSpaceFileSystemUSB設備FrameBuffer例子和使用Debug原理和Debug方法常用設備/fb/ram/loopback/zero內(nèi)容設備分類41設備驅(qū)動程序的任務設備初始化硬件操作和管理外部硬件和內(nèi)核空間的數(shù)據(jù)傳遞內(nèi)核空間和用戶空間的數(shù)據(jù)傳遞設備驅(qū)動程序的任務設備初始化42設備驅(qū)動程序的功能外部硬件設備驅(qū)動程序用戶程序存儲緩沖用戶空間內(nèi)核空間設備驅(qū)動程序的功能外部硬件設備驅(qū)動程序用戶程序存儲緩沖用戶空43用戶態(tài)程序vs內(nèi)核態(tài)程序用戶程序權限受限虛擬運行環(huán)境邏輯地址關鍵資源訪問受監(jiān)管函數(shù)調(diào)用由用戶控制內(nèi)核程序最高權限實際的運行環(huán)境物理地址可訪問所有資源函數(shù)由內(nèi)核直接調(diào)用可以運行驅(qū)動程序設備操作和管理能運行在用戶態(tài)嗎?用戶態(tài)程序vs內(nèi)核態(tài)程序用戶程序內(nèi)核程序設備操作和管理能44地址映射與物理地址訪問物理地址空間用戶進程1用戶進程2用戶進程3虛擬地址映射用戶利用指針訪問的是虛地址,不是物理地址,IO設備的物理地址可能是用戶進程不可觸及的虛擬地址映射虛擬地址映射地址映射與物理地址訪問物理地址空間用戶進程1用戶進程2用戶進45直接訪問內(nèi)核內(nèi)存(/dev/kmem)kmfd

=

open("/dev/kmem",

O_RDONLY

);

lseek(

kmfd,

offset,

SEEK_SET

);

read(

kmfd,

byteArray,

byteArrayLen

);

close(kmfd);直接訪問內(nèi)核地址(內(nèi)核態(tài)的虛地址)一般內(nèi)核地址起始于0xC0000000直接訪問內(nèi)核內(nèi)存(/dev/kmem)kmfd

=

open46直接訪問物理地址(/dev/mem)mem_fd

=

open("/dev/mem",

O_RDONLY

);

b=mmap(0,0x10000,

PROT_READ|PROT_WRITE,MAP_SHARED,

mem_fd,0xA0000)…close(memfd);0xA00000xB0000Pointerbmmap將文件中的數(shù)據(jù)映射成數(shù)組這里是將物理內(nèi)存(由特殊文件/dev/mem訪問)映射成指針b指向的數(shù)組。注意,指針b的值不一定是0xA0000,它是和物理地址0xA0000對應的用戶態(tài)的虛擬地址Linux中/dev/mem主要是用于設備內(nèi)存的訪問(比如顯卡內(nèi)存),而不是普通存儲器直接訪問物理地址(/dev/mem)mem_fd

=

ope47直接訪問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因為它們有數(shù)據(jù)緩沖,對讀寫操作不是立即完成的直接訪問IO端口(/dev/port)port_fd

=

o48outb()/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申請的操作端口地址在0x000~0x3FF,利用iopl()可以申請所有的端口地址必須以root運行用“gcc-02–oxxx.elfxxx.c”編譯

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

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

卸載lsmod

查詢可裝卸的設備驅(qū)動程序和

靜態(tài)連接到內(nèi)核的設備驅(qū)動程序靜態(tài)連接54Linux對硬件設備的抽象

設備文件Open/Close/Read/Write例子/dev/mouse/dev/lp0Linux對硬件設備的抽象 設備文件55驅(qū)動程序與設備文件設備驅(qū)動程序設備文件用mknod

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

命令創(chuàng)建用i56驅(qū)動程序代碼結(jié)構驅(qū)動程序注冊與注銷設備文件的操作函數(shù)(*open)()(*write)()(*flush)()(*llseek)()…中斷服務程序驅(qū)動程序代碼結(jié)構驅(qū)動程序注冊與注銷設備文件的操作函數(shù)中斷服務57LED設備驅(qū)動程序的例子CPULED設備驅(qū)動程序的例子CPU58structfile_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_fop59程序列表(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(structin60程序列表(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(stru61#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__

#de62程序編譯(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-li63設備裝載和設備文件建立chmod+x/tmp/LED.o/sbin/insmod-f./LED.ocat/proc/devices得到裝入內(nèi)核的主設備號mknod/dev/LampcNum1Num2

Num1為主設備號

Num2為次設備號強制安裝,忽略版本檢查設備裝載和設備文件建立chmod+x/tmp/LED.o64設備的測試和使用命令行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的記錄設備的測試和使用命令行開啟printk,也可以從/var/l65設備卸載/sbin/rmmodLED

rm-f/dev/LampFunctionofMOD_INC_USE_COUNT;MOD_DEC_USE_COUNT;設備卸載/sbin/rmmodLED

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

(USBDevice)中斷資源申請和釋放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復雜設備驅(qū)動程序的例子

(USBDevice)中斷資源申請68中斷服務程序

沒有返回參數(shù)簡短快速voidusb_ep1_int(intirq,

void*dev_id,

structpt_regs*regs)

{

//…

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

void*dev_id,

structpt_regs*regs)

{

read_data_from_hardware_FIFO();

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

void*dev_id,

structpt_regs*regs)

{

read_data_from_buffer();

send_data_hardware_FIFO();}數(shù)據(jù)發(fā)送中斷服務程序voidusb_ep2_int(int71設備文件接口函數(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ù)(read)ssize_tusb_ep1_72設備文件接口函數(shù)

(read,blockingmode)ssize_tusb_ep1_read(structfile*filp,

溫馨提示

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

評論

0/150

提交評論