Module dma_slice

Module dma_slice 

Source
Expand description

Mechanism for sharing buffers with DMA peripherals.

When implementing a chip peripheral driver using DMA, the driver must be careful to not introduce any undefined behavior. This module provides DmaSlice types, which drivers can use when passing a buffer to the DMA hardware. When used correctly, these types ensure that Rust’s memory requirements are preserved when hardware is accessing memory in a way the Rust compiler cannot reason about.

Tock provides multiple implementations of DmaSlice depending on the needs of the user. These include:

Internally, all implementations of DmaSlice use an architecture or chip-provided implementation of DmaFence to ensure that the Rust compiler cannot assume the memory passed to the DMA hardware is not modified.

Conceptually, a DmaSlice consumes a memory buffer. Once consumed, a pointer to that memory can then be safely provided to DMA hardware. When the buffer is consumed, the DmaSlice prevents the Rust compiler from making assumptions about the state of the memory accessed by DMA hardware that would be incorrect and introduce undefined behavior. Once the DMA operation finishes, the buffer must be extracted from the DmaSlice. Before extracting the buffer, the user must guarantee that the DMA hardware can no longer access the memory.

§Usage

This example shows how a developer might use the DmaSlice infrastructure in a driver. The DmaSliceMut::new operation can be replaced by the safe DmaSliceMut::new_static alternative if the provided slice reference has a 'static lifetime.

// Buffer that will be used by the DMA hardware.
let mut buffer: [u8; 16] = [0_u8; 16];

// Create the `DmaSlice` that can be provided to the DMA hardware.
//
// For a static slice, users can instead use the safe `new_static`
// constructor.
let dma_slice = unsafe { DmaSliceMut::new(&mut buffer, SomeDmaFence) };

// Provide the pointer to the buffer to the DMA hardware registers.
regs.dma_ptr.set(dma_slice.as_mut_ptr());

// Wait for the DMA operation to finish...

// Disable the DMA engine to ensure it cannot access the buffer.
regs.dma_ctrl.set(DmaOp::Stop);

// Extract the buffer to retrieve the Rust slice.
let buffer = unsafe { dma_slice.take(SomeDmaFence) };

Modules§

immutable_from_into_bytes

Structs§

DmaSlice
An immutable buffer that can be safely used for read-only DMA operations.
DmaSliceMut
A mutable buffer that can be safely used for DMA operations that read or write the buffer’s contents.
DmaSubSlice
An immutable buffer that can be safely used for read-only DMA operations, created from a SubSlice describing an active range in a larger buffer.
DmaSubSliceMut
A mutable buffer that can be safely used for DMA operations that read or write the buffer’s contents.

Enums§

DmaSliceMutImmut
A buffer that can be safely used for read-only DMA operations, backed by either a shared (immutable) or unique (mutable) Rust slice.
DmaSubSliceMutImmut
A buffer that can be safely used for read-only DMA operations, backed by either a SubSliceMutImmut.