当前位置:诺佳网 > 电子/半导体 > 可编程逻辑 >

使用Linux UIO框架实现ARM和FPGA的高效通信

时间:2025-09-01 | 栏目:可编程逻辑 | 点击:

应用背景

在 和 之间的通信过程中,通信开始或者完成时,需要实时通知对方,如果 ARM 使用类似 while (1) 循环进行反复查看标志位,会造成 空转,影响工作效率。如果使用中断加内核驱动的方式,虽然可以提高效率,但这对开发驱动的有较高的技术要求,因为内核驱动运行在内核态,一旦出现错误,可能会造成整个内核的崩溃,因此需要一种既高效又不依赖复杂内核驱动的解决方案。

UIO 简介

UIO (Usepace I/O) 是运行在用户空间的 I/O 技术, 系统中一般的驱动设备都是运行在内核空间,应用程序在用户空间调用即可。UIO 则是将驱动的小部分运行在内核空间,在用户空间实现驱动的绝大多数功能,使用 UIO 可以避免设备的驱动程序需要随着内核的更新而更新的问题。

相比传统内核态驱动,UIO 的优势包括:

简化了驱动开发流程,降低了内核崩溃的风险

避免了因内核版本更新而需要同步更新驱动的问题

支持用户空间直接访问硬件,提高开发灵活性和效率

7447c72e-f274-11ef-9310-92fbcf53809c.jpg

图1 UIO 驱动的内核部分、用户空间部分和 UIO 框架以及内核的关系

实现方案及步骤

配置内核设备树

首先对设备树节点进行修改,将设备的 compable 属性设置为 generic-uio,以加载通用 UIO 驱动,如下图 (图2) 所示:

746622fa-f274-11ef-9310-92fbcf53809c.jpg

图2 将设备的 compatible 属性设置为 generic-uio

配置内核

Linux 内核中已有 UIO 驱动,但是我们需要使能,才能在内核启动。根据内核设备树,加载相应的驱动。具体的内核增加的配置,参考下图 (图3):

747aa144-f274-11ef-9310-92fbcf53809c.jpg

图3 增加的内核驱动配置

应用层使用

下图 (图4) 为大家提供一套相对完整的参考代码:

7490fa70-f274-11ef-9310-92fbcf53809c.jpg

图4 应用层使用参考代码

说明

在步骤 3 中,re 为阻塞读。设备没有读到数值,该线程进入阻塞态。待时机合适,立马进入运行态。在进入阻塞态,释放的占用。待有数值以后,处理器立马进入运行态,如此即可高效完成工作任务。

UIO 框架说明

Linux UIO 框架的代码位于内核源码 drivers/uio/uio.c。Linux UIO 框架也会调用内核提供的其他 A 函数。通过一个设备文件和几个 sysfs 属性文件访问 UIO 设备。第一个设备的设备文件被称为 /dev/uio0,后续的设备被称为 /dev/uio1、/dev/uio2 等。

中断是通过读取 /dev/uioX 来处理的。一旦中断发生,来自 /dev/uioX 的 blocking read () 将立即返回。除此以外,也可以在 /dev/uioX 上使用 select() 来等待中断。从 /dev/uioX 读取的整数值表示总的中断数,可以使用这个数来计算是否错过了一些中断。

优势与总结

使用 UIO 框架实现 ARM 和 FPGA 的高效通信,不仅减少了 CPU 的资源占用,还降低了开发门槛,提升了系统稳定性。通过用户空间完成大部分驱动逻辑,既实现了高效中断处理,又简化了驱动维护,是一种高效可靠的通信方案。

本文主要介绍如何通过 UIO 技术,在 ARM 与 FPGA 通信中利用用户态实现高效中断处理,避免内核驱动的复杂性和风险。

您可能感兴趣的文章:

相关文章