Skip to content

Configuration

Build-time parameters live in inc/isotp_config.h. Each one is guarded by #ifndef and range-checked at compile time; override it with a compiler definition, for example -DISOTP_RX_BUFFER_SIZE=256U. The two buffer sizes are compiled into struct isotp_link; the other values are only the defaults that isotp_link_config_default() writes into a struct isotp_link_config, so every link can use its own values at run time.

Parameter Default Range Meaning
ISOTP_TX_BUFFER_SIZE 4095U 8 … 2^31−1 Largest message a link sends, in bytes
ISOTP_RX_BUFFER_SIZE 4095U 8 … 2^31−1 Largest message a link receives; longer ones are refused with FC OVFLW
ISOTP_DEFAULT_BLOCK_SIZE 8U 0 … 255 BS this receiver requests; 0 = no further Flow Control
ISOTP_DEFAULT_ST_MIN_US 0U 0 … 127000 STmin this receiver requests, µs
ISOTP_DEFAULT_N_BS_TIMEOUT_US 1000000U 1 … 2^31−1 N_Bs, µs (ISO 15765-2: 1000 ms)
ISOTP_DEFAULT_N_CR_TIMEOUT_US 1000000U 1 … 2^31−1 N_Cr, µs (ISO 15765-2: 1000 ms)
ISOTP_DEFAULT_WFT_MAX 10U 0 … 255 N_WFTmax: Wait frames accepted in a row

Messages longer than 4095 bytes use the 32-bit FF_DL of ISO 15765-2:2016; they need a buffer size above 4095. Your peer must support the escape sequence too.

Run-time configuration

struct isotp_link_config also holds what has no build-time default:

Member Default Meaning
tx_id 0 CAN ID of every frame this link sends (11- or 29-bit, passed to the writer)
write, write_context none Frame writer (required) and its context
on_message, on_tx_done, on_rx_error, app_context none Callbacks and their context
padding, padding_value false, 0xCC Pad every sent frame to 8 bytes

isotp_link_init() rejects a configuration without a writer, an STmin above 127 000 µs and timeouts of 0 or above 2^31−1 µs (deadlines are compared modulo 2^32).

Memory footprint

Measured with sizeof and arm-none-eabi-size (Cortex-M4, -Os):

Object Size
struct isotp_link, default 4095-byte buffers 8 296 bytes
struct isotp_link, 256-byte buffers 616 bytes
struct isotp_link, 64-byte buffers 232 bytes
Per link without the buffers 104 bytes
struct isotp_link_config 48 bytes
Code: isotp_protocol.o + isotp_link.o 516 + 1 268 = 1 784 bytes of flash, no data, no bss

The library has no global variables: the RAM it uses is the struct isotp_link instances you declare (one per peer) and the stack.

Stack usage

Worst-case stack of each public function, including the library functions it calls, measured with -fstack-usage -fcallgraph-info=su and tools/docs/stack_usage.py, default configuration, in bytes:

Function Cortex-M4 -Os Cortex-M4 -O0 x86-64 -O2
isotp_decode() 12 80 8
isotp_encode_consecutive() 16 32 8
isotp_encode_first() 12 48 8
isotp_encode_flow_control() 0 32 8
isotp_encode_single() 16 32 8
isotp_frame_pad() 16 32 8
isotp_link_config_default() 0 16 8
isotp_link_init() 16 32 16
isotp_link_invalid_frames() 0 16 8
isotp_link_poll() 80 136 72
isotp_link_receive() 120 200 120
isotp_link_rx_result() 0 16 8
isotp_link_send() 72 120 88
isotp_link_send_functional() 64 112 56
isotp_link_tx_busy() 0 16 8
isotp_link_tx_result() 0 16 8
isotp_st_min_decode() 0 24 8
isotp_st_min_encode() 0 24 8

Toolchains: xPack GNU Arm Embedded GCC 14.2.1 (-mcpu=cortex-m4 -mthumb) and GCC 13.3.0 (x86-64 Linux).

The figures do not include what runs behind a function pointer: your write function and your callbacks run on top of the library frame that calls them.

Path Worst chain (Cortex-M4 -Os) Stack
Receive isotp_link_receive() → isotp_link_send_fc() → isotp_link_write() → isotp_frame_pad() 120 B + write function or callback
Poll isotp_link_poll() → isotp_link_write() → isotp_frame_pad() 80 B + write function
Send isotp_link_send() → isotp_link_write() → isotp_frame_pad() 72 B + write function

on_message() runs inside isotp_link_receive(); when it answers with isotp_link_send(), add that chain too (Cortex-M4 -Os: up to 120 + 72 bytes plus your own frames).

Re-measure after a change:

mkdir -p build/su && for f in src/*.c; do
  arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -Os -std=c11 -I. -Iinc \
      -fstack-usage -fcallgraph-info=su -c "$f" -o "build/su/$(basename "$f" .c).o"
done
python tools/docs/stack_usage.py build/su --markdown --prefix isotp_

CMake options

Option Default Meaning
ISOTP_UNIT_TESTS OFF GoogleTest suite and coverage target (built with 5000-byte buffers)
ISOTP_INTEGRATION_TESTS OFF pytest suite
ISOTP_EXAMPLES OFF Host examples and the bare-metal simulation test
ISOTP_COVERAGE_MIN 100 Coverage gate
ISOTP_MISRA_FAIL_ON_VIOLATION ON MISRA gate
ISOTP_MISRA_RULE_TEXTS empty Licensed MISRA rule texts