All notable changes to XCPlite are documented in this file.
- xcpclient related changes:
- The call frame information (
.debug_frame,.eh_frame) of 32 bit targets is parsed with the address size of the ELF file. It was parsed with the 8 byte address size of the host, which produced unusable frame descriptions for ARM and Xtensa targets and a CFA offset of 0 by accident. For ARM Cortex-M targets (freertos_stm32_demo) the stack frame relative addresses of local variables change, please verify on the target - Xtensa (ESP32): the CFA offset is 0 by design, the trigger macros pass the CFA itself (
__builtin_dwarf_cfa()), verified on ESP32-S3 withfreertos_esp32_demo - Location expressions of variables which can not be evaluated (register locations, entry values, optimized code in other compilation units) and variables without a name are reported at debug level instead of error/warning level
- New option
--default-event <id>(alsodefault_eventin the TOML config file): event used for the DAQ measurement of variables without a fixed event, such as global variables in an A2L file generated from an ELF file. When an A2L file is created from an ELF file, the event is assigned to global variables and to static variables in functions without an event trigger as their default event
- The call frame information (
- Split
platform.c/.hintoplatform.c/.h(threads, mutex, clock, sleep, memory, atomics) andsockets.c/.h(socket abstraction for all platforms).sockets.hincludesplatform.h; files that use both include both explicitly (IWYU). - New raw Ethernet transport
OPTION_ENABLE_UDP_RAW: XCP on UDP/IPv4 implemented inside xcplib on top of a thin raw Ethernet HAL, for targets without a TCP/IP stack. Seedocs/SOCKET_RAW.md.- New build configuration
raw(src/xcplib_raw_cfg.h,build-raw/) with the new exampleudp_raw_demoand the unit testsocket_raw_test(Linux only) src/socket_raw.c— UDP/IPv4 layer, answer-only ARP, ICMP Echo responder, receive filter with an absolute-deadline loopsrc/socket_raw_hal.h— raw Ethernet HAL interface,src/socket_raw_hal_linux.c— AF_PACKET backend (requiresCAP_NET_RAW)test/test_socket_raw.sh— isolated veth/netns test setup with ARP, ping and XCP CONNECT checks- Mutually exclusive with
OPTION_ENABLE_UDP/OPTION_ENABLE_TCPand requiresOPTION_QUEUE_32; both enforced by#errorinxcptl_cfg.h, together with the SHM, multicast and MTU restrictions - The
rtosconfiguration keeps using the lwIP socket API - the raw transport is a separate configuration, not an override
- New build configuration
- Optional zero copy transmit for the raw Ethernet transport (
OPTION_UDP_RAW_ZERO_COPY, on by default): headroom is reserved in front of every transmit queue3/queue32 segment so the Ethernet/IPv4/UDP header is written in place instead of copying the payload into a frame buffer.- New generic queue concept
QUEUE_SEGMENT_HEADER_SIZEinqueue.h- reserved once per segment, as opposed to the existing per-messageQUEUE_ENTRY_USER_HEADER_SIZE queue32.c/queue32m.cgain one guarded field; with the option off the queue entry layout is byte identical to before- Command responses keep the copying path, they are built on the stack and are not hot
- New generic queue concept
- New
OPTION_UDP_RAW_HAL_EXTERNAL: an application can supply its own raw Ethernet HAL from outside the library. xcplib then selects no backend and theeth_hal_*symbols stay undefined inlibxcpliteuntil the application links its own implementation. Intended for backends which do not belong in the library, for example ASAM CMP for testing XCP tools through capture modules, or a vendor specific interface such as XLAPI.- Also lifts the Linux-only restriction of the raw transport: without a built in backend there is nothing platform specific left in it
- Depends on
libxcplitebeing a static library, so the undefinedeth_hal_*resolve at application link time with no indirection in the transmit path. A shared build would resolve them internally and the override would silently not take socket_raw_hal_linux.cis excluded by the same option, so the built in AF_PACKET backend is not linked in
OPTION_MTUin therawconfiguration set to 1420, below the 1500 of a standard Ethernet link, to leave headroom for a HAL backend which encapsulates the frame before putting it on the wire.XCPTL_MAX_SEGMENT_SIZEbecomes 1392, the largest Ethernet frame 1434 and its IP packet 1420 bytes, i.e.OPTION_MTUexactly. An encapsulating backend then fits inside a 1500 byte path:cmp_demowraps that 1434 byte frame in a 34 byte CMP envelope and 28 bytes of outer IPv4/UDP headers, reaching 1496 bytes. At the full link MTU a segment is 1472 bytes and the frame 1514, filling the path on its own, so an encapsulating backend has nothing left and the raw transport, which does not fragment, can only refuse the frame.- The previous value was 1504, a leftover of the pre-V2.1.11 convention where
OPTION_MTUwas the link MTU rounded up to a multiple of 8. Since "Fix UDP segment size calculation from MTU" (V2.1.11)XCPTL_MAX_SEGMENT_SIZEis(OPTION_MTU - 28) & ~7, soOPTION_MTUis the true link MTU and 1504 gained nothing over 1500 - Behaviour change:
udp_raw_demonow sends segments of 1392 instead of 1472 bytes
- The previous value was 1504, a leftover of the pre-V2.1.11 convention where
- New example
cmp_demo: an emulated ASAM CMP (Capture Module Protocol) capture module carrying XCP, for testing XCP tools which communicate through capture modules. Implemented against ASAM CMP Protocol Layer Specification V1.1.0. Nothing CMP specific is inlibxcplite— the whole protocol lives in the example, behind theeth_hal_*interface.- A standalone CMake project consuming an installed xcplite via
find_package(xcplite), not built from the rootCMakeLists.txt - CMP over UDP (6.4.2). CMP over raw Ethernet is a possible later step
src/cmp.c— the envelope codec, verified byte exact against the sample PCAPNG files shipped with the specification- Injection uses
TX_DATA_MSG(message type0x04), which CMP 1.1 introduced and 1.0 does not have. Without it a capture module could only carry DAQ and XCP could neverCONNECT. Note that a CMP 1.0 dissector reports it as an unknown message type src/cmp_rest.c— the mandatory REST interface (12.3), read only. ItsTransmitterobject is how a Data Sink detects that transmission is supported (7.2.2); without it a tool may never injectsrc/cmp_discovery.c—CMP_CM_DISCOVERYresponder (12.1.1) on239.255.0.0:5556, serviced by the REST thread. Section 12 requires only one of three discovery approaches and permits static configuration with none, so this is optionaltest/cmp_codec_test.c,test/fake_sink.py(a minimal Data Sink),test/discovery_probe.py,test/test_local.sh(loopback) andtest.sh(on target)
- A standalone CMake project consuming an installed xcplite via
- New
docs/XCP_DISCOVERY.md: records what xcplib has for XCP's own multicast discovery today —GET_SERVER_ID_EXTENDEDimplemented,GET_SERVER_IDstubbed, both behindXCPTL_ENABLE_MULTICAST, which no shipped configuration enables and which the raw transport excludes — and the options for it. Nothing is decided or changed. Also records thatXCPTL_MULTICAST_PORTis 5557 while ASAM CMP 12.1 states XCP uses 5556, which needs checking against ASAM MCD-1 XCP. - IPv4 fragmentation is now prevented on the socket transport:
socketOpensets the DF bit on UDP sockets (IP_MTU_DISCOVER/IP_PMTUDISC_DOon Linux,IP_DONTFRAGon macOS/BSD,IP_DONTFRAGMENTon Windows, no-op on lwIP). Fragmentation is harmful for DAQ - one lost fragment loses the whole datagram and reassembly adds jitter - and anOPTION_MTUlarger than the path MTU previously degraded measurement silently. Oversized segments now fail withEMSGSIZEand a message naming the segment size and theOPTION_MTUto reduce. Behaviour change: a setup that relied on fragmentation will now report an error instead of silently fragmenting. - The lwIP socket path now reports a segment that does not fit the link MTU. lwIP sets no DF option - it has no
IP_DONTFRAG- so unlike Linux, macOS/BSD, QNX and Windows it does not refuse an oversized datagram: it fragments or drops it according to its ownIP_FRAGbuild setting, silently either way. That made lwIP the one transport where anOPTION_MTUlarger than the link MTU degraded measurement with no diagnostic at all.socketSendTonow compares the segment plus 28 bytes of IPv4/UDP headers againstnetif_default->mtuand warns once, with the same wording as the socket path. It still sends: this is a diagnostic, not a guard, since refusing a datagram lwIP may well deliver would change behaviour.netif_defaultis not necessarily the interface routing to the destination on a multi-homed target, so a false report is possible there. create_thread()on Windows now returns 0 on success, matchingpthread_create(), instead of evaluating to the threadHANDLEwhere non-NULL meant success. The two conventions were inverted, soif (create_thread(...) != 0)read as an error on POSIX and as success on Windows. A portable check is still not possible - both FreeRTOS variants aredo {} while (0)statements which assert - andplatform.hnow documents the contract per platform. No caller in the repository tests the result, so nothing changes in behaviour.- Version aligned to 2.2.1 in
CMakeLists.txt(whatfind_package(xcplite)reports) and inOPTION_VERSION_MAJOR/_MINOR/_PATCHinxcplib_cfg.h(whatXCP_DRIVER_VERSIONreports to the XCP client). The two had drifted apart at 2.1.2 and 2.1.10. - Fixed
PLATFORM_32_BITtypo inxcplib_cfg.h, which prevented the automatic selection ofOPTION_QUEUE_32on 32 bit platforms - Fixed missing
#include <errno.h>inshm.c, which broke theshmconfiguration build on macOS - Window build workaround to disable section based event pre-registration
- Fixed older XCP protocol layer versions 0x0100 to 0x0102
- Support static allocation and improve FreeRTOS robustness (#124)
- Support static allocation for FreeRTOS tasks and mutexes
- Use static storage when configSUPPORT_STATIC_ALLOCATION is enabled
- Preserve dynamic allocation and recursive mutex support
- Update FreeRTOS documentation and remove obsolete queue TODOs
- Fix FreeRTOS delay rounding and overflow
- Avoid unaligned IPv4 address access in FreeRTOS/lwIP
- Fix synchronization of FreeRTOS queue state
- Correct FreeRTOS queue and lwIP documentation
- Fix FreeRTOS emulator clock test build
- xcpclient related changes (xcpclient version 3.0.10):
- Improved variable registration for global and static variables
- Global variables and local static variables in functions without event trigger are registered, but not associated to any specific default DAQ event
- Unique typedef names for struct/class types with the same name in different namespaces, classes or functions (
motor_control.Input,valve_control.Input). Previously all variables of such types referenced the first registered typedef and were shown with the wrong type. - Global variables with the same name in different namespaces are registered with namespace qualified names (
motor_control.input,valve_control.input) instead of dropping all but the first one - A struct type which is used for measurement and for calibration variables gets separate typedefs
- The GCC declaration and definition entries of a namespace scope variable are merged, they no longer produce duplicate instance errors
- Variables with internal linkage in a namespace and without DWARF location (e.g. metadata markers
XCP_COMMENT(motor_control__input, ...)inside a namespace) are resolved by their mangled symbol name - Metadata annotations placed in the same namespace or function as the variable no longer need a scope prefix (
XCP_COMMENT(input, ...)in namespacemotor_controlannotatesmotor_control.input), explicit prefixes keep working. Metadata for the typedef fields of namespace qualified instances. - Local variables without a DWARF location (optimized away) are no longer resolved to the address of a global variable with the same name, only symbols with local binding are considered for them
- no_a2l_demo, no_a2l_demo_cpp: more demo cases, no_a2l_demo_cpp demonstrates types and variables with the same name in different namespaces
- Documentation: new
docs/OFFLINE_A2L.mdfor the offline A2L generation with xcpclient (workflow, naming rules, supported types, diagnostics),docs/TECHNICAL.mdkeeps the library topics and the instrumentation marker contract, xcpclient and no_a2l_demo READMEs updated
- FreeRTOS related changes:
- Allow custom memory attributes for queue32m
- Avoid mutex allocation when queue32m uses critical sections
- Support optional recursive FreeRTOS mutexes
- Fix typos in FreeRTOS documentation and comments
- Fix UDP segment size calculation from MTU
- Make FreeRTOS queue segment count configurable
- Build cleanup:
shm.handpersistence.hare only included where the corresponding feature is enabled, reducing overhead for minimal embedded source subsets xcpclientrelated changes:- EPK validation — A2L file EPK is now compared against the EPK reported by the target; mismatch prints a warning and aborts unless overridden with
--yes - Dependency on
mc_registryswitched to publicRainerZ/xcp-lite3.0.9 - Improved error message when AML file is not found
- Uses ELF section boundary variables as fallback event detection when
xcp_evtssection is absent - Fixed ESP32 image containing multiple DROM segments.
- Handle C++ class types and fix empty typedefs for template structs in offline A2L generation
- The DWARF type reader was merged up to a2ltool 3.4.1.
- Unique names for field typedefs in the A2L writer (
xcp_registryupdate) - Fixed the size of pointer members in structs and classes
- No panic on ELF files without
xcp_evtssection or with duplicate event markers - README section on supported types and limitations, unit tests with a C++ type fixture
- Fixed free_rtos_esp32_demo linker map section based event detection when dynamic event management is disabled.
- EPK validation — A2L file EPK is now compared against the EPK reported by the target; mismatch prints a warning and aborts unless overridden with
- Documentation improvements.
- Fixed metadata macros XCP_LIMITS (missing ;) and XCP_READ_WRITE ([])
- Fixed link type_detection_test against xcplite for XCPLITE_CONFIGURATION define
-
XCP DAQ event info (#define XCP_ENABLE_DAQ_EVENT_INFO) support for disabled OPTION_DAQ_EVENT_LIST with section registered events
-
New example
no_a2l_demo_cppdemonstrating build-time A2L generation for C++ -
A2L generator declarations conditionally removed from public API headers (
inc/xcplib.h,inc/xcplib.hpp) for non-A2L configurations -
C++ namespace alias
xcplibremoved (breaking change for code usingxcplib::instead ofxcplite::) -
XcpSetA2lNameandXcpGetA2lNameare now independent from enabling the A2L generator -
Hardcoded maximum calibration segment name length limited by alignment requirements
-
Fixed
cpp_demoshutdown issue -
Windows build fixes
-
Removed code definition of
_GNU_SOURCE, made it public in CMakeLists.txt -
xcpclientrelated changes:- New
XCP_READ_WRITEmetadata macro - Added enum conversion support in ELF->A2L converter
- Updated
mc_registry,gimliandobjectcrate dependencies to latest versions - New options
--elf_skip_no_metadataand--config <xcpclient.toml> - Various bugfixes in debuginfo parsing and
no_a2l_demoevent handling
- New
- Critical bugfix in ´XcpEventExt_´, undefined behaviour when DAQ is not running
- Optimizations for microcontroller/RTOS builds, optimized locking (critical section instead of mutex) and static allocated queue (new ´queue32m.c´)
- Link time, deterministic event id assignment (´tXcpEventDescriptor´ in section ´xcp_evts´)
- Implemented ´XCP_LIMIT´, XCP_COMMENT and ´XCP_UNIT´ metadata definition to support A2L generation in RTOS use cases (new linker section ´xcp_meta´). See example no_a2l_demo for details
- ´xcpclient´ tool refactoring and bugfixes, xcp_registry dependency switched back to ´xcplite´ crate main on VectorGrp
- Made OPTION_DAQ_EVENT_LIST an configuration override and removed special configuration handling with XCPLIB_FOR_RUST
- Enabled 1ms event ´async´ (event id 0) as default event for global variables in RTOS builds
- ´XcpGetEcuEpk´ renamed to ´XcpGetLocalEpk´ for clarity in SHM mode
- silkit_demo updated
- ´DaqCreateEventExt´ fixed
- Asserts removed from the DAQ trigger macros
- freertos_stm32_demo with FreeRTOS and lwip for STM32 microcontrollers
- More flexibility how to provide the DAQ timebase
- Single source demo code for all FreeRTOS examples
- cmake build system revisited, build configurations and build options
- Improved convenience build script
- README files for all example applications
- xcpclient only uses the registry (xcp-lite xcp_registry crate), not the full Rust xcp-lite stack
- esp32_freertos_demo with FreeRTOS and lwip
- freertos_demo using FreeRTOS POSIX emulator port
- Heap allocation removed from socket platform abstraction layer
- Improved compatibility for 32 bit microcontroller RTOS operating systems (like freeRTOS, zephyr, ThreadX etc.)
- Improved support for offline A2L creation from ELF files, file system dependency is now optional
- XCP event and segment descriptor memory sections to preregister events and calibration segments/block in XcpInit, for deterministic event numbers without .BIN file
- The A2L generator in xcpclient can create an A2L file template with XCP events and segments from the ELF file only, by inspecting the event and segment descriptor memory sections
- Optional custom GET_ID to download the ELF file instead of the A2L file
- Addressing schema XCPLITE__AXSDD, memory access via callbacks, no calibration segment management
- gcc compatibility issue fixed
- Bug fixes and improvements, see commit history for details
silkit_demowith optional separate XCP server participant
- New demo
silkit_demodemonstrating XCP instrumentation of a sil-kit participant - Minor bug fixes and improvements
- Application specific memory addressing mode fixed, demo in example c_demo
- General refactoring and code cleanup, various minor code improvements and optimizations
- Renamed to
libxcplitewith external package namexcplite - DAQ performance optimization, lock-less transmit queue for vectored IO
- New function XcpCreateCalBlk to create calibration blocks without A2L memory segments
- Simplified build script and CMake configuration, build script option to install libxcplite
- Changed default encoding for dynamic addressing to 10 Bit event and 22 Bit signed offset, allowing for up to 4GB addressable range per event with max 1024 events
- New variadic C++ macro/template to create A2L typedefs and their components in one call with automatic type deduction (see hello_xcp_cpp example)
- New API functions to specify input quantities for axis
- New convenience functions in platform.c: clockGetMonotonicNs() and clockGetRealtimeNs()
- New demo
ptp4l_demodemonstrating minimum requirement to achieve XCP PTP support - Refactoring in platform.c socket abstraction: socket error handling, OPTION_SOCKET_HW_TIMESTAMPS, new function socketSetTimeout, improved debug logging for socketRecvFrom to help diagnose interface index issues on Linux, SOCKET keeps track of configured interface
- Log level 6 for very verbose debug logging
- Define GNU_SOURCE in cmakelists.txt
- xcpclient tool in Rust for testing and for offline A2L generation
- Improved Windows performance
- The signature of XpcInit has changed to
void XcpInit(const char *name, const char *epk, uint8_t mode);- The return value contract of
socketRecvandsocketRecvFromhas changed. Only code that uses these functions directly (i.e. code that includessocket.his affected)
- Multi application mode (OPTION_SHM_MODE). See
SHM.mdfor details.
- New variadic data acquisition C macro or C++ macro/template (
DaqEventVar) - Support for enabling and disabling individual DAQ events at runtime (
DaqEventEnable,DaqEventDisable) - New demo
point_cloud_demodemonstrating how to visualize arrays of objects in the CANape 3D scene window
- Removed .out extension from the binaries on Linux and macOS builds
- Improved thread safety of event creation to avoid unnecessary THREAD_LOCAL state
- Optimized A2L generation macros, inlined address calculations moved into A2L creator functions
- Auto addressing mode now supports absolute and relative addressing
- More idiomatic C++ code in examples
- Bug in transmit thread queue handling causing too many packets sent
- Fixed cpp_demo assertion
- A2L transport layer section removed when bound to ANY and IP address auto-detection is off
- Support for hardware timestamping in platform.c for Linux
- Async event and prescaler turned off by default
- Improved code documentation and comments
- Refactored example applications for better clarity
- Various minor code improvements and optimizations
- XcpInit signature changed to
void XcpInit(const char *name, const char *epk, bool activate);- A2lInit signature changed to
bool A2lInit(const uint8_t addr[4], uint16_t port, bool use_tcp, uint32_t mode);- CalSeg constructor signature changed, takes a pointer to the default parameters
CalSeg(const char *name, const T *default_params)- A2lTypedefBegin gets a pointer to any instance of the type.
- A2lTypedefParameterComponent does not need the typename parameter anymore
- A2lTypedefMeasurementComponent does not need the typename parameter anymore and has a comment parameter
{
A2lTypedefBegin(ParametersT, &kParameters, "A2L Typedef for ParametersT");
A2lTypedefParameterComponent(min, "Minimum random number value", "Volt", -100.0, 100.0);
A2lTypedefParameterComponent(max, "Maximum random number value", "Volt", -100.0, 100.0);
A2lTypedefEnd();
}
- DaqCreateEventInstance does not return the event id anymore, new function DaqGetEventInstanceId to get the event id from the name
```c
DaqCreateEventInstance("task");
tXcpEventId task_event_id = DaqGetEventInstanceId("task");- BIN format changes to enable future feature extensions, old BIN files are not compatible anymore
- Absolute or relative calibration parameter segment addressing (
OPTION_CAL_SEGMENTS_ABSinxcplib_cfg.h) - More flexible addressing scheme configuration (see
xcp_cfg.h) - Generated A2L file uses the
project_noidentifier to indicate the configured addressing schema (currently ACSDD or CASDD) - Support for more than one base address in relative address mode, variadic function to trigger event with multiple base addresses
- Optional async event with 1ms cycle time and prescaler support (
OPTION_DAQ_ASYNC_EVENTinxcplib_cfg.h) - Different options to control the behavior of calibration segment persistence and freeze
- Memory optimization for event/daq-list mapping
- XCP_ENABLE_COPY_CAL_PAGE_WORKAROUND to enable workaround for CANape init calibration segments bug
- Variadic macro to create, trigger, and register local and member variables in one call with automatic addressing mode deduction (see hello_xcp_cpp example)
DaqEventExtVar(avg_calc1, this, //
(input, "Input value for floating average", "V", 0.0, 1000.0), //
(average, "Current calculated average"), //
(current_index_, "Current position in ring buffer"), //
(sample_count_, "Number of samples collected"), //
(sum_, "Running sum of all samples")
);- Signature of
xcplib::CreateCalSegchanged, pointer to reference page - Automatic EPK segment is now optional (
OPTION_CAL_SEGMENT_EPKinxcplib_cfg.h)
- Tool
bintoolto convert XCPlite-specific BIN files to Intel-HEX format and apply Intel-HEX files to BIN files - New demo
no_a2l_demoto demonstrate workflows without runtime A2L generation (using a XCPlite-specific A2L creator, see README.md ofno_a2l_demo) - New demo
bpf_demoto demonstrate usage of XCPlite together with eBPF programs for Linux kernel tracing (see README.md ofbpf_demo) - Internal naming convention refactored to support A2L creation for dynamic objects from ELF/DWARF binaries
- Rust xcp-lite >V1.0.0 uses the calibration segment management of XCPlite instead of implementing its own
- Various bug fixes
- Breaking changes from V0.6
- Lockless transmit queue (works on x86-64 strong and ARM-64 weak memory models)
- Measurement and read access to variables on stack
- Calibration segments for lock-free and thread-safe calibration parameter access, consistent calibration changes, and page switches
- Support for multiple segments with working and reference page and independent page switching
- Build as a library
- Used as FFI library for the Rust xcp-lite version
- Refactored A2L generation macros