-
Notifications
You must be signed in to change notification settings - Fork 0
Serial Port Driver
Driver for serial ports (COM1-4) with UART register access via I/O ports. Handles communication via RS-232 serial interface.
The Serial Port Driver provides access to standard PC serial ports (COM1-COM4) using the 16550/16450 UART hardware. It implements the SerialPortAPI interface and extends the Driver framework, integrating with JNode's device management system. The driver uses programmed I/O (PIO) to access UART registers through I/O ports, supporting configurable baud rate, data bits, stop bits, and parity.
| Class/File | Purpose |
|---|---|
SerialPortDriver.java |
Main driver implementation - extends Driver, implements SerialPortAPI and ByteChannel
|
SerialPortAPI.java |
API interface defining baud rate constants and configuration methods |
SerialPortFinder.java |
Device finder that registers serial0 and serial1 devices at boot |
The driver accesses UART registers via I/O ports starting at a configurable base address. Each register is at offset basePort + n:
| Offset | Register | Access | Purpose |
|---|---|---|---|
| +0 | Data/ divisor LSB | R/W | DLAB=0: receive/transmit data; DLAB=1: divisor bits 0-7 |
| +1 | IER / divisor MSB | R/W | DLAB=0: interrupt enable; DLAB=1: divisor bits 8-15 |
| +2 | FCR / IIR | W/R | FIFO control (write) / FIFO status (read) |
| +3 | LCR | R/W | Line control: DLAB, parity, stop bits, data length |
| +4 | MCR | R/W | Modem control: DTR, RTS, loopback |
| +5 | LSR | R/W | Line status: data ready, overrun, framing, parity |
| +6 | MSR | R/W | Modem status: CTS, DSR, RI, CD |
| +7 | Scratch | R/W | 1-byte scratch register |
Baud rate is configured via a divisor value using the formula: baudRate = 115200 / divisor
Standard baud rate divisors:
- 9600 baud: divisor = 12 (BAUD9600 constant)
- 4800 baud: divisor = 24 (BAUD4800 constant)
- 2400 baud: divisor = 48 (BAUD2400 constant)
- 1200 baud: divisor = 96 (BAUD1200 constant)
Configuration sequence (from SerialPortDriver.java:121-124):
port.outPortByte(basePort + 3, control | 128); // Set DLAB=1
port.outPortByte(basePort + 0, divisor); // Divisor LSB
port.outPortByte(basePort + 1, divisor >> 8); // Divisor MSB
port.outPortByte(basePort + 3, control); // Clear DLAB, set LCRSerialPortFinder implements DeviceFinder to register serial ports at boot:
| Device Name | I/O Port Base | Standard Mapping |
|---|---|---|
| serial0 | 0x3f8 | COM1 |
| serial1 | 0x2f8 | COM2 |
The finder creates a Device instance for each port, associates it with a SerialPortDriver instance, and registers it with the DeviceManager.
The driver implements ByteChannel for NIO-based I/O:
-
read(ByteBuffer)- reads bytes into buffer viareadSingle()polling -
write(ByteBuffer)- writes bytes viawriteSingle()polling -
isOpen()/close()- channel state management
Both read and write use busy-wait loops polling the line status register (LSR).
-
Busy-wait I/O: The current implementation uses busy-wait polling for both read and readSingle (
SerialPortDriver.java:136-138) and write (SerialPortDriver.java:143-145). This is CPU-intensive and blocks the calling thread. -
No interrupt support: The driver does not use UART interrupts for data availability notification. Interrupt-driven I/O would be more efficient.
-
FIFO not utilized: Although the UART supports 16-byte transmit/receive FIFOs, the driver does not enable or utilize them, potentially limiting throughput.
-
Limited port detection: Only COM1 (0x3f8) and COM2 (0x2f8) are registered. COM3/COM4 at 0x3e8 and 0x2e8 are not automatically discovered.
-
No DMA support: Serial port DMA transfers are not implemented.
- Driver-Framework - Base driver architecture
- DeviceManager - Device registration and lifecycle
- DeviceAPI - Device API pattern
- Resource-Management - I/O port allocation
- Input-Drivers - Related input device drivers