Linux设备驱动程序课件

PPT
  • 阅读 67 次
  • 下载 0 次
  • 页数 38 页
  • 大小 180.740 KB
  • 2022-11-13 上传
  • 收藏
  • 违规举报
  • © 版权认领
下载文档25.00 元 加入VIP免费下载
此文档由【小橙橙】提供上传,收益归文档提供者,本网站只提供存储服务。若此文档侵犯了您的版权,欢迎进行违规举报版权认领
Linux设备驱动程序课件
可在后台配置第一页与第二页中间广告代码
Linux设备驱动程序课件
可在后台配置第二页与第三页中间广告代码
Linux设备驱动程序课件
可在后台配置第三页与第四页中间广告代码
Linux设备驱动程序课件
Linux设备驱动程序课件
还剩10页未读,继续阅读
【这是免费文档,您可以免费阅读】
/ 38
  • 收藏
  • 违规举报
  • © 版权认领
下载文档25.00 元 加入VIP免费下载
文本内容

【文档说明】Linux设备驱动程序课件.pptx,共(38)页,180.740 KB,由小橙橙上传

转载请保留链接:https://www.ichengzhen.cn/view-7171.html

以下为本文档部分文字说明:

内容•设备分类•设备驱动程序的框架•字符型设备•网络设备•文件系统–UserSpaceFileSystem•USB设备•FrameBuffer例子和使用•Debug原理和Debug方法•常用设备/fb/ram/loopback/zero设备驱动程序的

任务•设备初始化•硬件操作和管理•外部硬件和内核空间的数据传递•内核空间和用户空间的数据传递设备驱动程序的功能外部硬件设备驱动程序用户程序存储缓冲用户空间内核空间用户态程序vs内核态程序用户程序•权限受限•虚拟运行环境–

逻辑地址–关键资源访问受监管•函数调用由用户控制内核程序•最高权限•实际的运行环境–物理地址–可访问所有资源•函数由内核直接调用可以运行驱动程序地址映射与物理地址访问物理地址空间用户进程1用户进程2用户进程3虚拟地址映射用户利用指针访问的是

虚地址,不是物理地址,IO设备的物理地址可能是用户进程不可触及的虚拟地址映射虚拟地址映射直接访问内核内存(/dev/kmem)kmfd=open("/dev/kmem",O_RDONLY);lseek(kmfd,offset,SEEK_SET);read(km

fd,byteArray,byteArrayLen);close(kmfd);•直接访问内核地址(内核态的虚地址)•一般内核地址起始于0xC0000000直接访问物理地址(/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主要是用于设备

内存的访问(比如显卡内存),而不是普通存储器直接访问IO端口(/dev/port)port_fd=open("/dev/port",O_RDWR);lseek(port_fd,port_addr,SEEK_SET);read(port_fd,…);writ

e(port_fd,…);close(port_fd);•注意:不能用fopen/fread/fwrite/fclose因为它们有数据缓冲,对读写操作不是立即完成的outb()/outw()/inb()/inw()函数#i

nclude<stdio.h>#include<unistd.h>#include<asm/io.h>#defineBASEPORT0x378//printerintmain(){ioperm(BASEPORT,3,

1));//getaccesspermissionoutb(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-bit•outw(value,port);inw(port);//16-bit•访问时间大约1us设备驱动程序内访问设备地址•设备驱动程序可以通过指针访问设备地址•设备

驱动程序接触到的还是虚拟地址,但对于外界设备有固定的设备地址映射(设备的地址在移植Linux时候确定)物理内存地址空间设备驱动程序虚拟地址映射设备地址空间设备地址映射设备驱动程序虚拟地址映射设备地址映射直接访问IO端口vs设备驱动程序IO直接访问•用户态•程序编写/调试简单•查询模

式,响应慢•设备共享管理困难设备驱动访问•核心态•编程调试困难•可用中断模式访问、快•设备共享管理简单(由内核帮助完成)设备分类•字符设备–鼠标、串口、游戏杆•块设备–磁盘、打印机•网络设备–由BSDSocket访问字符设备vs块设备字

符设备•字符设备发出读/写请求时,对应的硬件I/O一般立即发生。•数据缓冲可有可无•ADC/DAC、按钮、LED、传感器等块设备•利用一块系统内存作缓冲区,一般读写由缓冲区直接提供,尽量减少IO操作•针对磁盘等慢速设备可装卸的设备驱动程序和静态连接到内核的设备驱动程序•静态连接到内

核的设备驱动程序–修改配置文件、重新编译和安装内核•可装卸的设备驱动程序–insmod装载–rmmod卸载–lsmod查询Linux对硬件设备的抽象设备文件•Open/Close/Read/Write•例子–/dev/mouse–/dev/lp0驱动程序与设备文件设备驱动程序设备文件用m

knod命令创建用insmod命令安装,或直接编译到内核中用户程序用open/read/write/close等命令访问通过主设备号找到设备驱动驱动程序代码结构驱动程序注册与注销设备文件的操作函数(*open)()(*write)()(*flush)()(*l

lseek)()…中断服务程序LED设备驱动程序的例子CPUstructfile_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_ini

t_module);module_exit(LED_cleanup_module);程序列表(1)程序列表(2)intLED_open(structinode*inode,structfile*filp){p

rintk("LED_open()\n");MOD_INC_USE_COUNT;return0;}intLED_release(structinode*inode,structfile*filp){printk(“LED_re

lease()\n“);MOD_DEC_USE_COUNT;return0;}程序列表(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;}(*((volatileuns

ignedint*)(0xXXXXXXXX)))|=MASK;(*((volatileunsignedint*)(0xXXXXXXXX)))&=~MASK;#ifndef__KERNEL__#define__KERNEL__#endif#ifndefM

ODULE#defineMODULE#endif#include<linux/config.h>#include<linux/module.h>#include<linux/sched.h>#include<linux/kernel.h>#include<linux/mall

oc.h>#include<linux/errno.h>#include<linux/types.h>#include<linux/interrupt.h>#include<linux/in.h>#include<linux/netde

vice.h>#include<linux/etherdevice.h>#include<linux/ip.h>#include<linux/tcp.h>#include<linux/skbuff.h>#include<sysdep.h>#include<linux/ioctl.h>#inclu

de<linux/in6.h>#include<asm/checksum.h>MODULE_AUTHOR("RendongYing");intLED_major,LED_status;程序列表(4)头文件程序编译(Makefile)CC=arm-elf-linux-gccLD=arm-el

f-linux-ldINCLUDE=/usr/local/src/bspLinux/includeLIB_INC=/usr/local/lib/gcc-lib/arm-elf-linux/2.95.3/includeCFLAGS=-O6-Wall-DCON

FIG_KERNELD-DMODULE-D__KERNEL__-DLinux-nostdinc-I--I.-I$(INCLUDE)-idirafter$(LIB_INC)LED.o:LED.c$(CC)$(CFL

AGS)-cLED.cclean:rm-fLED.o生成o文件设备装载和设备文件建立•chmod+x/tmp/LED.o•/sbin/insmod-f./LED.o•cat/proc/devices得到装入内核的主设备号•mknod/dev/LampcNum1Num2Num1为主设备号Num2为

次设备号强制安装,忽略版本检查设备的测试和使用•命令行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的记录设备卸载/sbin/rmmodLEDrm-f/dev/LampFunctionofMOD_INC_USE_COUNT

;MOD_DEC_USE_COUNT;复杂的设备驱动程序驱动程序注册与注销(注册/注销设备、中断)设备文件的操作函数(*open)()(*write)()(*flush)()(*llseek)()…中断服务程序

内核数据缓冲区用户数据空间复杂设备驱动程序的例子(USBDevice)中断资源申请和释放•if(request_irq(USB_INTR_SOURCE1,usb_ep1_int,SA_INTERRUPT,"USBE

P1",0)<0)printk("Int.req.failed!\n");•free_irq(USB_INTR_SOURCE0,0);cat/proc/interrupts中断服务程序•没有返回参数•简短快速voidusb_ep1

_int(intirq,void*dev_id,structpt_regs*regs){//…}数据接收中断服务程序voidusb_ep1_int(intirq,void*dev_id,structpt_reg

s*regs){read_data_from_hardware_FIFO();put_data_into_data_buffer();}数据发送中断服务程序voidusb_ep2_int(intirq,void*dev_id,structpt_regs*re

gs){read_data_from_buffer();send_data_hardware_FIFO();}设备文件接口函数(read)ssize_tusb_ep1_read(structfile*filp,char*buf,size_tcoun

t,loff_t*f_pos){if(data_buffer_empty())return0;elsecopy_data_to_user_space();returndata_copyed;}copy_to_use

r(user_buf,device_driver_buf,size);设备文件接口函数(read,blockingmode)ssize_tusb_ep1_read(structfile*filp,char*buf,size_tco

unt,loff_t*f_pos){while(device_driver_buf_empty()){if(wait_event_interruptible(q_ep2,device_driver_bu

f_not_empty))return-ERESTARTSYS;}copy_data_to_user_space();returndata_copyed;}wait_queue_head_trq_EP2;init_waitqueue_head(&rq_EP2);设备

文件接口函数(write)ssize_tusb_ep2_write(structfile*filp,char*buf,size_tcount,loff_t*f_pos){if(data_buffer_full())return0

;elsecopy_data_to_device_driver_buf();if(no_transmission_now)send_1st_data();returndata_copyed;}copy_from_user(device_driver_bu

f,user_buf,size);内存申请•malloc?X•kmalloc•kfree•vmalloc•vfree禁止设备打开多次intLED_flag;intLED_init_module(void){LED_flag=0;…}intL

ED_open(structinode*inode,structfile*filp){if(LED_flag=0){LED_flag=1;MOD_INC_USE_COUNT;return0;}elsereturn-ENOD

EV;}intLED_release(structinode*inode,structfile*filp){LED_flag=0;MOD_DEC_USE_COUNT;return0;}同一设备驱动管理几个接口Se

rialPortDeviceDriverUART0UART0应用程序同一设备驱动管理几个接口intdev_open(structinode*inode,structfile*filp){intminor=MINOR(inode->i_rdev);filp->pri

vate_data=sub_dev_dat[minor];…}ssize_tdev_write(structfile*filp,constchar*buf,size_tcount,loff_t*f_pos){switch(*(filp->private_data)){

…}}

小橙橙
小橙橙
文档分享,欢迎浏览!
  • 文档 25747
  • 被下载 7
  • 被收藏 0
相关资源
广告代码123
若发现您的权益受到侵害,请立即联系客服,我们会尽快为您处理。侵权客服QQ:395972555 (支持时间:9:00-21:00) 公众号
Powered by 太赞文库
×
确认删除?