Appendix B — CAN Frame Format Reference
OpenLCB uses CAN 2.0B extended frames with 29-bit identifiers. This appendix documents the bit-field layout of the CAN identifier and the different frame types used by the protocol.
B.1 29-Bit Identifier Layout
The 29-bit CAN extended identifier is divided into fields that differ based on whether the frame is a control frame or an OpenLCB message frame:
Bit: 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
[R] [M] [--- Frame Type/Seq ---] [------ Variable Field ------] [-- Source Alias --]
R = Reserved (bit 28): always 1 on transmit, ignored on receive
M = OpenLCB Message flag (bit 27): 1 = OpenLCB message, 0 = CAN control frame
Bits 26-24 = Frame Type (messages) or Sequence Number (control frames)
Bits 23-12 = Variable Field (MTI for messages, sub-type for control frames)
Bits 11-0 = Source Alias (12-bit CAN alias of the sending node)
Identifier Masks
| Constant | Value | Purpose |
|---|---|---|
RESERVED_TOP_BIT | 0x10000000 | Bit 28 -- always set to 1 |
CAN_OPENLCB_MSG | 0x08000000 | Bit 27 -- 1 = OpenLCB message frame |
MASK_CAN_FRAME_SEQUENCE_NUMBER | 0x07000000 | Bits 26-24 -- frame type or sequence number |
MASK_CAN_VARIABLE_FIELD | 0x00FFF000 | Bits 23-12 -- MTI or control frame sub-type |
MASK_CAN_SOURCE_ALIAS | 0x00000FFF | Bits 11-0 -- source node alias |
B.2 Frame Type Classification
bits 26-24"} E -->|"001"| F["Standard Message"] E -->|"010"| G["Datagram Only"] E -->|"011"| H["Datagram First"] E -->|"100"| I["Datagram Middle"] E -->|"101"| J["Datagram Final"] E -->|"110"| K["Reserved"] E -->|"111"| L["Stream"] D --> M{"Sequence bits
26-24 + Variable"} M --> N["CID / RID / AMD / AME / AMR"]
B.3 OpenLCB Message Frame Types
| Constant | Value | Bits 26-24 | Description |
|---|---|---|---|
OPENLCB_MESSAGE_STANDARD_FRAME_TYPE | 0x01000000 | 001 | Global or addressed OpenLCB message (MTI in variable field) |
CAN_FRAME_TYPE_DATAGRAM_ONLY | 0x02000000 | 010 | Complete datagram in a single CAN frame |
CAN_FRAME_TYPE_DATAGRAM_FIRST | 0x03000000 | 011 | First frame of a multi-frame datagram |
CAN_FRAME_TYPE_DATAGRAM_MIDDLE | 0x04000000 | 100 | Middle frame of a multi-frame datagram |
CAN_FRAME_TYPE_DATAGRAM_FINAL | 0x05000000 | 101 | Final frame of a multi-frame datagram |
CAN_FRAME_TYPE_RESERVED | 0x06000000 | 110 | Reserved for future use |
CAN_FRAME_TYPE_STREAM | 0x07000000 | 111 | Stream data frame |
B.4 CAN Control Frames
Control frames have bit 27 = 0. They handle alias allocation and mapping management:
Check ID (CID) Frames
| Constant | Value | Bits 26-24 | Variable Field Contains |
|---|---|---|---|
CAN_CONTROL_FRAME_CID7 | 0x07000000 | 111 | Node ID bits 47-36 (first 12 bits) |
CAN_CONTROL_FRAME_CID6 | 0x06000000 | 110 | Node ID bits 35-24 (2nd 12 bits) |
CAN_CONTROL_FRAME_CID5 | 0x05000000 | 101 | Node ID bits 23-12 (3rd 12 bits) |
CAN_CONTROL_FRAME_CID4 | 0x04000000 | 100 | Node ID bits 11-0 (last 12 bits) |
Alias Management Frames
| Constant | Value | Description | Data Field |
|---|---|---|---|
CAN_CONTROL_FRAME_RID | 0x00700000 | Reserve ID -- claims the alias | Empty (0 bytes) |
CAN_CONTROL_FRAME_AMD | 0x00701000 | Alias Map Definition -- maps alias to Node ID | 6-byte Node ID |
CAN_CONTROL_FRAME_AME | 0x00702000 | Alias Mapping Enquiry -- query alias ownership | 6-byte Node ID (or empty for global query) |
CAN_CONTROL_FRAME_AMR | 0x00703000 | Alias Map Reset -- node releasing alias | 6-byte Node ID |
B.5 Multi-Frame Message Indicator Bits
For standard OpenLCB messages that span multiple CAN frames (not datagrams), the first data byte contains framing bits:
| Constant | Value | Bits 5-4 | Meaning |
|---|---|---|---|
MULTIFRAME_ONLY | 0x00 | 00 | Single frame (complete message) |
MULTIFRAME_FIRST | 0x10 | 01 | First frame of multi-frame sequence |
MULTIFRAME_FINAL | 0x20 | 10 | Final frame of multi-frame sequence |
MULTIFRAME_MIDDLE | 0x30 | 11 | Middle frame of multi-frame sequence |
Use MASK_MULTIFRAME_BITS (0x30) to extract the framing indicator from the first data byte.
B.6 Datagram Frame Sequencing
Datagrams up to 8 bytes use a single "Datagram Only" frame. Larger datagrams (up to 72 bytes) are split across multiple frames:
For datagram frames, the variable field (bits 23-12) carries the destination alias instead of the MTI. The frame type bits (26-24) identify the frame as a datagram.
B.7 CAN Identifier Field Masks (OpenLCB Messages)
When the frame is a standard OpenLCB message (frame type = 001), the variable field contains the MTI. These masks extract specific MTI sub-fields from the CAN identifier:
| Constant | Value | Purpose |
|---|---|---|
MASK_CAN_STREAM_OR_DATAGRAM | 0x01000000 | Stream/datagram indicator in CAN ID |
MASK_CAN_PRIORITY | 0x00C00000 | Priority field in CAN ID |
MASK_CAN_SIMPLE_PROTOCOL | 0x00010000 | Simple protocol indicator |
MASK_CAN_DEST_ADDRESS_PRESENT | 0x00008000 | Destination address present |
MASK_CAN_EVENT_PRESENT | 0x00004000 | Event ID present in payload |
MASK_CAN_PRIORITY_MODIFIER | 0x00003000 | Priority modifier bits |
All CAN frame format constants are defined in openlcb_defines.h. CAN frame type definitions are in the can_frame_format and can_control_frames Doxygen groups.