API Reference
Relevant source files
This document provides comprehensive API documentation for the arm_pl011 crate, covering all public interfaces, method signatures, and usage patterns. The API is designed for direct hardware control of PL011 UART controllers in embedded systems and bare-metal environments.
For implementation details and internal architecture, see Core Implementation. For hardware-specific register specifications, see Hardware Reference.
API Overview
The arm_pl011 crate exposes a minimal but complete interface centered around the Pl011Uart struct. The API follows a pattern of explicit initialization followed by character-level I/O operations with optional interrupt handling.
Public Interface Structure
flowchart TD
subgraph subGraph5["Safety Traits"]
SEND["unsafe impl Send"]
SYNC["unsafe impl Sync"]
end
subgraph subGraph4["Interrupt Methods"]
IS_IRQ["is_receive_interrupt(&self) -> bool"]
ACK_IRQ["ack_interrupts(&mut self)"]
end
subgraph subGraph3["I/O Methods"]
PUTCHAR["putchar(&mut self, c: u8)"]
GETCHAR["getchar(&mut self) -> Option"]
end
subgraph subGraph2["Initialization Methods"]
INIT["init(&mut self)"]
end
subgraph subGraph1["Constructor Methods"]
NEW["new(base: *mut u8)"]
end
subgraph subGraph0["Public API Surface"]
CRATE["arm_pl011 crate"]
UART["Pl011Uart struct"]
REGS["Pl011UartRegs (internal)"]
end
CRATE --> UART
UART --> ACK_IRQ
UART --> GETCHAR
UART --> INIT
UART --> IS_IRQ
UART --> NEW
UART --> PUTCHAR
UART --> REGS
UART --> SEND
UART --> SYNC
Sources: src/lib.rs(L8) src/pl011.rs(L34 - L103)
Method Call Flow
sequenceDiagram
participant Application as "Application"
participant Pl011Uart as "Pl011Uart"
participant PL011Hardware as "PL011 Hardware"
Application ->> Pl011Uart: new(base_addr)
Note over Pl011Uart: Construct with hardware base address
Application ->> Pl011Uart: init()
Pl011Uart ->> PL011Hardware: Configure registers (icr, ifls, imsc, cr)
Note over PL011Hardware: Clear interrupts, set FIFO levels, enable RX/TX
loop "Character Output"
Application ->> Pl011Uart: putchar(c)
Pl011Uart ->> PL011Hardware: Check fr register (TX FIFO full?)
Pl011Uart ->> PL011Hardware: Write to dr register
end
loop "Character Input"
Application ->> Pl011Uart: getchar()
Pl011Uart ->> PL011Hardware: Check fr register (RX FIFO empty?)
Pl011Uart -->> Application: Some(char) or None
end
opt "Interrupt Handling"
PL011Hardware ->> Pl011Uart: Hardware interrupt
Application ->> Pl011Uart: is_receive_interrupt()
Pl011Uart ->> PL011Hardware: Read mis register
Pl011Uart -->> Application: true/false
Application ->> Pl011Uart: ack_interrupts()
Pl011Uart ->> PL011Hardware: Write to icr register
end
Sources: src/pl011.rs(L51 - L103)
Core Types
Pl011Uart
The main driver struct that provides safe access to PL011 UART hardware registers.
| Field | Type | Description |
|---|---|---|
| base | NonNull | Typed pointer to memory-mapped register base address |
Safety Characteristics:
- Implements
SendandSyncfor multi-threaded environments - Uses
NonNullfor memory safety guarantees - Requires
unsafeimplementations due to hardware register access
Sources: src/pl011.rs(L42 - L47)
Pl011UartRegs
Internal register structure defining the memory layout of PL011 UART registers.
| Offset | Register | Type | Description |
|---|---|---|---|
| 0x00 | dr | ReadWrite | Data Register |
| 0x18 | fr | ReadOnly | Flag Register |
| 0x30 | cr | ReadWrite | Control Register |
| 0x34 | ifls | ReadWrite | Interrupt FIFO Level Select |
| 0x38 | imsc | ReadWrite | Interrupt Mask Set Clear |
| 0x3c | ris | ReadOnly | Raw Interrupt Status |
| 0x40 | mis | ReadOnly | Masked Interrupt Status |
| 0x44 | icr | WriteOnly | Interrupt Clear |
Sources: src/pl011.rs(L9 - L32)
Method Documentation
Constructor Methods
new(base: *mut u8) -> Self
Creates a new Pl011Uart instance from a hardware base address.
Parameters:
base: Raw pointer to the memory-mapped UART register base address
Returns:
Pl011Uartinstance ready for initialization
Safety:
- Marked as
const fnfor compile-time construction - Uses
NonNull::new().unwrap()- will panic if base address is null - Caller must ensure base address points to valid PL011 hardware
Example Usage:
// Base address for QEMU virt machine PL011
const UART_BASE: *mut u8 = 0x09000000 as *mut u8;
let mut uart = Pl011Uart::new(UART_BASE);
Sources: src/pl011.rs(L50 - L55)
Initialization Methods
init(&mut self)
Initializes the PL011 UART with default configuration for basic operation.
Configuration Applied:
- Clears all pending interrupts (
icr = 0x7ff) - Sets FIFO trigger levels to 1/8 for both RX and TX (
ifls = 0) - Enables receive interrupts (
imsc = 1 << 4) - Enables UART, transmitter, and receiver (
cr = (1 << 0) | (1 << 8) | (1 << 9))
Prerequisites:
- Hardware clock and reset must be properly configured
- Base address must point to accessible PL011 registers
Sources: src/pl011.rs(L61 - L76)
I/O Methods
putchar(&mut self, c: u8)
Transmits a single byte through the UART.
Parameters:
c: Byte value to transmit
Behavior:
- Blocks until TX FIFO has space (polls
frregister bit 5) - Writes character to data register (
dr) - No return value - always succeeds once FIFO space available
Register Operations:
// Wait for TX FIFO not full
while self.regs().fr.get() & (1 << 5) != 0 {}
// Write character
self.regs().dr.set(c as u32);
Sources: src/pl011.rs(L78 - L82)
getchar(&mut self) -> Option
Attempts to read a single byte from the UART receive buffer.
Returns:
Some(byte): If data is available in RX FIFONone: If RX FIFO is empty
Behavior:
- Non-blocking operation
- Checks RX FIFO empty flag (
frregister bit 4) - Reads from data register (
dr) if data available
Register Operations:
if self.regs().fr.get() & (1 << 4) == 0 {
Some(self.regs().dr.get() as u8)
} else {
None
}
Sources: src/pl011.rs(L84 - L91)
Interrupt Methods
is_receive_interrupt(&self) -> bool
Checks if a receive interrupt is currently pending.
Returns:
true: Receive interrupt is pendingfalse: No receive interrupt pending
Register Operations:
- Reads masked interrupt status (
misregister) - Checks receive interrupt bit (bit 4)
Sources: src/pl011.rs(L93 - L97)
ack_interrupts(&mut self)
Clears all pending UART interrupts.
Behavior:
- Writes
0x7ffto interrupt clear register (icr) - Clears all interrupt types simultaneously
- Should be called from interrupt handler after processing
Sources: src/pl011.rs(L99 - L102)
Thread Safety Implementation
The Pl011Uart struct implements both Send and Sync traits to enable safe usage across thread boundaries in multi-threaded embedded systems.
flowchart TD
subgraph subGraph1["Safety Rationale"]
HW_ATOMIC["Hardware register access is inherently atomic"]
NO_STATE["No shared mutable state between operations"]
MMIO_SAFE["Memory-mapped I/O operations are thread-safe"]
end
subgraph subGraph0["Thread Safety Guarantees"]
UART["Pl011Uart"]
SEND["unsafe impl Send"]
SYNC["unsafe impl Sync"]
end
SEND --> HW_ATOMIC
SYNC --> MMIO_SAFE
SYNC --> NO_STATE
UART --> SEND
UART --> SYNC
Implementation Details:
Send: Safe to transfer ownership between threadsSync: Safe to share references between threads- Hardware registers provide atomic access guarantees
- No internal synchronization primitives required
Usage Considerations:
- Multiple threads can safely call read-only methods (
is_receive_interrupt) - Mutable methods require external synchronization for concurrent access
- Interrupt handlers can safely access the same instance
Sources: src/pl011.rs(L46 - L47)