Normal Addressing
Overview
Normal Addressing is an ISO 15765-2 addressing format in which the CAN identifier alone represents the network address; no addressing information is stored in the payload.
For the definition of the addressing format and its semantics, refer to ISO 15765-2. This page documents only what is specific to the OpenBSW implementation.
Implementation:
DoCanNormalAddressingDoCanNormalAddressingFilter
Note
Examples use the project configuration (NORMAL_ADDRESSING_ADDRESSES): the
diagnostic pair 0x2A / 0xF0, the legislative ISO 15765-4 pair
0x7E0 / 0x7E8, and the legislative OBD functional request id
0x7DF. ECU address 0x2A (LOGICAL_ADDRESS).
Address Entry Model
Each entry defines a bidirectional channel (request and response) and has six fields:
struct AddressEntry
{
uint32_t _canReceptionId; // CAN id this entry receives on
uint32_t _canTransmissionId; // CAN id used for the response
uint16_t _transportSourceId; // transport source (sender)
uint16_t _transportTargetId; // transport target (this node)
uint8_t _receptionCodecIdx; // index into the codec span (RX)
uint8_t _transmissionCodecIdx;// index into the codec span (TX)
};
There is no _singleFrameOnly field; multi-frame functional requests are
rejected via an invalid transmission id (see Functional Addressing).
Example (legislative physical pair): RX 0x7E0 / TX 0x7E8, source
NORMAL_ADDRESSING_TESTER_ID, target 0x2A. One entry defines both the
request (0x7E0: tester -> 0x2A) and response (0x7E8: 0x2A ->
tester) paths.
CAN Identifier Support
Both 11-bit (base) and 29-bit (extended) reception ids are supported and may
coexist in one table. init() separates them:
Base (11-bit) ids are registered with
BitFieldFilter::add().Extended (29-bit) ids are collected into
_extendedEntriesand matched by lookup rather than the bit field.
The project table is currently all 11-bit, but mixing 29-bit entries is supported.
Address Representation and Format
The data-link address is the CAN identifier itself: reception decoding returns
canId; transmission encoding writes canId = transmissionAddress. No
payload bytes are reserved for addressing (protocol data begins at byte 0).
Reported format: DoCanAddressFormat::Normal. The frame codec is selected per
direction via the entry’s _receptionCodecIdx / _transmissionCodecIdx.
Initialization
init() accepts:
addressEntries- the address table (non-owning span).codecEntries- span of frame codecs indexed by the entry codec indices.
Start-up assertions:
Address table is non-empty.
Reception CAN ids are strictly increasing (unique) - required for the
etl::lower_boundreception lookup.Extended (29-bit) reception ids are valid.
Functional Addressing
A functional (broadcast) request is an ordinary entry whose transmission id is invalid. Project configuration:
RX CAN ID = 0x7DF (OBD functional request)
TX CAN ID = INVALID_ADDRESS
Source = NORMAL_ADDRESSING_TESTER_ID
Target = FUNCTIONAL_ALL_ISO14229
Per ISO 15765-2 a functional request is single-frame only. Because this entry
reports INVALID_ADDRESS as the transmission id, DoCanReceiver rejects a
multi-frame functional request. Each ECU replies physically via its own entry
(0x7E8 for 0x2A).
Reception / Transmission Mapping
getReceptionParameters()looks up the RX CAN id viafindEntryTypeByReceptionAddress(etl::lower_boundover base and extended entries), then returns the transport pair(_transportSourceId, _transportTargetId), transmission id_canTransmissionId(possiblyINVALID_ADDRESS), and reception codec.getTransmissionParameters()reverses the requested transport pair (sourceId = pair.target,targetId = pair.source), linearly finds the matching entry, and builds the data-link pair(_canReceptionId, _canTransmissionId)with the transmission codec. Returnsnullptrif no pair matches.
Example: requested pair source 0x2A / target NORMAL_ADDRESSING_TESTER_ID
reverses to source NORMAL_ADDRESSING_TESTER_ID / target 0x2A, matching
RX 0x7E0 / TX 0x7E8 -> TX CAN ID = 0x7E8.
Filter and Layer Integration
DoCanNormalAddressingFilter implements IDoCanAddressConverter and
can::BitFieldFilter. match() dispatches by id kind: base (11-bit) ids via
BitFieldFilter::match(), extended (29-bit) ids via
findEntryTypeByReceptionAddress over _extendedEntries.
There is no composite converter. The filter is the IDoCanAddressConverter of
a dedicated Normal transport layer, bound as the first of the four layers of
DoCanMultiAddressingTransportLayer:
_multiAddressingTransportLayer.bind(
normalAddressingLayer, // backed by _normalAddressingFilter
extendedAddressingLayer,
rangeExtendedAddressingLayer,
normalFixedAddressingLayer);
On transmission, routing is by tester id: both
NORMAL_ADDRESSING_TESTER_ID and NORMAL_ADDRESSING_DIAG_TESTER_ID map to
the normal layer. formatDataLinkAddress() prints the raw CAN id as
0x%08x (e.g. 0x000007e0).
Implementation Invariants
Address table is non-empty; reception CAN ids strictly increasing (unique).
Extended (29-bit) reception ids are valid.
Data-link address equals the CAN identifier; no payload bytes reserved.
Reception and transmission mappings remain reversible; transport pairs unique.
A functional entry uses an invalid transmission id (no per-entry single-frame flag; entries have exactly six fields).
Base ids admitted via
BitFieldFilter; extended ids via the extended-entry lookup.Address format stays
DoCanAddressFormat::Normal.The filter is bound as the Normal layer of
DoCanMultiAddressingTransportLayer.