DMA API
用于 Rust 的 DMA(直接内存访问)抽象 API,提供安全的 DMA 内存操作接口,适用于嵌入式和裸机环境。
特性
no_std支持: 完全支持裸机环境- 类型安全: 提供类型安全的 DMA 操作接口
- 自动缓存同步: 根据传输方向自动处理缓存刷新/失效
- Linux 兼容语义: API 设计遵循 Linux DMA 映射约定
- RAII 风格: 自动管理 DMA 映射的生命周期
核心类型
Direction - DMA 传输方向
DeviceDma - DMA 设备操作
DMA 设备的主要操作接口,提供内存分配、映射和缓存操作。
DmaOp trait - 操作系统抽象层
需要由平台实现的 trait,用于提供底层的 DMA 操作支持。
DArray<T> - DMA 数组
DMA 可访问的数组类型,支持自动缓存同步。
DBox<T> - DMA Box
DMA 可访问的单值容器,支持自动缓存同步。
SingleMapping - 单次映射
临时的单缓冲区 DMA 映射,RAII 风格自动清理。
使用示例
实现 DmaOp trait
use ;
use ;
;
使用 DeviceDma 和 DMA 容器
use ;
// 创建 DMA 设备实例
static DMA_IMPL: MyDmaImpl = MyDmaImpl;
let device = new;
// 创建 DMA 数组 (自动初始化为零)
let mut dma_array = device.
.expect;
// 写入数据 (自动处理缓存同步)
dma_array.set;
dma_array.set;
// 读取数据 (自动处理缓存同步)
let value = dma_array.read;
assert_eq!;
// 获取 DMA 地址用于硬件配置
let dma_addr = dma_array.dma_addr;
// 配置 DMA 控制器使用 dma_addr...
// 使用索引访问
let val = dma_array; // 自动处理缓存同步
// 创建 DMA Box (单个值)
let mut dma_box = device.
.expect;
dma_box.write;
let value = dma_box.read;
// 修改值 (read-modify-write 模式)
dma_box.modify;
使用 SingleMapping 映射现有缓冲区
use DeviceDma;
use ;
let device = new;
// 现有缓冲区
let mut buffer = ;
let addr = new.unwrap;
let size = new.unwrap;
// 映射缓冲区用于 DMA
let mapping = unsafe ;
// 使用映射的 DMA 地址
let dma_addr = mapping.dma_addr;
// ... DMA 传输 ...
// 映射在离开作用域时自动解除
缓存同步
API 遵循 Linux DMA 缓存一致性语义,由 DmaOp trait 的 prepare_read 和 confirm_write 方法自动处理:
读操作前 (prepare_read)
- FromDevice/Bidirectional: 执行
invalidate- 使 CPU 缓存失效,准备接收设备数据 - ToDevice: 无需操作
写操作后 (confirm_write)
- ToDevice/Bidirectional: 执行
flush- 将 CPU 数据写回内存 - FromDevice: 无需操作
DMA 容器的自动同步
DArray<T> 和 DBox<T> 在以下操作时自动处理缓存同步:
read()/set()- 自动同步对应元素index(索引访问) - 自动同步读取的元素write()/modify()- 自动同步写入copy_from_slice()- 写入后自动同步整个范围
API 参考
核心类型
| 类型 | 说明 |
|---|---|
DeviceDma |
DMA 设备操作接口 |
Direction |
DMA 传输方向枚举 |
DmaOp |
操作系统抽象层 trait |
DmaHandle |
DMA 映射句柄 |
DArray<T> |
DMA 数组容器 |
DBox<T> |
DMA 单值容器 |
SingleMapping |
单次映射 |
Linux 等价 API
| Rust API | Linux Equivalent |
|---|---|
DeviceDma::map_single() |
dma_map_single() |
SingleMapping::drop() |
dma_unmap_single() |
DmaOp::alloc_coherent() |
dma_alloc_coherent() |
DmaOp::dealloc_coherent() |
dma_free_coherent() |
DmaOp::flush() |
dma_cache_sync() (DMA_TO_DEVICE) |
DmaOp::invalidate() |
dma_cache_sync() (DMA_FROM_DEVICE) |
对齐要求
DMA 操作通常需要对齐到特定的边界:
new_array()/new_box()的align参数指定对齐字节数- 常见对齐值:64、128、256、512、4096
- 确保返回的 DMA 地址满足对齐要求
DMA Mask
DeviceDma::new() 的 dma_mask 参数指定设备可寻址的地址范围:
0xFFFFFFFF(32 位设备)0xFFFFFFFFFFFFFFFF(64 位设备)- 其他值根据设备硬件限制