




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
Linux設備驅動程序docin/sundae_mengLinux設備驅動程序docin/sundae_meng1內容設備分類設備驅動程序的框架字符型設備網絡設備文件系統UserSpaceFileSystemUSB設備FrameBuffer例子和使用Debug原理和Debug方法常用設備/fb/ram/loopback/zero內容設備分類2設備驅動程序的任務設備初始化硬件操作和管理外部硬件和內核空間的數據傳遞內核空間和用戶空間的數據傳遞設備驅動程序的任務設備初始化3設備驅動程序的功能外部硬件設備驅動程序用戶程序存儲緩沖用戶空間內核空間設備驅動程序的功能外部硬件設備驅動程序用戶程序存儲緩沖用戶空4用戶態程序vs內核態程序用戶程序權限受限虛擬運行環境邏輯地址關鍵資源訪問受監管函數調用由用戶控制內核程序最高權限實際的運行環境物理地址可訪問所有資源函數由內核直接調用可以運行驅動程序設備操作和管理能運行在用戶態嗎?用戶態程序vs內核態程序用戶程序內核程序設備操作和管理能5地址映射與物理地址訪問物理地址空間用戶進程1用戶進程2用戶進程3虛擬地址映射用戶利用指針訪問的是虛地址,不是物理地址,IO設備的物理地址可能是用戶進程不可觸及的虛擬地址映射虛擬地址映射地址映射與物理地址訪問物理地址空間用戶進程1用戶進程2用戶進6直接訪問內核內存(/dev/kmem)kmfd
=
open("/dev/kmem",
O_RDONLY
);
lseek(
kmfd,
offset,
SEEK_SET
);
read(
kmfd,
byteArray,
byteArrayLen
);
close(kmfd);直接訪問內核地址(內核態的虛地址)一般內核地址起始于0xC0000000直接訪問內核內存(/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將文件中的數據映射成數組這里是將物理內存(由特殊文件/dev/mem訪問)映射成指針b指向的數組。注意,指針b的值不一定是0xA0000,它是和物理地址0xA0000對應的用戶態的虛擬地址Linux中/dev/mem主要是用于設備內存的訪問(比如顯卡內存),而不是普通存儲器直接訪問物理地址(/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因為它們有數據緩沖,對讀寫操作不是立即完成的直接訪問IO端口(/dev/port)port_fd
=
o9outb()/outw()/inb()/inw()函數#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()函數#in10設備驅動程序內訪問設備地址設備驅動程序可以通過指針訪問設備地址設備驅動程序接觸到的還是虛擬地址,但對于外界設備有固定的設備地址映射(設備的地址在移植Linux時候確定)物理內存地址空間設備驅動程序虛擬地址映射設備地址空間設備地址映射設備驅動程序虛擬地址映射設備地址映射設備驅動程序內訪問設備地址設備驅動程序可以通過指針訪問設備地11直接訪問IO端口vs設備驅動程序IO直接訪問用戶態程序編寫/調試簡單查詢模式,響應慢設備共享管理困難設備驅動訪問核心態編程調試困難可用中斷模式訪問、快設備共享管理簡單(由內核幫助完成)直接訪問IO端口vs設備驅動程序IO直接訪問設備驅動訪問12設備分類字符設備鼠標、串口、游戲桿塊設備磁盤、打印機網絡設備由BSDSocket訪問設備分類字符設備13字符設備vs塊設備字符設備字符設備發出讀/寫請求時,對應的硬件I/O一般立即發生。數據緩沖可有可無ADC/DAC、按鈕、LED、傳感器等塊設備利用一塊系統內存作緩沖區,一般讀寫由緩沖區直接提供,盡量減少IO操作針對磁盤等慢速設備字符設備vs塊設備字符設備塊設備14可裝卸的設備驅動程序和
靜態連接到內核的設備驅動程序靜態連接到內核的設備驅動程序修改配置文件、重新編譯和安裝內核可裝卸的設備驅動程序insmod 裝載rmmod
卸載lsmod
查詢可裝卸的設備驅動程序和
靜態連接到內核的設備驅動程序靜態連接15Linux對硬件設備的抽象
設備文件Open/Close/Read/Write例子/dev/mouse/dev/lp0Linux對硬件設備的抽象 設備文件16驅動程序與設備文件設備驅動程序設備文件用mknod
命令創建用insmod命令安裝,或直接編譯到內核中用戶程序用open/read/write/close等命令訪問通過主設備號找到設備驅動驅動程序與設備文件設備驅動程序設備用mknod
命令創建用i17驅動程序代碼結構驅動程序注冊與注銷設備文件的操作函數(*open)()(*write)()(*flush)()(*llseek)()…中斷服務程序驅動程序代碼結構驅動程序注冊與注銷設備文件的操作函數中斷服務18LED設備驅動程序的例子CPULED設備驅動程序的例子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得到裝入內核的主設備號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復雜的設備驅動程序驅動程序注冊與注銷(注冊/注銷設備、中斷)設備文件的操作函數(*open)()(*write)()(*flush)()(*llseek)()…中斷服務程序內核數據緩沖區用戶數據空間復雜的設備驅動程序驅動程序注冊與注銷設備文件的操作函數中斷服28復雜設備驅動程序的例子
(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復雜設備驅動程序的例子
(USBDevice)中斷資源申請29中斷服務程序
沒有返回參數簡短快速voidusb_ep1_int(intirq,
void*dev_id,
structpt_regs*regs)
{
//…
}中斷服務程序沒有返回參數30數據接收中斷服務程序voidusb_ep1_int(intirq,
void*dev_id,
structpt_regs*regs)
{
read_data_from_hardware_FIFO();
put_data_into_data_buffer();}數據接收中斷服務程序voidusb_ep1_int(int31數據發送中斷服務程序voidusb_ep2_int(intirq,
void*dev_id,
structpt_regs*regs)
{
read_data_from_buffer();
send_data_hardware_FIFO();}數據發送中斷服務程序voidusb_ep2_int(int32設備文件接口函數(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);設備文件接口函數(read)ssize_tusb_ep1_33設備文件接口函數
(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);設備文件接口函數
(read,blockingmode)34設備文件接口函數(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);設備文件接口函數(write)ssize_tusb_ep235內存申請malloc?Xkmallockfreevmallocvfree內存申請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同一設備驅動管理幾個接口SerialPort
DeviceDriverUART0UART0應用程序同一設備驅動管理幾個接口SerialPort
Devic38同一設備驅動管理幾個接口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))
{…}}同一設備驅動管理幾個接口intdev_open(struc39Linux設備驅動程序docin/sundae_mengLinux設備驅動程序docin/sundae_meng40內容設備分類設備驅動程序的框架字符型設備網絡設備文件系統UserSpaceFileSystemUSB設備FrameBuffer例子和使用Debug原理和Debug方法常用設備/fb/ram/loopback/zero內容設備分類41設備驅動程序的任務設備初始化硬件操作和管理外部硬件和內核空間的數據傳遞內核空間和用戶空間的數據傳遞設備驅動程序的任務設備初始化42設備驅動程序的功能外部硬件設備驅動程序用戶程序存儲緩沖用戶空間內核空間設備驅動程序的功能外部硬件設備驅動程序用戶程序存儲緩沖用戶空43用戶態程序vs內核態程序用戶程序權限受限虛擬運行環境邏輯地址關鍵資源訪問受監管函數調用由用戶控制內核程序最高權限實際的運行環境物理地址可訪問所有資源函數由內核直接調用可以運行驅動程序設備操作和管理能運行在用戶態嗎?用戶態程序vs內核態程序用戶程序內核程序設備操作和管理能44地址映射與物理地址訪問物理地址空間用戶進程1用戶進程2用戶進程3虛擬地址映射用戶利用指針訪問的是虛地址,不是物理地址,IO設備的物理地址可能是用戶進程不可觸及的虛擬地址映射虛擬地址映射地址映射與物理地址訪問物理地址空間用戶進程1用戶進程2用戶進45直接訪問內核內存(/dev/kmem)kmfd
=
open("/dev/kmem",
O_RDONLY
);
lseek(
kmfd,
offset,
SEEK_SET
);
read(
kmfd,
byteArray,
byteArrayLen
);
close(kmfd);直接訪問內核地址(內核態的虛地址)一般內核地址起始于0xC0000000直接訪問內核內存(/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將文件中的數據映射成數組這里是將物理內存(由特殊文件/dev/mem訪問)映射成指針b指向的數組。注意,指針b的值不一定是0xA0000,它是和物理地址0xA0000對應的用戶態的虛擬地址Linux中/dev/mem主要是用于設備內存的訪問(比如顯卡內存),而不是普通存儲器直接訪問物理地址(/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因為它們有數據緩沖,對讀寫操作不是立即完成的直接訪問IO端口(/dev/port)port_fd
=
o48outb()/outw()/inb()/inw()函數#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()函數#in49設備驅動程序內訪問設備地址設備驅動程序可以通過指針訪問設備地址設備驅動程序接觸到的還是虛擬地址,但對于外界設備有固定的設備地址映射(設備的地址在移植Linux時候確定)物理內存地址空間設備驅動程序虛擬地址映射設備地址空間設備地址映射設備驅動程序虛擬地址映射設備地址映射設備驅動程序內訪問設備地址設備驅動程序可以通過指針訪問設備地50直接訪問IO端口vs設備驅動程序IO直接訪問用戶態程序編寫/調試簡單查詢模式,響應慢設備共享管理困難設備驅動訪問核心態編程調試困難可用中斷模式訪問、快設備共享管理簡單(由內核幫助完成)直接訪問IO端口vs設備驅動程序IO直接訪問設備驅動訪問51設備分類字符設備鼠標、串口、游戲桿塊設備磁盤、打印機網絡設備由BSDSocket訪問設備分類字符設備52字符設備vs塊設備字符設備字符設備發出讀/寫請求時,對應的硬件I/O一般立即發生。數據緩沖可有可無ADC/DAC、按鈕、LED、傳感器等塊設備利用一塊系統內存作緩沖區,一般讀寫由緩沖區直接提供,盡量減少IO操作針對磁盤等慢速設備字符設備vs塊設備字符設備塊設備53可裝卸的設備驅動程序和
靜態連接到內核的設備驅動程序靜態連接到內核的設備驅動程序修改配置文件、重新編譯和安裝內核可裝卸的設備驅動程序insmod 裝載rmmod
卸載lsmod
查詢可裝卸的設備驅動程序和
靜態連接到內核的設備驅動程序靜態連接54Linux對硬件設備的抽象
設備文件Open/Close/Read/Write例子/dev/mouse/dev/lp0Linux對硬件設備的抽象 設備文件55驅動程序與設備文件設備驅動程序設備文件用mknod
命令創建用insmod命令安裝,或直接編譯到內核中用戶程序用open/read/write/close等命令訪問通過主設備號找到設備驅動驅動程序與設備文件設備驅動程序設備用mknod
命令創建用i56驅動程序代碼結構驅動程序注冊與注銷設備文件的操作函數(*open)()(*write)()(*flush)()(*llseek)()…中斷服務程序驅動程序代碼結構驅動程序注冊與注銷設備文件的操作函數中斷服務57LED設備驅動程序的例子CPULED設備驅動程序的例子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得到裝入內核的主設備號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復雜的設備驅動程序驅動程序注冊與注銷(注冊/注銷設備、中斷)設備文件的操作函數(*open)()(*write)()(*flush)()(*llseek)()…中斷服務程序內核數據緩沖區用戶數據空間復雜的設備驅動程序驅動程序注冊與注銷設備文件的操作函數中斷服67復雜設備驅動程序的例子
(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復雜設備驅動程序的例子
(USBDevice)中斷資源申請68中斷服務程序
沒有返回參數簡短快速voidusb_ep1_int(intirq,
void*dev_id,
structpt_regs*regs)
{
//…
}中斷服務程序沒有返回參數69數據接收中斷服務程序voidusb_ep1_int(intirq,
void*dev_id,
structpt_regs*regs)
{
read_data_from_hardware_FIFO();
put_data_into_data_buffer();}數據接收中斷服務程序voidusb_ep1_int(int70數據發送中斷服務程序voidusb_ep2_int(intirq,
void*dev_id,
structpt_regs*regs)
{
read_data_from_buffer();
send_data_hardware_FIFO();}數據發送中斷服務程序voidusb_ep2_int(int71設備文件接口函數(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);設備文件接口函數(read)ssize_tusb_ep1_72設備文件接口函數
(read,blockingmode)ssize_tusb_ep1_read(structfile*filp,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 代理進口報關 合同標準文本
- 英語口語能力提升計劃
- 出售西苑車庫合同樣本
- 2025年蘇教版六年級下冊課題研究教學計劃
- 包裝供應合同標準文本
- 包廠合作合同樣本
- 辦公場地裝修合同標準文本
- 糖尿病患者內科護理計劃
- 買賣船合同樣本
- 基于集成學習和融合方法的鋰離子電池健康狀態預測
- 《基于stm32的窗簾控制系統設計與實現》14000字(論文)
- 大型活動期間的公路養護應急預案
- 國內外小學音樂跨學科教學的研究現狀
- 教堂寺廟租賃合同協議
- 防范遏制礦山領域重特大生產安全事故硬措施解讀
- 河南省洛陽市澗西區2024-2025學年八年級上學期期中考試數學試題
- 社會認知理論發展
- 管道完整性管理培訓
- 小學全體教師安全工作培訓
- 19G522-1鋼筋桁架混凝土樓板圖集
- 律師事務所薪酬分配制度
評論
0/150
提交評論