{"id":42019133,"url":"https://github.com/vectorgrp/xcp-lite","last_synced_at":"2026-01-26T03:31:03.707Z","repository":{"id":250668460,"uuid":"810301447","full_name":"vectorgrp/xcp-lite","owner":"vectorgrp","description":"XCP for Rust","archived":false,"fork":false,"pushed_at":"2025-09-27T16:59:49.000Z","size":16485,"stargazers_count":20,"open_issues_count":0,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-14T18:24:27.143Z","etag":null,"topics":["a2l","asam","autosar","canape","mdf","rust","sdv","vector","xcp","xcplite"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vectorgrp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-06-04T12:34:05.000Z","updated_at":"2025-10-12T23:59:23.000Z","dependencies_parsed_at":"2024-09-16T00:14:40.375Z","dependency_job_id":"0649f24b-bcd7-4e6e-8889-e2a572260da4","html_url":"https://github.com/vectorgrp/xcp-lite","commit_stats":null,"previous_names":["vectorgrp/xcp-lite"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vectorgrp/xcp-lite","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vectorgrp%2Fxcp-lite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vectorgrp%2Fxcp-lite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vectorgrp%2Fxcp-lite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vectorgrp%2Fxcp-lite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vectorgrp","download_url":"https://codeload.github.com/vectorgrp/xcp-lite/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vectorgrp%2Fxcp-lite/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28765881,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T03:19:35.311Z","status":"ssl_error","status_checked_at":"2026-01-26T03:19:13.815Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["a2l","asam","autosar","canape","mdf","rust","sdv","vector","xcp","xcplite"],"created_at":"2026-01-26T03:31:03.189Z","updated_at":"2026-01-26T03:31:03.701Z","avatar_url":"https://github.com/vectorgrp.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# xcp-lite\n\nXCP for Rust - Rust API for XCPlite (\u003chttps://github.com/vectorgrp/XCPlite\u003e)  \n  \n\nxcp-lite is a Rust API for measurement and calibration, which uses the ASAM XCP protocol for communication with a measurement and calibration tool like CANape and ASAM A2L for data description.  \n\nThis is no complete implementation of XCP in Rust, the protocol and transport layer implementation is in C/C++ based on XCPlite.  \nFor more details on XCP and XCPlite, see \u003chttps://github.com/vectorgrp/XCPlite\u003e.  \n\nMain purpose was to experiment with Rust and to demonstrate some more advanced features of measurement and calibration with CANape:\n\n- Automatic A2L and IDL generation with proc-macros\n- A transparent wrapper for calibration variables which provides synchronized and memory safe calibration access\n- Support for offline calibration, calibration page switching, reinit, load and save to json file\n- Measurement of dynamic variables from stack or heap\n- Measurement of variables with non static lifetime\n- Measurement of thread local data instances\n- Data objects and containers with dynamic size like point clouds or detection lists, to demonstrate CANape ADAS features\n- Support Google protobuf or OMG DDS/CDR serialized data objects with XCP and CANape\n\nRequires CANape 22 or later. Example projects are updated to CANape 23.  \n  \n## Introduction\n\nXCP is a measurement and calibration protocol commonly used in the automotive industry. It is an ASAM standard.  \n\nIt provides real time signal acquisition (measurement) and modification of parameter constants (calibrations) in a target micro controller system (ECU), to help observing and optimizing control algorithms in real time.  \n  \nTimestamped events, measurement variables and parameter constants are described by an ASAM-A2L description file, another associated ASAM standard.\nData objects are identified by an address. In a micro controller system programmed in C or C++, these addresses are used to directly access the ECUs memory, like a debugger would do. This concept has minimum impact on the target system in terms of memory consumption and runtime. The A2l is a kind of annotated ELF Linker-Address-Map, with rich semantic information on data instances and data types.  \nIn a higher abstraction level programming language, XCP can be treated as a serializer/deserializer, where A2L is the schema, which is generated from the target software data types and instances. Measurement signals and calibration parameters must have static lifetime and a defined memory layout, but no predefined memory location. Data acquisition and modification is achieved by appropriate code instrumentation for measurement and wrapper types for calibration parameters and parameter groups.  \n\nThe ASAM-XCP standard defines a protocol and a transport layer. There are transport layers for all common communication busses used in the automotive industry, such as CAN, CAN-FD, FLEXRAY, SPI and Ethernet.  \n\nXCPlite (\u003chttps://github.com/vectorgrp/XCPlite\u003e) is a simplified implementation of XCP in C,C++, optimized for the XCP on Ethernet Transport Layer.  \n\nIn C or C++ software, A2L data objects are usually created with global or static variables, which means they have a constant memory address. XCPlite for C++ introduced an additional code instrumentation concept to measure and calibrate instances of classes located on heap. It is still using direct memory access, but A2L addresses are relative and the lifetime of measurement variables is associated to events.\n\nAn implementation of XCP in Rust, with direct memory access, will get into conflict with the memory and concurrency safety concepts of Rust. In Rust, mutating static variables by using pointers is considered Unsafe code, which might create undefined behavior in parallel access. Thread safety when accessing any data will be strictly enforced.\n\nxcp-lite (\u003chttps://github.com/vectorgrp/xcp-lite\u003e) is an implementation of XCP for Rust. It provides a user friendly concept to wrap structs with calibration parameters in a convenient and thread safe type, to make calibration parameters accessible and safely interior mutable by the XCP client tool.\nTo achieve this, the generation of the A2L description is part of the solution. In XCPlite this was an option.\nA2L objects for events and measurement values will be lazily created during startup, using a runtime registry and a proc-macro to create calibration parameter descriptions from structs.\n\nThe calibration parameter wrapper type CalSeg enables all advanced calibration features of a measurement and calibration tool like CANape. An instance of CalSeg creates a memory segment, which enables version checking, checksum calculation, offline and indirect calibration, page switching and parameter persistence (freeze and init). It also provides parameter persistence to a json file.  \n\nxcp-lite also implements a concept to measure variables on stack or as thread local instances.\n\nCurrently xcp-lite for Rust uses a C library build from XCPlite sources, which contains the XCP server, an ethernet transport layer with its rx/tx server threads, the protocol layer, time stamp generation and time synchronization. The C implementation is optimized for speed by minimizing copying and locking data. There are no heap allocations during runtime. The Rust layer includes the registry and A2L generation, wrapper types for calibration parameters and macros to capture measurement data on events.\n\nThe code should work on Linux, Windows and Mac, Intel and ARM.  \n  \nThe project creates a library crate xcp and a main application to demonstrate all use cases. An entry level example is hello_xcp in the example folder. There are other, more specific examples in the examples folder.  \n\nThere is an integration test, where the crate a2lfile is used to verify the generated A2L file and a quick and dirty, tokio based XCP client with hardcoded DAQ decoding for black box testing.\n\n## Examples  \n\n### xcp-lite (xcp-lite/src/main.rs)\n\nMain application of the crate\nDoes not serve demonstration purposes, better refer to the examples below\nManually check various measurement and calibration features with the CANape project in ./CANape  \n\n### hello_xcp\n\nA very basic example  \nMeasure a local variable and calibrate a parameter of basic scalar type\n\n### struct_measurement_demo\n\nDemonstrates measurement data collection of more complex types, such as struct, arrays of struct and multi-dimensional array slices\nAlso has some basic calibratable scalar parameters\nThis demo generates A2L objects TYPEDEF and INSTANCES  \n\n### calibration_demo\n\nDemonstrate various calibratable basic types, nested structs and multi dimensional types with shared axis and associated lookup functions with interpolation  \nThis demo generate A2L objects CURVE and MAP with shared AXIS_PTS  \n\n### single_thread_demo\n\nShows how to measure and calibrate in a single instance task thread  \nShows how to clone a calibration parameter set, move it to a thread and sync its calibration changes  \n\n### multi_thread_demo\n\nShows how to measure and calibrate in a task instantiated in multiple threads with multiple instances of measurement events and local variables\n\n### rayon_demo\n\nUse CANape to observe rayon workers calculating a mandelbrot set line by line\n\n### tokio_demo\n\nDemonstrates using XCP in an async tokio based application\n\n### point_cloud_demo\n\nMeasure a lidar point cloud and visualize it in CANapes 3D scene window  \nUse CDR serialization over XCP and the CDR/IDL schema generator proc-macro\n\n## Code instrumentation for measurement and calibration\n  \nThere are 3 important types: Xcp, XcpEvent/DaqEvent and CalSeg.  \nXcp is a wrapper for XCPlite. It is a singleton. There is a builder to initialize the XCP server or ethernet transport layer.\n  \nCalSeg is a generic type used to encapsulate structs containing calibration parameters. This is called a calibration segment and the parameter struct wrapped is a calibration page. A calibration page must be Copy and may contain nested structs of basic types or arrays with dimension up to 2.  \n  \nA CalSeg has interior mutability. Parameter mutation happens only on acquiring a calibration segment guard.\n  \nA CalSeg may be shared among multiple threads. It it cloned like an Arc, implements the Deref trait for convenience and does not do any locks to deref to the inner calibration parameter page struct.\n\nMeasurement code instrumentation provides event definition, registration or capture of measurement objects. Measurement objects can be captured (copied to a buffer inside the event) or accessed directly on stack memory after being registered. Capture works for variables on heap or stack. Measurement variables can be registered as single instance or multi instance, which creates one variable instance for each thread instance. Variable names and event names are automatically extended with an index in this case.\n\nThe registration of objects has to be completed, before the A2L file is generated. The A2L is created at latest on connect of the XCP client tool. Objects created later, will not be visible to CANape.  \n  \n## Safety Considerations\n\nThe fundamental functional concept of this XCP implementation is, to mutate the calibration variables in their original binary representation in a thread safe, transparent wrapper type.  \nThe implementation restricts memory accesses to the inner calibration page of a calibration segment, but does not check the correctness of modifications inside the calibration page.\nAs usual, the invariants to consider this safe, include the correctness of the A2L file and of the XCP client tool. When the A2L file is uploaded by the XCP tool on changes, this is always guaranteed.\nThe wrapper type is Send, not Sync and implements the Deref trait for convenience. This opens the possibility to get aliases to the inner calibration values, which should be avoided. But this will never cause undefined behavior, as the values will just not get updated, when the XCP tool does a calibration page switch.\n\nCode in Unsafe blocks exists in the following places:\n\n- The implementation of Sync for CalSeg  \n- In particular the XCPlite bindings XcpEventExt for measurement and cb_read/cb_write for calibration, which carry byte pointers and memory offsets of measurement and calibration objects  \n- And formally all calls to the C FFI of the XCPlite server (optional), transport layer and protocol layer  \n\nA completely safe measurement and calibration concept is practically impossible to achieve, without massive consequences for the API, which would lead to much more additional boilerplate code to achieve calibration.\nThe memory oriented measurement and calibration approach of XCP is very common in the automotive industry and there are many tools, HIL systems and loggers supporting it.  \nXCP is used during the development process only, it is never integrated in production code or it is disabled by save code.\n\n## Build\n\n### Features\n\nFeatures are:\n\n- a2l_reader\nCheck A2L file after generation before upload\n\n### Build, Run, Test\n\nBuild, Run, Test examples:\n\n```\nBuild:\n  cargo b \n  cargo b --release \n  cargo b --features a2l_reader\n\nRun the main example:\n  cargo r -- --bind 127.0.0.1 --log-level 4\n  cargo r -- --port 5555 --bind 172.19.11.24 --tcp \n \nRun a specific example:\n  cargo r -p struct_measurement_demo\n  cargo r -p xcp_client  \n\n```\n\nTest\n\nTests may not run in parallel, as the XCP implementation is a singleton.\nFeature a2l_reader is needed for xcp_client based testing\n\n```\n  cargo test --features=a2l_reader  -- --test-threads=1 --nocapture\n  cargo test --features=a2l_reader  -- --test-threads=1 --nocapture  --test test_multi_thread\n```\n\nUse --nocapture because the debug output from the XCPlite C library is via normal printf\n\n## Notes\n\nLike in C/C++ XCPlite, all measurement and calibration code instrumentation is non blocking and lock-free.\nThere are no heap allocation during runtime, except for the lazy registrations for A2L generation.\n  \nbuild.rs automatically builds a minimum static C library from individually pre configured core XCPlite sources.\n\nThe generated A2L file is finalized on XCP connect and provided for upload via XCP.\n\nThe proc macro for more convenient A2L generation is still in an experimental state.\n\nMeasurement of local variables is done with a macro which either copies to a static transfer buffer in the event or directly accesses the value on stack.  \nThis involves a lazy initialization of the structures to build the A2l file describing the local variables.  \n\nThe EPK version string in the A2L file can be set by the application. It resides a separate, hardcoded const memory segment.  \n\n## CANape\n\nTo use one of the CANape projects included, use 'Project/Open\" and select the file CANape.ini in the CANape folder.  \n\nThe examples are build with CANape 23.\nOlder versions were not tested.\n\n![CANape](CANape.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvectorgrp%2Fxcp-lite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvectorgrp%2Fxcp-lite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvectorgrp%2Fxcp-lite/lists"}