打印

zynq下UIO中断

[复制链接]
1649|3
手机看帖
扫描二维码
随时随地手机跟帖
沙发
zhangmangui|  楼主 | 2018-11-28 22:53 | 只看该作者
Uio即是user space I/O,用户空间驱动的简称, 可以运行在用户空间写硬件驱动。
   
     硬件设备可以根据功能分为网络设备,块设备,字符设备,或者根据与CPU相连的方式 分为PCI设备,USB设备等。它们被不同的内核子系统支持。这些标准的设备的驱动编写 较为容易而且容易维护。很容易加入主内核源码树。但是,又有很多设备难以划分到这些子系统中,比如I/O卡,现场总线接口或者定制的FPGA。  
     
     通常这些非标准设备的驱动被实现为字符驱动。这些驱动使用了很多内核内部函数和宏。 而这些内部函数和宏是变化的。这样驱动的编写者必须编写一个完全的内核驱动,而且一直维护这些代码。而且这些驱动进不了主内核源码。于是就出现了用户空间I/O框架(Userspace I/O framework)。  

UIO 的工作原理:
     UIO分成2个部分,主要是内核部分和用户空间部分, 在内核部分主要是实现硬件寄存器的内存映射(struct uio_info -> struct uio_mem)及读写操作, 在用户空间部分,将uio设备的uio_mem映射到本地(mmap), 这样就可以实现在用户空间访问硬件设备寄存器的目的, 再通过设备的控制逻辑,就可以实现硬件设备的驱动。  
     
     一个UIO设备驱动的主要任务有两个:
         
         1. 存取设备的内存 UIO 核心实现了mmap()可以处理物理内存(physical memory),逻辑内存(logical memory),虚拟内存(virtual memory)。UIO驱动的编写是就不需要再考虑这些繁琐的细节。 如果有些设备的总线不是PCI总线, 那么仍需要做相关的处理   
         
         2. 处理设备产生的中断 对于设备中断的应答必须在内核空间进行。所以在内核空间有一小部分代码 用来应答中断和禁止中断,但是其余的工作全部留给用户空间处理。  

               如果用户空间要等待一个设备中断,它只需要简单的阻塞在对 /dev/uioX的read()操作上。当设备产生中断时,read()操作立即返回。UIO 也实现了poll()系统调用,你可以使用  select()来等待中断的发生。select()有一个超时参数可以用来实现有限时间内等待中断。   

             对设备的控制还可以通过/sys/class/uio下的各个文件的读写来完成。你注册的uio设备将会出现在该目录下。假如你的uio设备是uio0那么映射的设备内存文件出现在 /sys/class/uio/uio0/maps/mapX,对该文件的读写就是对设备内存的读写。   

         如下的图描述了uio驱动的内核部分,用户空间部分,和uio 框架以及内核内部函数的关系。      

UIO的具体实现  
     UIO内核部分  
     一个uio驱动的注册过程简单点说有两个步骤:
        1. 初始化设备相关的 uio_info结构。 uio_info包括了name, open(),release(), mmap(),  struct uio_mem等  
         
         2. 调用uio_register_device 分配并注册一个uio设备。 uio核心字符设备注册的函数有: uio_open,uio_fasync,uio_release,uio_poll,uio_read, uio_write 当用户空间访问该uio设备的时候, 就会调用这些接口  
         
         3, Uio核心除了完成相关的维护工作外,还调用了注册在uio_info中的相关方法进行初始化。  

     Uio用户空间部分
    通过open,mmap, write read等函数与内核空间交互, 间接和硬件的寄存器交互。 在内核空间驱动中所描述的内存区域uio_mem可以通过mmap()调用映射到用户空间中。 同时根据设备的使用规则,就可以编写驱动了  
     
     设备中断处理
     在__uio_register_device中,为uio设备注册了统一的中断处理函数uio_interrupt, 在该函数中,调用了uio设备自己提供的中断处理函数handler(uio_info结构中)。 并调用了uio_event_notify函数对uio设备的中断事件计数器(listener)增一, 通知各个读进程 “有数据可读”。每个uio设备的中断处理函数都是单独注册的。  
     
     用户空间调用poll/(uio_poll)操作判断是否有数据可读的依据就是 listener中的中断事件计数值(event_count)和uio设备中的中断事件计数器值不一致(前者小于后者)。因为listener的值除了在执行文件打开操作时被置为被赋值外,只在uio_read操作中被更新为uio设备的中断事件计数器值。              

使用特权

评论回复
板凳
zhangmangui|  楼主 | 2018-11-28 22:58 | 只看该作者
ZYNQ中的UIO驱动和中断程序学习【Xilinx-Petalinux学习】
这篇博客很有帮助

使用特权

评论回复
发新帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

934

主题

26373

帖子

585

粉丝