Platform abstraction
The driver selects register definitions at compile time using thePLATFORM_TARGET preprocessor macro:
uart.c
UART0_BASE is defined by plataform.h as an alias for PLATFORM_UART0_BASE, which must be provided as a compile-time define (the header enforces this with #error).
QEMU PL011 register map
WhenPLATFORM_TARGET == 1, the driver accesses the UART through a volatile unsigned int * pointer:
uart.c
| Register | Offset | Description |
|---|---|---|
UART_DR | 0x00 | Read: received byte. Write: byte to transmit. |
UART_FR | 0x18 | Flag register. Poll to check FIFO status. |
UART_FR_TXFF | bit 0x20 | TX FIFO full — wait before writing. |
UART_FR_RXFE | bit 0x10 | RX FIFO empty — wait before reading. |
BeagleBone TL16C750 register map
WithoutPLATFORM_TARGET == 1, the driver uses PUT32/GET32 memory-mapped I/O helpers:
uart.c
| Register | Offset | Description |
|---|---|---|
UART_THR | +0x00 | Write a byte here to transmit. Read to receive. |
UART_LSR | +0x14 | Line Status Register. Poll for TX/RX readiness. |
UART_LSR_THRE | bit 0x20 | TX Holding Register Empty — safe to write. |
UART_LSR_RXFE | bit 0x10 | RX empty — no byte available yet. |
Public API
uart_putc
uart.c
uart_getc
uart.c
os_write / uart_puts
uart_putc() for each character. uart_puts is an alias for os_write.
uart.c
os_read / uart_gets_input
buffer. Characters are echoed back as they are received. Reading stops when a newline (\n) or carriage return (\r) is received, or when max_length - 1 characters have been stored. The buffer is always null-terminated. uart_gets_input is an alias for os_read.
uart.c
The UART driver is entirely polling-based. Every call to
uart_putc() or uart_getc() spins in a tight loop until the hardware is ready. There are no receive or transmit interrupts, no DMA, and no ring buffers. Output is strictly synchronous.Usage in the OS
The OS main loop wrapsos_write (aliased as PRINT) in a critical section to prevent the scheduler from preempting mid-output:
os.c
uart_putc busy-waits, a preemption mid-transmission would leave the UART in a partially-written state visible to the new process’s output. Disabling IRQs for the duration of each print call prevents interleaved output across processes.