Range-Based Extended Addressing

Overview

DoCanRangeExtendedAddressingFilter is a variant of DoCanExtendedAddressingFilter for the special case where a contiguous range of CAN identifiers maps arithmetically onto a contiguous range of transport (N_TA) addresses:

transportId = canId - baseCanId + baseTransportId

The Extended Addressing format itself (AE byte, source/target semantics, functional rules) is defined by ISO 15765-2; see Extended Addressing. This page documents only the range variant.

Instead of one lookup-table entry per participant, the block is described by three values (base CAN id, base transport address, count), giving a constant, table-free footprint and O(1) translation. The filter implements the same interfaces as the table-based Extended filter (IDoCanAddressConverter plus a CAN acceptance filter) and is the converter for a dedicated range-extended transport layer, one of the four aggregated by DoCanMultiAddressingTransportLayer. It replaces the table-based filter only for the layer that owns it; the other layers are untouched.

Table vs range Extended filter

Property

DoCanExtendedAddressingFilter (table)

DoCanRangeExtendedAddressingFilter (range)

Address layout

Arbitrary / sparse

Contiguous, uniformly mapped

Storage

One entry per node

Three scalars (base id, base N_TA, count)

CAN acceptance

BitFieldFilter

IntervalFilter (single interval)

Lookup cost

Search over the table

Arithmetic (add / subtract)

Best fit

A few non-adjacent ECUs

A dense block of ECUs

Address Translation

CAN id and transport address are derived from one another via the base offsets, with a bounds check against count:

  • canIdToTransportId: baseTransportId + (canId - baseCanId), valid for baseCanId <= canId < baseCanId + count.

  • transportIdToCanId: baseCanId + (transportId - baseTransportId), valid for baseTransportId <= transportId < baseTransportId + count.

The mapping is symmetric (id and address differ by a constant offset). CAN acceptance uses IntervalFilter, initialised in init() from the same count as [baseCanId, baseCanId + count - 1] - so the accepted set is by construction identical to the translatable set and the two cannot drift apart.

Functional Addressing

Functional targets may be flagged via the functionalAddresses slice passed to init(); handling follows ISO 15765-2 (single-frame only, functional target reports an invalid transmission address so DoCanReceiver rejects a multi-frame functional request).

Note

Extended Addressing on 11-bit ids has no legislative broadcast id; for physical point-to-point use the functional slice is left empty. The Normal Fixed functional-broadcast remapping in DoCanMultiAddressingTransportLayer applies only to the Normal Fixed layer.

Configuration Constraints

init() asserts (start-up traps on violation):

  • count is non-zero.

  • Range fits an 11-bit base id: baseCanId + (count - 1) <= CanId::MAX_RAW_BASE_ID.

  • Range fits one AE byte: baseTransportId + (count - 1) <= 0xFF.

Layer Integration

There is no composite converter. The range filter is the IDoCanAddressConverter of a dedicated range-extended layer, bound as the third of four layers. The init() signature is unchanged from the standalone filter:

// Demo block: CAN ids 0x600..0x60F <-> transport ids 0x20..0x2F.
uint32_t const RANGE_EXTENDED_BASE_CAN_ID       = 0x600U;
uint16_t const RANGE_EXTENDED_BASE_TRANSPORT_ID = 0x020U;
uint16_t const RANGE_EXTENDED_RANGE_COUNT       = 0x010U; // 16 nodes

_rangeExtendedAddressingFilter.init(
    static_cast<DataLinkLayerType::AddressType>(RANGE_EXTENDED_BASE_CAN_ID),
    RANGE_EXTENDED_BASE_TRANSPORT_ID,
    RANGE_EXTENDED_RANGE_COUNT,
    ::etl::span<uint16_t const>{}, // no functional targets on this range
    _rangeExtendedCodec);

_multiAddressingTransportLayer.bind(
    _normalAddressingLayer,
    _extendedAddressingLayer,
    _rangeExtendedAddressingLayer, // backed by _rangeExtendedAddressingFilter
    _normalFixedAddressingLayer);

No static AddressEntryType[] table is required for this layer.

Note

Type aliases and member names follow the project’s DoCanSystem.h / DoCanSystem.cpp conventions; the init() arguments and the bind() slot order are the fixed parts.

Frame Routing

Reception (RX). The layer’s own IntervalFilter ([baseCanId, baseCanId + count - 1]) is the acceptance gate; any accepted id is guaranteed to translate (shared count).

Transmission (TX). DoCanMultiAddressingTransportLayer::send selects the layer by tester id via getTransportLayerForTesterId, a switch matching a single RANGE_EXTENDED_ADDRESSING_TESTER_ID. An unmatched tester id yields TP_SEND_FAIL rather than a silent mis-route.

Important

RX and TX are asymmetric on purpose. RX accepts the whole block (any of the count nodes can send here); TX reaches this layer only for the one configured RANGE_EXTENDED_ADDRESSING_TESTER_ID. This matches an ECU-side role (receive from many, reply to one tester). A tester/gateway-side role originating frames to every node would need a range check in getTransportLayerForTesterId instead of one constant; the “dense block” best-fit above describes the reception side.

Important

Two invariants keep the multilayer split unambiguous:

  • Disjoint RX ranges. The acceptance interval must not overlap any other layer’s accepted CAN ids on the same bus.

  • Distinct tester ids. Each mode uses a distinct tester id, since getTransportLayerForTesterId switches on the target id.

The acceptance interval is derived from count inside init(), so it cannot be configured wider than the translatable range.

Disjointness

Per-layer stateless routing requires the range-extended CAN ids to be disjoint from all other layers on the same bus. The integrator asserts this at start-up, for example:

Normal      : 0x7DF / 0x7E0 / 0x7E8, plus diag pair 0x2A / 0xF0
Extended    : table filter's id set
RangeExt    : [0x600, 0x60F]
NormalFixed : 29-bit ids (isBase == false)

Disjointness is enforced by the integrator’s start-up assertion, not guaranteed by the layout itself.

Limitations

  • Only a single contiguous linear range is supported; sparse maps require the table-based DoCanExtendedAddressingFilter.

  • The CAN-id and transport-id offsets must be equal (symmetric mapping); asymmetric request/response layouts are not expressible.

  • count is bounded by both the 11-bit base id space and the 8-bit AE byte.