在 Linux 中,驱动的“技术机制”指的是:为了实现用户空间访问硬件、系统层面与设备交互所采用的驱动类型、接口形式与内核机制。
这不仅取决于你要驱动的设备类型(GPIO、DMA、ADC、网卡等),还取决于它连接方式(AXI、SPI、I2C、PCIe)、访问模式(流式/块式/共享内存)和是否中断驱动、DMA驱动、热插拔设备等。
✅ Linux 驱动常用技术机制一览
技术机制 | 适用场景 | 特点与典型接口 |
---|---|---|
Platform 驱动 | 用于片上资源(如 AXI、内建外设) | 基于 device tree + probe |
字符设备驱动 | 控制型外设(如 GPIO、串口) | 提供 open/read/write/ioctl 等接口 |
Block 设备驱动 | 存储类设备(SD、eMMC、NAND) | 挂载文件系统 |
网络设备驱动 | 以太网、Wi-Fi、LoRa、网桥等 | net_device 结构,eth_tool/ioctl 等 |
I2C/SPI 驱动 | I2C/SPI 总线上的外设(如 EEPROM、ADC) | 通过 i2c_driver/spi_driver 接口 |
PCI/PCIe 驱动 | 高速外设(网卡、SSD) | 支持热插拔、中断、多 BAR 映射 |
USB 驱动 | 热插拔 USB 外设 | USB core 子系统 |
UIO 驱动 | 用户空间快速访问 FPGA 硬件资源 | 驱动无需代码,/dev/uioX mmap 即可 |
Misc 设备驱动 | 轻量级设备(如 watchdog) | 自动分配主设备号,简单易用 |
DMA 驱动机制 | 用于大数据传输,提高效率 | dma_alloc_coherent + 中断回调 |
中断驱动 | 响应外设中断(GPIO、FPGA、外设) | request_irq / irq_handler |
Poll/select 驱动机制 | 支持用户空间非阻塞等待 | poll()/select()/epoll |
Fasync 异步通知 | 用户空间通过 signal 获知硬件事件 | kill_fasync + fasync_helper |
mmap 映射机制 | 用于共享内存(如 DMA 缓冲区) | vm_area_struct + mmap 函数 |
Procfs/sysfs 接口 | 驱动信息与参数调试(可选辅助接口) | cat /proc/xxx /sys/class/xxx |
🧱 主要机制详细解释
✅ 1. Platform Driver(平台总线驱动)
- 用于控制 SoC 芯片内部“非枚举”设备(如 Zynq AXI 外设)
- 依赖设备树中 compatible 字符串匹配
- 通常配合字符设备接口 file_operations 提供访问
结构:
struct platform_driver {
.probe = ..., // 匹配设备时调用
.remove = ..., // 卸载设备
.driver = {
.name = "...",
.of_match_table = ...
}
};
✅ 2. 字符设备接口(file_operations)
- 面向控制类外设(读写寄存器、GPIO、PWM、触发控制等)
- 提供标准的 open/read/write/ioctl/mmap 接口
- 可配合 platform 驱动统一使用
用户空间通过 /dev/xxx
文件访问。
✅ 3. UIO(User-space I/O)
- 用户态 mmap IO 访问机制,适用于自定义 FPGA 外设控制
- 配置设备树 compatible = “generic-uio”
- 无需编写内核驱动
- 用户空间通过
/dev/uioX
+mmap()
+read()
即可操作
适合快速开发、调试,性能较低但简单。
✅ 4. 中断机制
- 使用 request_irq 注册中断处理函数
- 中断中不能访问用户空间(不能 copy_to_user)
- 可配合 wait queue 或异步唤醒机制使用
✅ 5. mmap 映射机制
- 将物理内存(如 DMA 缓冲、FIFO 缓冲)映射到用户空间
- 一般配合
dma_alloc_coherent()
申请内核连续内存 - 用户态用
mmap(fd, ...)
映射
适用于高性能数据读写,如视频、波形数据等。
✅ 6. poll/select/epoll 机制
- 用于非阻塞地等待事件(如 FIFO 数据准备就绪)
- 用户态
select(fd, ...)
可阻塞直到驱动中唤醒 - 驱动需实现
.poll
接口,并返回合适的 mask
✅ 7. fasync 异步通知机制
- 内核事件发生时自动向用户进程发送
SIGIO
- 需实现
.fasync
接口 - 用于用户进程注册 signal,当驱动中调用
kill_fasync
发信号通知
✅ 8. DMA 驱动机制
-
使用 Linux DMA API:
dma_alloc_coherent()
分配dma_map_single()
+dma_sync
系列管理缓存
-
中断中读取 DMA 状态 + 唤醒读写线程
通常配合 AXI DMA 使用。
✅ 技术机制选择建议表
你要实现的目标 | 推荐技术机制 |
---|---|
控制类外设(GPIO、寄存器) | platform + 字符设备驱动 |
简单映射 + 用户态控制 | UIO 驱动 + mmap |
带中断的事件型外设(FIFO) | platform + 中断 + poll |
高速数据传输(ADC/DMA) | platform + DMA + mmap |
网络设备(MAC、UDP/IP) | net_device 子系统 |
SPI/I2C 外设 | spi_driver / i2c_driver |
🧩 举例:FPGA 中自定义 IP 使用建议
硬件类型 | 建议机制 |
---|---|
AXI-GPIO | platform + 字符设备 |
AXI-Stream FIFO | platform + 中断 + poll |
AXI-DMA + 缓冲区 | DMA + mmap |
简单状态寄存器读取 | UIO |
✅ 总结
Linux 驱动采用的技术机制并不是孤立的,而是组合使用的:
- platform + file_operations(大多数标准驱动)
- mmap + poll + 中断(高性能读写)
- UIO + 用户空间控制(快速测试开发)
- DMA + 中断 + 缓冲(高速采集系统)