as

BL over DoIP Demo on Host Simulator

Table of Contents

  1. Introduction
  2. Architecture
  3. Configuration
  4. Build
  5. Run DoIPBL
  6. Test Flashing over DoIP
  7. DoIP to CAN Gateway Demo (Loader -> DoIPBL -> CanBL)

1. Introduction

DoIPBL is a bootloader application running on the host simulator (Windows or Linux) that demonstrates flashing the bootloader over DoIP (ISO 13400) diagnostic services, instead of CAN.

It is built from the same BL stack as CanBL (see BL Configuration & Host Simulation), with the CAN related modules (CanTp) replaced by the Ethernet diagnostic stack: DoIP on top of SoAd and TcpIp. The BL, Dcm and PduR configuration and behavior stay the same.

Notes:

2. Architecture

graph TB
    subgraph PC["Loader (PC tool)"]
        LDR["Loader.exe -d DOIP.224.244.224.245"]
    end
    subgraph HOST["DoIPBL (host simulator process)"]
        TCPIP["TcpIp"] --> SOAD["SoAd"]
        SOAD --> DOIP["DoIP"]
        DOIP --> PDUR["PduR"]
        PDUR --> DCM["Dcm"]
        DCM --> BL["BL"]
        SIM["Simulator (Mcu/reset/BL jump glue)"] --- BL
    end
    LDR -- "UDP 13400 multicast discovery (224.244.224.245)" --> TCPIP
    LDR -- "TCP 13400 routing activation + UDS" --> TCPIP

The diagnostic request path: Loader -> TCP 13400 -> TcpIp -> SoAd -> DoIP -> PduR(P2P_RX) -> Dcm -> BL. The response path: BL -> Dcm -> PduR(P2P_TX) -> DoIP -> SoAd -> TcpIp -> TCP -> Loader.

DoIP creates two SoAd sockets automatically:

After the TCP connection is established, the tester sends a routing activation request with source address 0xbeef; once activated, UDS requests are routed to Dcm with target address 0xdead.

3. Configuration

All DoIP related configurations are under app/bootloader/config/Net:

File Content
Network.json DoIP module: discovery address, max_connections, target P2P with logical address 0xdead, routine default and tester default with address 0xbeef
Dcm.json Dedicated Dcm configuration for DoIPBL with only the P2P physical channel (no CAN functional channel P2A)
PduR.json PduR routing: P2P_RX from DoIP to Dcm and P2P_TX from Dcm to DoIP
Mempool.json Memory pool (MemCluster named Net) used by SoAd/DoIP

The DoIP target is named P2P and the PduR routines are named P2P_RX/P2P_TX, so they map to the Dcm P2P channel (index 0) generated by Dcm.json.

The application glue code is in app/bootloader/src/doip.c, guarded by USE_DOIP, it provides:

In app/bootloader/main.c, when USE_TCPIP, USE_SOAD and USE_DOIP are defined, the initialization calls TcpIp_Init, SoAd_Init, DoIP_Init and DoIP_ActivationLineSwitchActive, and the main functions TcpIp_MainFunction, SoAd_MainFunction and DoIP_MainFunction are scheduled.

4. Build

Refer to build environment setup for the toolchain. Then build the AsOne and LoaderFBL libraries, the Loader PC tool and the DoIPBL bootloader one by one, the same pattern as the CanBL simulation test:

scons --lib=AsOne
scons --lib=LoaderFBL
scons --app=Loader
scons --app=DoIPBL

The outputs on Windows are:

Building DoIPBL also generates the Dcm/PduR/SoAd/DoIP configuration code from app/bootloader/config/Net/*.json into the build directory.

5. Run DoIPBL

Start the bootloader (on Windows, make sure the MSYS2 mingw64/bin runtime DLLs such as libstdc++-6.dll are in PATH):

# optional: enable the Dcm module logs (DCMI is DEBUG level, hidden by default)
set AS_LOG_DCMI=1            # Windows CMD; on Linux use export AS_LOG_DCMI=1
build\nt\GCC\DoIPBL\DoIPBL.exe

The DoIPBL host build never jumps to the application and never resets, so it stays running in the default session and is ready for flashing.

Expected behavior:

6. Test Flashing over DoIP

This section gives the complete command list to verify flashing end to end on the host. All commands run from the repository root. Prerequisites: python is in PATH, and Loader.exe/DoIPBL.exe have been built per section 4.

6.1 Generate Dummy Flash Driver (1052 bytes)

Use the same generator script as section 6.2 to generate a single 1052-byte section with sequential values (0, 1, 2, …, 255, 0, 1, …) at address 0:

python tools/utils/gensims19.py -n 1 -s 1052 -g 0 -b 0 -o build/FlashDriverDummy.s19

6.2 Generate Dummy Application (partition A and B)

The generator script is kept at tools/utils/gensims19.py. It generates a multi-section S19 image; partition A starts at 0x1000 and partition B at 0x100000 (same memory layout as CanBL, because DoIPBL shares config/BL/BL.json):

# partition A
python tools/utils/gensims19.py -n 8 -s 8192 -g 2048 -b 0x1000 -o build/AppDummy.s19.A

# partition B
python tools/utils/gensims19.py -n 8 -s 8192 -g 2048 -b 0x100000 -o build/AppDummy.s19.B

6.3 Sign Flash Driver and Application

Sign the images with the Loader (signature areas match the BL A/B layout):

# sign the application for partition A
build\nt\GCC\Loader\Loader.exe -f build/AppDummy.s19.A -s 0xfff00 -S crc32-v3

# sign the application for partition B
build\nt\GCC\Loader\Loader.exe -f build/AppDummy.s19.B -s 0x1fff00 -S crc32-v3

# sign the flash driver
build\nt\GCC\Loader\Loader.exe -f build/FlashDriverDummy.s19 -s 2048 -S crc32

6.4 Program over DoIP

Run the Loader from another terminal (on Windows make sure C:\msys64\mingw64\bin and build\nt\GCC\one are in PATH for the Loader runtime DLLs). Start DoIPBL and keep it running; because the DoIPBL host build never jumps to the application or resets, a single DoIPBL instance can be used to program both partitions one after another.

# start DoIPBL and keep it running
set AS_LOG_DCMI=1            # Windows CMD; on Linux use export AS_LOG_DCMI=1
build\nt\GCC\DoIPBL\DoIPBL.exe

# program partition A
build\nt\GCC\Loader\Loader.exe -d DOIP.224.244.224.245 -c FBL -S crc32 -f build/FlashDriverDummy.s19.sign -a build/AppDummy.s19.A.sign

# program partition B (no need to restart DoIPBL)
build\nt\GCC\Loader\Loader.exe -d DOIP.224.244.224.245 -c FBL -S crc32 -f build/FlashDriverDummy.s19.sign -a build/AppDummy.s19.B.sign

A successful run ends with every step printing okay, progress 100.00% and a loader speed summary (about 4 kbps on the host loopback). The flashing procedure goes through DoIP routing activation, extended session, communication control off, security access (extended and program levels), erase, download, verification, check integrity, ECU reset, communication enable and DTC setting on; each step prints PASS or FAIL, and a FAIL aborts the flashing.

Notes:

7. DoIP to CAN Gateway Demo (Loader -> DoIPBL -> CanBL)

DoIPBL additionally works as a DoIP-to-CAN diagnostic gateway: UDS requests received over DoIP with target address 0x731 are forwarded over CAN via CanTp to CanBL, so the CAN application (CanApp) can be flashed remotely over DoIP. The full loop is Loader -> DoIPBL -> CanBL -> CanApp:

graph TB
    subgraph PC["Loader (PC tool)"]
        LDR["Loader.exe -d DOIP.224.244.224.245 -t 0x731 -r 0xe80"]
    end
    subgraph GW["DoIPBL (DoIP-to-CAN gateway)"]
        TCPIP["TcpIp"] --> SOAD["SoAd"]
        SOAD --> DOIP["DoIP"]
        DOIP --> PDUR["PduR"]
        PDUR --> DCM["Dcm"]
        PDUR --> CANTP["CanTp"]
        CANTP --> CANIF["CAN glue (main.c)"]
    end
    subgraph TARGET["CanBL (host simulator process)"]
        CANTP2["CanTp (P2P 0x731)"] --> PDUR2["PduR"] --> DCM2["Dcm"] --> BL2["BL"] --> APP["CanApp"]
    end
    LDR -- "UDP/TCP 13400" --> TCPIP
    CANIF -- "CAN: TX 0x731, RX 0x732" --> CANTP2

7.1 Gateway Configuration

Compared with section 3, the following is added under app/bootloader/config/Net (BL main.c stays unchanged):

File Content
Network.json Extra target: CAN_BL at 0x0731 with node TX CAN id 0x731; extra routine/tester CANBL with tester address 0x0E80
PduR.json TP gateway routes CAN_BL_RX (DoIP -> CanTp) and CAN_BL_TX (CanTp -> DoIP) with DestBufferSize: 4096 (the TP gateway buffer is mandatory, otherwise DoIP answers NACK 0x08)
CanTp.json One TP gateway channel CAN_BL (LL_DL: 64, the source/destination PduIds are derived from the PduR routing)

The gateway CAN TX id and RX filter are given statically as build definitions in app/bootloader/SConscript (CAN_DIAG_P2P_TX=0x731, CAN_DIAG_P2P_RX=0x732); the glue in main.c uses them as defaults, and the command line -t/-r can override them at runtime.

Note: the Loader parses -t/-r as decimal unless a 0x prefix is given, always use e.g. -t 0x731.

7.2 Run the Gateway Loop Demo

Build the CAN side and start the three processes (Windows: keep MSYS2 mingw64/bin DLLs in PATH):

scons --app=CanBL
scons --app=CanApp

# terminal 1: the CAN target (flashes itself into partition A/B, then jumps to CanApp)
build\nt\GCC\CanBL\CanBL.exe

# terminal 2: the DoIP-to-CAN gateway (CAN TX id 0x731, RX filter 0x732, from the SConscript build definitions)
# the Dcm DCMI logs (DEBUG level) are hidden by default, enable them per module:
set AS_LOG_DCMI=1            # Windows CMD; on Linux use export AS_LOG_DCMI=1
build\nt\GCC\DoIPBL\DoIPBL.exe

# terminal 3: flash the CAN application over DoIP, tester SA 0xE80, target TA 0x731
build\nt\GCC\Loader\Loader.exe -d DOIP.224.244.224.245 -t 0x731 -r 0xe80 -c FBL -S crc32 -f build/FlashDriverDummy.s19.sign -a build/AppDummy.s19.A.sign

# program partition B (no need to restart)
build\nt\GCC\Loader\Loader.exe -d DOIP.224.244.224.245 -t 0x731 -r 0xe80 -c FBL -S crc32 -f build/FlashDriverDummy.s19.sign -a build/AppDummy.s19.B.sign

A successful run ends with progress 100.00% (about 2-3 kbps, the DoIP-to-CAN gateway forwards every UDS request through CAN TP). After the final ECU reset, CanBL verifies the application integrity, activates the flashed partition and jumps to CanApp.exe.

7.3 Loader SA/TA Mapping

The gateway introduces the tester CANBL (SA 0x0E80) and the target CAN_BL (TA 0x0731) routed by its routine. The Loader needs no modification to use the mapping via the command line; the mapping mechanism of its DOIP branch (loader_cmd.cpp) is:

Optional: to forward through the gateway by default when -r/-t are not given (instead of flashing the gateway itself), differentiate the defaults by device name in the DOIP branch of loader_cmd.cpp, e.g. for device name DOIP-CANBL.224.244.224.245 default to rxid = 0xe80 (CANBL tester) and txid = 0x731 (CAN_BL target). Keep the existing 0xbeef/0xdead defaults (section 6 relies on them). Do not change toU32 to parse hex by default: -s (signature offset), -T (timeout) and other options share it, that would change their behavior; keep the 0x prefix convention.