Linux设备驱动程序课件.ppt

上传人:小飞机 文档编号:3757079 上传时间:2023-03-20 格式:PPT 页数:40 大小:1.24MB
返回 下载 相关 举报
Linux设备驱动程序课件.ppt_第1页
第1页 / 共40页
Linux设备驱动程序课件.ppt_第2页
第2页 / 共40页
Linux设备驱动程序课件.ppt_第3页
第3页 / 共40页
Linux设备驱动程序课件.ppt_第4页
第4页 / 共40页
Linux设备驱动程序课件.ppt_第5页
第5页 / 共40页
点击查看更多>>
资源描述

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

1、,Linux设备驱动程序,内容,设备分类设备驱动程序的框架字符型设备网络设备文件系统User Space File SystemUSB设备FrameBuffer例子和使用Debug原理和Debug方法常用设备/fb/ram/loopback/zero,直接访问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因为它们有数据缓冲,对

2、读写操作不是立即完成的,outb()/outw()/inb()/inw()函数,#include#include#include#define BASEPORT 0 x378/printerint main()ioperm(BASEPORT,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 x00

3、00 x3FF,利用iopl()可以申请所有的端口地址必须以root运行用“gcc-02 o xxx.elf xxx.c”编译,outb(value,port);inb(port);/8-bitoutw(value,port);inw(port);/16-bit访问时间大约1us,设备驱动程序内访问设备地址,设备驱动程序可以通过指针访问设备地址设备驱动程序接触到的还是虚拟地址,但对于外界设备有固定的设备地址映射(设备的地址在移植Linux时候确定),物理内存地址空间,设备驱动程序,虚拟地址映射,设备地址空间,设备地址映射,设备驱动程序,虚拟地址映射,设备地址映射,直接访问IO端口 vs 设备驱

4、动程序,IO直接访问用户态程序编写/调试简单查询模式,响应慢设备共享管理困难,设备驱动访问核心态编程调试困难可用中断模式访问、快设备共享管理简单(由内核帮助完成),设备分类,字符设备鼠标、串口、游戏杆块设备磁盘、打印机网络设备由BSD Socket访问,字符设备 vs 块设备,字符设备字符设备发出读/写请求时,对应的硬件I/O一般立即发生。数据缓冲可有可无ADC/DAC、按钮、LED、传感器等,块设备利用一块系统内存作缓冲区,一般读写由缓冲区直接提供,尽量减少IO操作针对磁盘等慢速设备,可装卸的设备驱动程序和静态连接到内核的设备驱动程序,静态连接到内核的设备驱动程序修改配置文件、重新编译和安装

5、内核可装卸的设备驱动程序insmod装载rmmod卸载lsmod查询,Linux对硬件设备的抽象,设备文件Open/Close/Read/Write例子/dev/mouse/dev/lp0,驱动程序与设备文件,设备驱动程序,设备文件,用mknod命令创建,用insmod命令安装,或直接编译到内核中,用户程序,用open/read/write/close等命令访问,通过主设备号找到设备驱动,驱动程序代码结构,驱动程序注册与注销,设备文件的操作函数(*open)()(*write)()(*flush)()(*llseek)(),中断服务程序,LED设备驱动程序的例子,CPU,struct file

6、_operations LED_fops=read:LED_read,write:LED_write,open:LED_open,release:LED_release,;int LED_init_module(void)SET_MODULE_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(

7、“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_pos)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_#

8、endif#ifndef MODULE#define MODULE#endif#include#include#include#include#include#include#include#include#include#include#include#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-linu

9、x-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)-c LED.cclean:rm-f LED.o,生成o文件,设备装载和设备文件建立,chmod+x/tmp/LED.o/sbin/insmo

10、d-f./LED.ocat/proc/devices得到装入内核的主设备号mknod/dev/Lamp c Num1 Num2Num1为主设备号Num2为次设备号,强制安装,忽略版本检查,设备的测试和使用,命令行echo 8/proc/sys/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 of

11、MOD_INC_USE_COUNT;MOD_DEC_USE_COUNT;,复杂的设备驱动程序,驱动程序注册与注销(注册/注销 设备、中断),设备文件的操作函数(*open)()(*write)()(*flush)()(*llseek)(),中断服务程序,内核数据缓冲区,用户数据空间,复杂设备驱动程序的例子(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);,c

12、at/proc/interrupts,中断服务程序,没有返回参数 简短快速void usb_ep1_int(int irq,void*dev_id,struct pt_regs*regs)/,数据接收中断服务程序,void usb_ep1_int(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_dat

13、a_from_buffer();send_data_hardware_FIFO();,设备文件接口函数(read),ssize_t usb_ep1_read(struct file*filp,char*buf,size_t count,loff_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

14、_ep1_read(struct file*filp,char*buf,size_t count,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();return data_copyed;,wait_queue_head_t rq_EP2;init_waitqueue_head(,设备文件接口函数(write),ssize_t usb_ep2_wr

15、ite(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();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_

16、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;return 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),40,结束语,谢谢大家聆听!,

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号