Skip to content
Open-source embedded library

ISO 15765-2 (ISO-TP)in portable C

ISOTP-C turns 8-byte CAN frames into complete messages of up to 4095 bytes (or more, with the 32-bit length), and your messages back into flow-controlled frames — with no heap, no RTOS and code that passes MISRA C:2012.

  • No heap
    No RTOS
  • MISRA C:2012
    0 violations
  • 100 % line &
    branch coverage
  • MIT License
    open source
A long message leaves the ISOTP-C chip as a First Frame, the ECU answers with Flow Control, and the Consecutive Frames follow and are reassembled at the ECU
The problem

Eight bytes per frame, kilobytes per message

Diagnostics, calibration and flashing exchange messages of hundreds or thousands of bytes over a bus whose classical frames carry eight. The receiver decides how fast the sender may go, frames can be lost or arrive out of order, and the code runs on an ECU with a few kilobytes of RAM that will be reviewed against MISRA C.

Messages larger than a frame

Segmentation into First and Consecutive Frames, reassembly with sequence-number checks, the receiver's block size and separation time obeyed, N_Bs and N_Cr timeouts detected.

  • FF / CF / FC
  • BS + STmin
  • N_Bs / N_Cr

Tight embedded budgets

104 bytes per link plus the two message buffers you size at build time, at most 120 bytes of stack on a Cortex-M4; no allocation, no globals, no clock reads.

  • Static memory
  • Bare metal
  • Zephyr

Code you can certify

Zero MISRA C:2012 violations, a documented deviation register, 100 % line and branch coverage and static analysis in CI.

  • MISRA C
  • Cppcheck
  • CodeQL
What you get

A small library with a clear job

Two layers and 18 functions: a pure frame codec and a link that does the transport protocol. Time is an argument, the CAN driver is one callback.

18public functions
104 BRAM per link + buffers
120 Bstack on Cortex-M4
0MISRA C:2012 violations

Quick start

A minimal ECU in one file

The library touches the hardware through two things you provide: a function that writes one CAN frame, and the received frames you pass in together with the current time in microseconds. Everything else — segmentation, flow control, timeouts — happens inside isotp_link_receive() and isotp_link_poll(). This program echoes every request it receives on CAN ID 0x7E0 back on 0x7E8, whatever its length:

#include "isotp.h"

static struct isotp_link link;

static int can_write(void* context, uint32_t can_id, const uint8_t* data, size_t length)
{
    (void) context;
    return board_can_write(can_id, data, length);
}

static void on_message(const uint8_t* data, uint32_t length, void* context)
{
    (void) context;
    (void) isotp_link_send(&link, data, length, board_micros()); /* echo */
}

int main(void)
{
    struct isotp_link_config config;
    uint8_t frame[8];
    uint32_t can_id;

    isotp_link_config_default(&config);
    config.tx_id = 0x7E8U;
    config.write = can_write;
    config.on_message = on_message;
    (void) isotp_link_init(&link, &config);

    for (;;)
    {
        size_t length = board_can_read(&can_id, frame); /* 0: no frame waiting */
        if ((length > 0U) && (can_id == 0x7E0U))
        {
            isotp_link_receive(&link, frame, length, board_micros());
        }
        isotp_link_poll(&link, board_micros());
    }
}

board_can_write(), board_can_read() and board_micros() stand for your CAN driver and a free-running microsecond timer; the examples implement them for a simulated board, Linux SocketCAN and Zephyr.

Find your way

If you want to… Read
Understand what the library does and does not do Introduction
Build it, run the tests, add it to your project Getting Started
Understand the layers, the state machines and the timers How It Works
Write an ECU or a tester with it Using the Library
Add addressing modes, CAN FD or contribute Extending the Library
Look up the bytes on the wire Protocol
Look up a function API Reference
Read everything offline or print it PDF user manual
SystemFromScratch®

Part of an open-source embedded portfolio

ISOTP-C is developed by Anton Vynohradov under SystemFromScratch® — embedded software and hardware built from the first schematic to certification.

SystemFromScratch® is a registered trademark. ISO 15765-2 is a standard of the International Organization for Standardization (ISO). ISOTP-C is an independent implementation and is not affiliated with or endorsed by ISO.