FIFO underrun
A FIFO (first in, first out) buffer decouples a producer from a consumer while preserving order: the first item written is the first item read. It absorbs short-term rate mismatches between the two sides.
An underrun occurs when the consumer asks for data and the buffer is empty — the consumer is draining faster than the producer refills, averaged over the buffer's depth. The mirror-image failure is an overrun, where the producer fills a buffer the consumer cannot empty fast enough and data is dropped or overwritten.
Where it shows up
- Audio and video playback — the DAC or display controller needs a sample every fixed interval. Missing one produces an audible click, a dropout, or a stalled frame.
- Display controllers — an LTDC or LCD controller reading a frame buffer over a shared bus underruns when another master monopolises the bus, showing up as torn or shifted lines.
- Serial and network transmission — a UART or MAC transmitter that runs dry mid-frame emits a truncated or corrupted frame that the receiver discards.
Causes
- Average production rate genuinely below average consumption rate. No amount of buffering fixes this; the buffer only postpones the failure.
- Rates that match on average but have bursty producers, with a buffer too shallow to cover the worst-case gap.
- Latency spikes on the producer side: interrupts disabled too long, a higher-priority task overrunning, a blocking flash write, cache misses on a cold path.
- Bus or DMA contention that starves the transfer even though the CPU has the data ready.
- Clock drift between two independently clocked domains — the classic case in audio, where a 48 kHz source and a 48 kHz sink differ by tens of ppm and one side slowly loses.
Fixes
- Deepen the buffer. The cheapest fix, and it works when the mismatch is bursty. Size it from the worst-case producer stall, not from the average, and accept the added latency.
- Prefill before starting. Do not let the consumer begin until the buffer holds a chosen high-water mark of data. This alone removes most start-up underruns.
- Raise the producer's priority or move it to DMA so it is not at the mercy of scheduling jitter.
- Reduce or adapt the consumption rate — lower sample rate, lower resolution, or a codec that tolerates the available bandwidth.
- Handle clock drift explicitly: drive both sides from one clock, or resample against a rate estimated from buffer occupancy. Adaptive rate control based on fill level is the standard technique in streaming.
- Degrade predictably when an underrun does happen — repeat the last sample, insert silence, or hold the last frame. Anything is better than reading uninitialised memory.
- Instrument it. Count underruns and log the buffer's minimum occupancy. A margin that never drops below, say, 40 % is evidence the buffer is sized correctly; one that regularly touches zero is a failure waiting for a busier day.
Retransmission helps only where the transport allows it, such as TCP-based streaming. In a real-time path with a hard deadline, late data is as useless as missing data, so the design has to prevent the underrun rather than recover from it.