12. Mapping Device Memory Details | 设备内存映射详解
-
Linux 的字符设备驱动框架提供了将设备内存映射到用户空间进程地址空间的能力
-
字符驱动程序可以实现用户空间应用程序可以调用的mmap()函数
-
mmap() 函数在调用进程的虚拟地址空间中创建一个新的映射
-
- 返回一个虚拟地址,对应于指定的物理地址
-
- 它还可以用于将文件映射到内存空间,以便通过内存读写访问文件的内容
-
每当用户空间程序在虚拟地址范围内读取或写入时,它都在访问设备
-
这提供了改进的性能,因为不需要系统调用
13. Mapping Device Memory Flow | 设备内存映射流程
14.User Space Application Interrupt Processing|用户空间应用程序中断处理
-
中断永远不会在用户空间中直接处理
-
中断可以由 UIO 内核驱动程序处理,然后通过 UIO 设备文件描述符将其中继到用户空间
-
想要在中断发生时得到通知的用户空间驱动程序调用 UIO 设备文件描述符上的 select() 或 read()
-
- 读取可以以阻塞或非阻塞模式完成
-
read() 返回事件数(中断)
-
线程可用于处理中断
-
或者,用户提供的内核驱动程序可以处理中断,然后通过其他机制(如共享内存)将数据传递给用户空间驱动程序
-
- 这对于具有非常快中断的设备可能是必要的
15. User Space Application Interrupt Processing Example | 用户空间应用程序中断处理示例
int未决 = 0 ;
int重新启用 = 1 ;
/*
* 1. UIO 设备如前所述打开
*/
int uio_fd = open( " /dev/uio0 " , O_RDWR);
/*
* 2. 读取UIO设备文件描述符等待中断,
* 默认读取块,也可以使用非阻塞读取
*
* 注意:pending变量包含中断次数有
个 * 如果多个
*/
read(uio_fd, ( void *)&pending, sizeof ( int ));
//
//添加设备特定处理,例如在此处确认设备中的中断
//
/*
* 3. 在中断控制器级别重新启用中断
*/
write(uio_fd, ( void *)&reenable, sizeof ( int ));
第二部分:具有用户空间应用程序和内核空间驱动程序的高级 UIO
16. UIO Driver Details | UIO驱动详解
-
用户提供内核驱动和用户空间驱动
-
内核空间驱动程序是从设备树配置并注册UIO设备的平台驱动程序
-
内核空间驱动程序还可以在内核空间提供中断处理程序
-
用户空间驱动程序可以直接访问硬件
17. Kernel UIO API - Basics | 内核UIO API基础
-
The API is small and simple to use API小且易用
struct uio_info
-- name : 设备名
-- version : 设备驱动程序版本
-- irq : 中断号
-- irq_flags : request_irq()
的标志-- handler : 驱动程序 irq 处理程序(可选)
-- mem[] : 可以使用的内存区域映射到用户空间
o addr:内存地址
o memtype:内存区域的类型(物理、逻辑、虚拟)
18. Kernel UIO API - Registration | 内核UIO API - 注册
-
函数uio_register_device()将驱动程序连接到 UIO 框架
-
需要一个 struct uio_info 作为输入
-
通常从平台设备驱动程序的 probe() 函数调用
-
创建设备文件 /dev/uio# (#starting from 0) 和所有相关的 sysfs 文件属性
-
函数 uio_unregister_device() 断开驱动程序与 UIO 框架的连接
-
通常从平台设备驱动程序的清理函数调用
-
删除设备文件 /dev/uio#
19. Kernel Space Driver Example | 内核空间驱动示例
probe()
{
/*
* 1. driver probe()函数中的平台设备驱动初始化
*/
dev = devm_kzalloc(&pdev->dev, ( sizeof ( struct uio_timer_dev)), GFP_KERNEL);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0 );
dev->regs = devm_ioremap_resource(&pdev-> dev, res);
irq = platform_get_irq(pdev, 0 );
/*
* 2. 添加基本UIO结构初始化
*/
开发->uio_info.name = “ uio_timer ” ;
开发->uio_info.version = 1 ;
开发- >uio_info.priv =开发;
/*
* 3. 添加UIO
的内存区域初始化 */
dev->uio_info.mem[ 0 ].name = " registers " ;
dev->uio_info.mem[ 0 ].addr = res->开始;
开发->uio_info.mem[ 0 ].size = resource_size(res);
开发->uio_info.mem[ 0 ].memtype = UIO_MEM_PHYS;
/*
* 4. 添加UIO
的中断初始化 */
dev->uio_info.irq = irq;
开发->uio_info.handler = uio_irq_handler;
/*
* 5. 向内核框架注册UIO设备
*/
uio_register_device(&pdev->dev, &dev-> info);
}
20. UIO Framework Details | UIO框架详解
-
UIO 驱动程序
-
- 设备的设备树节点可以在 compatible 属性中使用您想要的任何内容,因为它只需与内核空间驱动程序中使用的内容匹配,就像任何平台设备驱动程序一样
-
UIO 平台设备驱动程序
-
- 设备的设备树节点需要在其兼容属性中使用“generic - uio”
原文链接:https://www.cnblogs.com/vlhn/p/7761869.html
更多DPDK学习资料有需要的可以自行添加进入学习交流君 羊 793599096 免费获取,或自行报名学习,免费订阅,永久学习,关注我持续更新哦!!!
学习地址:http://ke.qq.com/course/5066203?flowToken=1043717