UART / TTY End-to-End Flow (Day29 + Day30 Summary)¶
🎯 Objective¶
- Provide a complete picture of UART communication in Linux
- Connect user-space APIs to kernel driver execution
- Summarize TX / RX flow, buffering, and design principles
- Serve as a quick reference for debugging and interviews
🧠 1. System Overview¶
USER SPACE
write() / read()
↓
TTY core
↓
Line Discipline (N_TTY)
↓
Serial Core (uart_ops)
↓
PL011 Driver
↓
UART Hardware (FIFO)
↓
GPIO / Wire
🟢 2. TX Flow (User → Hardware)¶
Full Path¶
write()
→ tty_write()
→ line discipline
→ uart_write()
→ xmit buffer
→ pl011_start_tx()
→ UART TX FIFO
→ wire
Step-by-Step¶
1. write()¶
- user initiates transmission
- returns quickly after buffering
2. xmit buffer¶
- circular buffer (~4KB)
- decouples user speed from hardware speed
3. pl011_start_tx()¶
- moves data from xmit buffer → UART FIFO
- may enable TX interrupt for remaining data
Key Insight¶
write() ≠ data transmitted
write() = data buffered
🔵 3. RX Flow (Hardware → User)¶
Full Path¶
Step-by-Step¶
1. UART RX¶
- hardware receives data into FIFO
2. Interrupt¶
- triggered when FIFO reaches threshold
3. pl011_irq()¶
- reads FIFO
- pushes data to flip buffer
4. Flip Buffer¶
- temporary kernel buffer
- separates IRQ from user space
5. TTY buffer¶
- managed by TTY core
- final buffer before user read()
6. read()¶
- copies data from TTY buffer to user
Key Insight¶
read() ≠ direct hardware access
read() = data from TTY buffer
🔁 4. TX vs RX Comparison¶
| Aspect | TX | RX |
|---|---|---|
| Entry | write() | interrupt |
| Buffer | xmit buffer | flip buffer |
| Driver role | push data | collect data |
| Direction | user → hardware | hardware → user |
| Timing | async | interrupt-driven |
🧠 5. Buffer Architecture¶
Buffer Roles¶
| Buffer | Purpose |
|---|---|
| FIFO | hardware staging |
| xmit buffer | TX decoupling |
| flip buffer | IRQ-safe staging |
| tty buffer | user-visible data |
🧠 6. Why So Many Buffers?¶
1. Interrupt Safety¶
- cannot access user memory in IRQ
- must copy to kernel buffer
2. Decoupling¶
- independent timing
- independent execution context
3. Performance¶
- batching reduces interrupts
- asynchronous transmission
4. Reliability¶
- prevents data loss
- absorbs burst traffic
🧠 7. TTY vs Simple Driver¶
Simple Char Driver¶
TTY Subsystem¶
Key Difference¶
TTY introduces abstraction, flexibility, and reusability
🧠 8. Role Separation¶
| Layer | Responsibility |
|---|---|
| User | read/write |
| TTY core | buffering, fd management |
| Line discipline | behavior (raw/canonical) |
| Serial core | generic UART handling |
| Driver | hardware interaction |
| Hardware | physical transmission |
🧠 9. Design Principles¶
1. Asynchronous I/O¶
- write() does not block transmission
- driver sends data in background
2. Layered Design¶
- separation of concerns
- reusable components
3. Interrupt-driven RX¶
- efficient data reception
- minimal CPU usage
4. Buffer-based Flow Control¶
- handles speed mismatch
- prevents overflow
🎯 10. Key Takeaways¶
- UART is hardware, TTY is abstraction
- write() pushes data into buffer
- read() pulls data from buffer
- flip buffer bridges IRQ and TTY core
- driver does not interact with user directly
🚀 Final Insight¶
Linux TTY subsystem transforms a simple UART into a flexible, asynchronous, and reusable communication interface