Linux设备驱动程序.ppt

上传人:sccc 文档编号:5789689 上传时间:2023-08-20 格式:PPT 页数:39 大小:492.01KB
返回 下载 相关 举报
Linux设备驱动程序.ppt_第1页
第1页 / 共39页
Linux设备驱动程序.ppt_第2页
第2页 / 共39页
Linux设备驱动程序.ppt_第3页
第3页 / 共39页
Linux设备驱动程序.ppt_第4页
第4页 / 共39页
Linux设备驱动程序.ppt_第5页
第5页 / 共39页
点击查看更多>>
资源描述

《Linux设备驱动程序.ppt》由会员分享,可在线阅读,更多相关《Linux设备驱动程序.ppt(39页珍藏版)》请在三一办公上搜索。

1、Linux设备驱动程序,http:/,内容,设备分类设备驱动程序的框架字符型设备网络设备文件系统User Space File SystemUSB设备FrameBuffer例子和使用Debug原理和Debug方法常用设备/fb/ram/loopback/zero,设备驱动程序的任务,设备初始化硬件操作和管理外部硬件和内核空间的数据传递内核空间和用户空间的数据传递,设备驱动程序的功能,外部硬件,设备驱动程序,用户程序,存储缓冲,用户空间,内核空间,用户态程序 vs 内核态程序,用户程序权限受限虚拟运行环境逻辑地址关键资源访问受监管函数调用由用户控制,内核程序最高权限实际的运行环境物理地址可访问所

2、有资源函数由内核直接调用 可以运行驱动程序,设备操作和管理能运行在用户态吗?,地址映射与物理地址访问,物理地址空间,用户进程1,用户进程2,用户进程3,虚拟地址映射,用户利用指针访问的是虚地址,不是物理地址,IO设备的物理地址可能是用户进程不可触及的,虚拟地址映射,虚拟地址映射,直接访问内核内存(/dev/kmem),kmfd=open(/dev/kmem,O_RDONLY);lseek(kmfd,offset,SEEK_SET);read(kmfd,byteArray,byteArrayLen);close(kmfd);,直接访问内核地址(内核态的虚地址)一般内核地址起始于0 xC00000

3、00,直接访问物理地址(/dev/mem),mem_fd=open(/dev/mem,O_RDONLY);b=mmap(0,0 x10000,PROT_READ|PROT_WRITE,MAP_SHARED,mem_fd,0 xA0000)close(memfd);,0 xA0000,0 xB0000,Pointer b,mmap将文件中的数据映射成数组这里是将物理内存(由特殊文件/dev/mem访问)映射成指针b指向的数组。注意,指针b的值不一定是0 xA0000,它是和物理地址0 xA0000对应的用户态的虚拟地址Linux中/dev/mem主要是用于设备内存的访问(比如显卡内存),而不是普

4、通存储器,直接访问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因为它们有数据缓冲,对读写操作不是立即完成的,outb()/outw()/inb()/inw()函数,#include#include#include#define BASEPORT 0 x378/printerint main()ioperm(BASEPORT,

5、3,1);/get access permission outb(0,BASEPORT);usleep(100000);printf(status:%dn,inb(BASEPORT+1);ioperm(BASEPORT,3,0);/give up exit(0);,ioperm(from,num,turn_on)用ioperm申请的操作端口地址在0 x0000 x3FF,利用iopl()可以申请所有的端口地址必须以root运行用“gcc-02 o xxx.elf xxx.c”编译,outb(value,port);inb(port);/8-bitoutw(value,port);inw(por

6、t);/16-bit访问时间大约1us,设备驱动程序内访问设备地址,设备驱动程序可以通过指针访问设备地址设备驱动程序接触到的还是虚拟地址,但对于外界设备有固定的设备地址映射(设备的地址在移植Linux时候确定),物理内存地址空间,设备驱动程序,虚拟地址映射,设备地址空间,设备地址映射,设备驱动程序,虚拟地址映射,设备地址映射,直接访问IO端口 vs 设备驱动程序,IO直接访问用户态程序编写/调试简单查询模式,响应慢设备共享管理困难,设备驱动访问核心态编程调试困难可用中断模式访问、快设备共享管理简单(由内核帮助完成),设备分类,字符设备鼠标、串口、游戏杆块设备磁盘、打印机网络设备由BSD Soc

7、ket访问,字符设备 vs 块设备,字符设备字符设备发出读/写请求时,对应的硬件I/O一般立即发生。数据缓冲可有可无ADC/DAC、按钮、LED、传感器等,块设备利用一块系统内存作缓冲区,一般读写由缓冲区直接提供,尽量减少IO操作针对磁盘等慢速设备,可装卸的设备驱动程序和静态连接到内核的设备驱动程序,静态连接到内核的设备驱动程序修改配置文件、重新编译和安装内核可装卸的设备驱动程序insmod装载rmmod卸载lsmod查询,Linux对硬件设备的抽象,设备文件Open/Close/Read/Write例子/dev/mouse/dev/lp0,驱动程序与设备文件,设备驱动程序,设备文件,用mkn

8、od命令创建,用insmod命令安装,或直接编译到内核中,用户程序,用open/read/write/close等命令访问,通过主设备号找到设备驱动,驱动程序代码结构,驱动程序注册与注销,设备文件的操作函数(*open)()(*write)()(*flush)()(*llseek)(),中断服务程序,LED设备驱动程序的例子,CPU,struct file_operations LED_fops=read:LED_read,write:LED_write,open:LED_open,release:LED_release,;int LED_init_module(void)SET_MODULE

9、_OWNER(,程序列表(1),程序列表(2),int LED_open(struct inode*inode,struct file*filp)printk(LED_open()n);MOD_INC_USE_COUNT;return 0;int LED_release(struct inode*inode,struct file*filp)printk(“LED_release()n“);MOD_DEC_USE_COUNT;return 0;,程序列表(3),ssize_t LED_read(struct file*filp,char*buf,size_t count,loff_t*f_po

10、s)int i;for(i=0;iLED_on();else Data-LED_off();return count;,(*(volatile unsigned int*)(0 xXXXXXXXX)|=MASK;(*(volatile unsigned int*)(0 xXXXXXXXX),#ifndef _KERNEL_#define _KERNEL_#endif#ifndef MODULE#define MODULE#endif#include#include#include#include#include#include#include#include#include#include#i

11、nclude#include#include#include#include#include#include#include MODULE_AUTHOR(Rendong Ying);int LED_major,LED_status;,程序列表(4),头文件,程序编译(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-DCO

12、NFIG_KERNELD-DMODULE-D_KERNEL_-DLinux-nostdinc-I-I.-I$(INCLUDE)-idirafter$(LIB_INC)LED.o:LED.c$(CC)$(CFLAGS)-c LED.cclean:rm-f LED.o,生成o文件,设备装载和设备文件建立,chmod+x/tmp/LED.o/sbin/insmod-f./LED.ocat/proc/devices得到装入内核的主设备号mknod/dev/Lamp c Num1 Num2Num1为主设备号Num2为次设备号,强制安装,忽略版本检查,设备的测试和使用,命令行echo 8/proc/sys

13、/kernel/printkcat/dev/Lamp cat/dev/Lamp 程序void main()int fd=open(“/dev/Lamp,O_RDWR);write(fd,开启printk,也可以从/var/log/messages看printk的记录,设备卸载,/sbin/rmmod LEDrm-f/dev/Lamp,Function ofMOD_INC_USE_COUNT;MOD_DEC_USE_COUNT;,复杂的设备驱动程序,驱动程序注册与注销(注册/注销 设备、中断),设备文件的操作函数(*open)()(*write)()(*flush)()(*llseek)(),中

14、断服务程序,内核数据缓冲区,用户数据空间,复杂设备驱动程序的例子(USB Device),中断资源申请和释放if(request_irq(USB_INTR_SOURCE1,usb_ep1_int,SA_INTERRUPT,USB EP1,0)0)printk(Int.req.failed!n);free_irq(USB_INTR_SOURCE0,0);,cat/proc/interrupts,中断服务程序,没有返回参数 简短快速void usb_ep1_int(int irq,void*dev_id,struct pt_regs*regs)/,数据接收中断服务程序,void usb_ep1_i

15、nt(int irq,void*dev_id,struct pt_regs*regs)read_data_from_hardware_FIFO();put_data_into_data_buffer();,数据发送中断服务程序,void usb_ep2_int(int irq,void*dev_id,struct pt_regs*regs)read_data_from_buffer();send_data_hardware_FIFO();,设备文件接口函数(read),ssize_t usb_ep1_read(struct file*filp,char*buf,size_t count,lof

16、f_t*f_pos)if(data_buffer_empty()return 0;else copy_data_to_user_space();return data_copyed;,copy_to_user(user_buf,device_driver_buf,size);,设备文件接口函数(read,blocking mode),ssize_t usb_ep1_read(struct file*filp,char*buf,size_t count,loff_t*f_pos)while(device_driver_buf_empty()if(wait_event_interruptible(

17、q_ep2,device_driver_buf_not_empty)return-ERESTARTSYS;copy_data_to_user_space();return data_copyed;,wait_queue_head_t rq_EP2;init_waitqueue_head(,设备文件接口函数(write),ssize_t usb_ep2_write(struct file*filp,char*buf,size_t count,loff_t*f_pos)if(data_buffer_full()return 0;else copy_data_to_device_driver_buf

18、();if(no_transmission_now)send_1st_data();return data_copyed;,copy_from_user(device_driver_buf,user_buf,size);,内存申请,malloc?Xkmallockfreevmallocvfree,禁止设备打开多次,int LED_flag;int LED_init_module(void)LED_flag=0;int LED_open(struct inode*inode,struct file*filp)if(LED_flag=0)LED_flag=1;MOD_INC_USE_COUNT;r

19、eturn 0;else return-ENODEV;int LED_release(struct inode*inode,struct file*filp)LED_flag=0;MOD_DEC_USE_COUNT;return 0;,同一设备驱动管理几个接口,Serial Port Device Driver,UART 0,UART 0,应用程序,同一设备驱动管理几个接口,int dev_open(struct inode*inode,struct file*filp)int minor=MINOR(inode-i_rdev);filp-private_data=sub_dev_datminor;ssize_t dev_write(struct file*filp,const char*buf,size_t count,loff_t*f_pos)switch(*(filp-private_data),

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号