HDLC (High-Level Data Link Control) is a bit-oriented, synchronous data link layer protocol standardized by ISO (ISO 13239 / ISO/IEC 13239) that provides framing, error detection, and optional flow control over point-to-point or multipoint serial links. It defines a frame structure built around flag bytes, address and control fields, a payload, and a CRC, and has been widely adopted as a foundation for higher-layer protocols and proprietary embedded communication schemes.
In practice
In embedded systems, HDLC is most commonly encountered not as a fully implemented standard but as a framing technique. Many proprietary protocols borrow the HDLC frame structure: a 0x7E start/end flag byte, payload bytes with byte-stuffing (replacing 0x7E and 0x7D in the payload with escaped sequences), and a 16-bit CRC-CCITT for error detection. This subset is sometimes called HDLC-like or "HDLC framing" and is used over UARTs, RS-232, RS-485, and similar physical layers where the full synchronous HDLC specification would be impractical.
Several well-known protocols are built on or derived from HDLC. PPP (Point-to-Point Protocol) uses HDLC-like framing over serial links. The IEC 62056 DLMS/COSEM standard used in smart metering relies on HDLC for its data link layer. IrDA's link access layer (IrLAP) also uses HDLC-like framing conventions. On older telecom-class hardware and some industrial controllers, full synchronous HDLC with dedicated hardware controllers (e.g., the classic Zilog SCC Z85C30 or on-chip HDLC peripherals found in some PowerPC and RISC-V SoCs) is still encountered in certain industry segments, particularly telecom and utility metering infrastructure.
A common pitfall when implementing HDLC framing on a UART-based MCU is forgetting byte stuffing for the flag value (0x7E) and the escape byte (0x7D) inside the payload. Failing to handle this correctly causes the receiver to misidentify frame boundaries. Another frequent issue is CRC byte ordering: HDLC is a bit-oriented protocol that serializes bits LSB-first on the wire, and the resulting CRC byte order in software implementations can differ from other conventions; mixing byte order between transmitter and receiver is a subtle bug that passes visual inspection but fails validation.
On resource-constrained microcontrollers, a minimal HDLC framing layer is straightforward to implement in a few hundred bytes of code and fits comfortably on 8-bit parts. Full HDLC with windowed I-frames, supervisory frames (RR, RNR, REJ), and unnumbered frames is more complex and is rarely needed in embedded designs unless interoperating with telecom or utility metering infrastructure.
Frequently asked
What is the structure of an HDLC frame?
A standard HDLC frame consists of: a Flag field (0x7E) marking the start and end of the frame, an Address field (1 or more bytes identifying the station), a Control field (1 or 2 bytes indicating frame type and sequence numbers), an Information field (the payload, variable length), a Frame Check Sequence (FCS, typically
CRC-CCITT-16 or CRC-32), and a closing Flag (0x7E). In asynchronous HDLC variants used over
UARTs, byte stuffing ensures that 0x7E and 0x7D values in the payload do not confuse the framing logic.
Do I need special hardware to implement HDLC on an MCU?
Not for HDLC-like framing over a
UART. The flag detection, byte stuffing, and
CRC calculation can all be done in software, and a basic implementation fits on even small 8-bit MCUs. Full synchronous HDLC at high bit rates benefits from dedicated hardware controllers (on-chip HDLC/SDLC peripherals or external parts like the Z85C30), but those scenarios are uncommon in typical embedded designs today.
What CRC does HDLC use, and how is it calculated?
Standard HDLC specifies
CRC-CCITT (CRC-16, polynomial 0x1021) as its default FCS, with CRC-32 as an option for higher-reliability links. The CRC is computed over the Address, Control, and Information fields. HDLC is a bit-oriented protocol that serializes bits LSB-first on the wire, which affects how the CRC is implemented in software. When porting or interoperating, verifying initial value, input/output reflection, and final XOR settings against a known test vector is strongly recommended.
What is the difference between HDLC I-frames, S-frames, and U-frames?
HDLC defines three frame types by the Control field: Information frames (I-frames) carry payload data and include send/receive sequence numbers for flow control and error recovery. Supervisory frames (S-frames) manage flow control and acknowledgement without carrying data (subtypes: RR, RNR, REJ, SREJ). Unnumbered frames (U-frames) handle link setup, teardown, and management. Most minimal embedded HDLC implementations use only U-frames or a stripped-down I-frame structure and omit the full supervisory mechanism.
Which higher-level protocols are based on HDLC?
Several widely used protocols derive from or embed HDLC framing:
PPP (RFC 1662) uses HDLC-like framing for IP over serial links; DLMS/COSEM (IEC 62056) uses HDLC as its data link layer in smart energy meters; IrDA LAP uses HDLC framing at its link access layer; and SS7 MTP2 in telecom signaling is also HDLC-based. Many proprietary embedded protocols borrow only the flag-and-CRC framing subset without adopting the full HDLC frame hierarchy.
Differentiators vs similar concepts
HDLC is often confused with or conflated with SDLC (IBM's Synchronous Data Link Control), which HDLC was derived from and largely supersedes. HDLC is also frequently conflated with
PPP: PPP uses HDLC-like framing (RFC 1662) as its encapsulation layer but adds its own negotiation protocols (LCP, NCP) on top, making PPP a higher-level protocol that relies on HDLC framing rather than being HDLC itself. Additionally, "HDLC framing" as commonly used in embedded systems typically refers only to the flag, byte-stuffing, and
CRC subset, not the full address/control/windowing machinery of the ISO standard.