这几天因为一个项目用回了zynq7020平台,需要用到PL端的中断,所以考虑使用Linux下的uio驱动。
虽然以前也用过UIO,但时间久了还是有点忘记了,所以记录一下使用的过程,方便以后回顾和方便各位看官。
UIO(Userspace I/O framework)其实就是Linux提供给用户空间进行底层I/O操作的方案,反正我是这么理解的。
在Linux中,用户空间一般不允许直接访问底层的I/O, 也就是不能直接访问物理地址的。想要访问物理地址,就需要将物理地址转换为虚拟地址。
最常用的方法就是mmap(), 将想要访问的地址使用mmap()这个系统调用映射为程序空间虚拟地址。所以,UIO的主要一个工作就是,将驱动程序指定的I/O地址使用mmap()进行地址映射。
至于中断,我们知道,在用户空间也是不能直接接收内核的中断的,所以,UIO也是做了一半的工作,UIO将驱动程序指定的中断进行注册和回调。当中断来临的时候,UIO将响应中断进行回调函数。但是,在回调函数中,UIO只是做了将中断屏蔽掉,剩下的处理和重新打开中断交给了用户空间。
核心部分可以参考uio_core.c。看完就应该大概明白个所以了,中断注册和响应写得非常巧妙,我就不做分析了,看看怎么用吧。
今天的主角:uio_pdrv_genirq
1、首先是配置内核支持UIO驱动。我使用的是petalinux,用和不用petalinux没啥关系,原理大概一样。
petalinux-config -c kernel
Device Drivers --->
<*> Userspace I/O drivers --->
<M>