The Eclipse Leda project provides system image “recipes” to deliver a functional and always-available Linux-based image/distribution in the context of SDV (Software Defined Vehicle), by pulling together individual contributor pieces from Eclipse SDV and the larger OSS community.
The quickstart images help to learn how the SDV development, test and deployment lifecycle works from an E2E perspective, including the deployment of applications into the container runtimes on constrained embedded devices.
The ready images are also useful for quickly setting up showcases with virtual or real hardware devices.
Eclipse Leda provides a Poky-based reference build pipeline and an OpenEmbedded Metalayer meta-leda for integration into existing Yocto-based projects.
The Eclipse Leda project will provide system image “recipes” to deliver a functional Linux-based image/distribution in the context of SDV (Software Defined Vehicle), by pulling together individual contributons from the SDV and the larger OSS community.
The Eclipse Leda distribution will work with build scripts, package definitions, image build pipelines, etc, with the goal to pull SDV projects and dependecies from the larger OSS community into a working Linux system. Such system images (or other useful forms of delivery, as determined by the project) will be made available for consumption for anyone who is interested in working with the SDV tech stack. These deliveries take the form of container (base) images, installable/flashable image files, etc (again to be evolved by the project team according to community needs). Also in scope is concise and useful documentation for consumers of the project’s deliverables, plus a method of delivering that documentation.
In the context described above - the ambition of SDV to build a technology ecosystem for software-defined vehicle concern - a prime challenge will be the combination of these initially diverse components into a coherent and useful whole: all the software components in the world will not have the impact needed to transform the automotive industry unless we can make them play together coherently an form a functional portfolio. As a first step towards that goal, this proposal (Eclipse Leda) is for a “SDV distribution” project that pulls together individual contributor pieces from SDV and the larger OSS community, to deliver a functional and always-available Linux-based image/distribution with two primary goals:
be the crystalization point for functionally integrating diverse SDV-scope projects into a working whole
deliver a continually available, always working starting image for developers interested in getting going with the SDV tech stack
1.1 - Architecture
Runtime Overview
The runtime overview shows the general layer architecture for the runtime of the SDV edge stack as implemented by the Leda quickstart image.
Dotted lines indicate out-of-scope components. They may be non-Edge components (such as cloud services, or SDKs and additional development tooling for vehicle applications). Dotted lines for in-vehicle edge components indicate that they may be used, but are not pre-installed or pre-configured on the Leda quickstart image.
Deployment Overview
Eclipse Leda can be used in different deployment scenarios: on physical hardware, on virtual machines or installed on existing Linux distributions.
Depending on the specific deployment, some features may not be applicable. Each deployment option is meant for different uses. The applicabability
depend to your specific requirements.
Option 1: Hardware - Suitable for proof-of-concepts, system integration tasks, access to actual physical actuators and sensors.
However, an automated setup is much harder to realize, as additional hardware for remote controlling of power supply is needed.
The constrained environment of a physical device is good to verify accidental assumptions made by application developers,
such as resource consumptions (CPU, memory) or the existence of Linux tools, Kernel modules or device drivers.
Option 2: Docker Containers - Good for quick startup and throw-away (ephemeral) uses, such as automated system testing or one-off troubleshooting.
The access to physical hardware is limited and more complicated to set up. QEMU provides emulation of devices, such as CAN-Bus.
Due to multiple nesting of abstraction technology (Docker + QEMU + OS), additional configuration of networking and device pass-thrus are necessary.
It’s easy and cheap to spin-off many separate instances to simulate a whole vehicle system with multiple vehicle computers and
simulated ECUs in the same vehicle network.
Option 3: Package Installation - Good for existing devices with feature-rich functionality where the original OS should be used.
Leda does not support self-update for this deployment option, as it relies on the master OS distribution channels.
The constraints of an embedded device are not replicable easily on a PC-style host machine without additional effort.
Package installation is good when the focus is on exploring the Vehicle Applications, SDKs, Vehicle Signal Abstractions etc.
Option 1: Hardware
Option 2: Docker Containers
Option 3: Package Installation
Target use case
PoC
Automation
Existing devices
Cloud communication
++
++
+++
Automation
–
+++
++
Device provisioning
++
++
+++
Access to hardware
+++
-
++
Container isolation
+++
++
+++
Network flexibility
+++
-
++
Self update
+++
+
–
Realistic constrains
+++
-
-
Build Environment Overview
1.2 - Features
Publish/Subscribe messaging infrastructure for cloud connectivity by Eclipse Kanto
local messaging for applications and SDV system components via an MQTT message broker
connection to a backend messaging hub, such as Azure IoT Hub or the IoT Suite
device identification and authentication for cloud connectivity by using TLS device certificates
Container runtime
An OCI-compliant container orchestration for vehicle applications and services by Eclipse Kanto
containerd.io as the default container runtime. Both layers of container runtimes can be exchanged with other implementations
A Vehicle Update Manager to orchestrate deployments of Vehicle Applications, configurations and base operating system updates
An example Vehicle Seat Service implementation to showcase
An OpenTelemetry collector and example configurations to collect and publish logs and metrics of containerized Vehicle Applications to the cloud backend for further processing
The features of the reusable build recipes implemented as an OpenEmbedded metalayer meta-leda are:
Build recipes for a Yocto-based distribution to build SDV-related software components
Build recipes for customizations of the target device’s storage structure to enable A/B system updates
Build recipes for pre-packaging container images into the device during the manufacturing process to minimize initial online provisioning time
A customized minimal setup for use on constrained devices and a full setup with convenient developer tools
Ready images for virtual devices, for automated testing and evaluation purposes, eg QEMU ARM-64
Ready images for physical devices, for evaluation and demo purposes, eg Raspberry Pi 4
1.3 - Goals
The project aims to provide an integration point for Open Source components for the Software Defined Vehicle ecosystem.
In a complex architecture, there are many different ways of implementations and alternative solutions possible.
For embedded vehicle computer systems and their software stack, there are a lot of requirements to consider, depending on the actual use cases:
Integration and High-Level Testing (System Integrators, Suppliers)
Open Source Collaboration (Developers, OEMs, ISVs, Open Source Organizations, Standardization Organizations)
Some of the requirements derived from the above are taken into account for Leda’s quickstart setups.
Thereas some other requirements can only be met once the project is in a nearer production environment and by customizing the target device image.
The following document will list some of these requirements and give an explanation on why they are set as goals in the Leda quickstart distribution.
Overview
Provide an example operating system build and configuration for constrained in-vehicle devices:
Suppliers and system integrators want a way to cusomize and optimize the base operating system as much as possible.
This is to achieve a high efficiency, high level of reuse and cost benefits of the planned hardware.
The build system for the operating system, and the selection of the underlying distribution is key to the convenience for new users,
but also commercially a business decision with an impact on the future maintainability of the platform.
The Yocto Project has been chosen as an established de-facto standard for customized Linux distributions for embedded systems.
Leda provides an OpenEmbedded Meta-Layer, which can be used with many existing SDKs of SoC manufacturers.
Additionally, Leda will strive for being easy to install on low-cost “evaluation boards” such as the Raspberry Pi,
or development environments such as a virtual machine in the cloud.
Integrate software-defined-vehicle Open Source components to showcase the available features and their state of maturity:
The SDV ecosystem will grow and a lot of new software projects will be needed to solve the current problems and challenges.
The Eclipse SDV ecosystem already contains many software packages, which independently make sense for their set goals.
With Leda, we want to increase the integrational aspect, helping project leads, developers, contributors, users and architects
to evaluate the SDV portfolio, how it can be integrated with each other and how a possible reference architecture implementation might be loooking like.
Demonstrate the use and interaction of open protocols and specifications:
OpenTelemetry specs and components, to show the possibilities of applying DevOps methodologies and technologies
to operate, monitor and maintain fleets of vehicles and their distributed software applications
Eclipse IoT related specifications for software rollouts and digital twin representations
1.4 - Roadmap
Initial Open Source contribution expected by Q2 2022 (Done)
A first milestone build is expected end of 2022 (Done)
Plan for the first release cycle to be created in Q1/2023 (In Progress - Q2/2023)
Release cycles are planned every 3-6 months
Release planning will be conducted together with corresponding Eclipse projects
First pre-release of Eclipse Leda quickstart images, based on Yocto LTS release
Kirkstone with Long Term Support until at least April 2024.
Minimal feature set to run software-defined-vehicle applications (such as Eclipse Velocitas apps) using COVESA Vehicle Signal Specification
and the Eclipse Kuksa.VAL Databroker on virtual devices (QEMU), in Docker,
or on physical consumer-grade devices (Raspberry Pi 4 64-Bit) for development, demonstration and prototyping purposes.
Includes example applications from Kuksa:
Example Seat Service
Example HVAC Service
DBC Feeder replays a Tesla Model 3 CAN-Dump and feeds it into Kuksa.VAL Databroker
Switched to a BitBake build using kas for layer management
Added automated system tests using Robot framework and Dockerized environments
General cleanup of recipes, dependencies and structuring of the meta-leda sublayers to improve reusability
Automatic deployment of containers based on container manifests with ad-hoc updates (filewatcher in kanto-auto-deployer)
Preparation for AirGap installation of containers
General improvements, such as Wifi network management
Known Issues
The following issues were known to the development team before starting the 0.1.0-M1 build cycle.
They have been prioritized as non-critical and may be fixed for later releases.
Rule: OCaaS Policy A9 License with no classification
Message: The license LicenseRef-scancode-biosl-4.0 found for package ‘Unmanaged::leda-distro-fork:0716b55ff8f57319263d67ee16d90e64588b391d’ is not categorized and / or evaluated for usage.
Evaluation: This license seems to be detected incorrectly by the tool being used, as it is an internal, proprietary license which is not used in the Eclipse Leda project.
Incorrectly detected license “GPL-1.0” for ORT configuration file
Rule: OCaaS Policy C1 Strict Copyleft
Message: License GPL-1.0-only found for package ‘Unmanaged::leda-distro-fork:0716b55ff8f57319263d67ee16d90e64588b391d’ is categorized as strict-copyleft which must not be used for BT11 Open Source Development service applications.
Evaluation: The scan tool incorrectly detects its own configuration file (.ort.original.yml) as being licensed under GPL-v1.0
Incorrectly detected license “GPL-2.0-only” for standard Leda license header (which is Apache Software License)
Rule: OCaaS Policy C1 Strict Copyleft
Message: License GPL-2.0-only found for package ‘Unmanaged::leda-distro-fork:0716b55ff8f57319263d67ee16d90e64588b391d’ is categorized as strict-copyleft which must not be used for BT11 Open Source Development service applications.
Evaluation: The scan tool incorrectly detects the Apache License header as GPL-2.0 license text
Incorrectly detected license “proprietary”
Rule: OCaaS Policy C3 Commercial
Message: License LicenseRef-scancode-proprietary-license found for package ‘Unmanaged::leda-distro-fork:0716b55ff8f57319263d67ee16d90e64588b391d’ is categorized as commercial and requires special handling.
Evaluation: The scan tool incorrectly detects its own configuration file (.ort.original.yml) as being licensed under proprietary licenses.
First pre-release of Eclipse Leda quickstart images, based on Yocto LTS release
Kirkstone with Long Term Support until at least April 2024.
Minimal feature set to run software-defined-vehicle applications (such as Eclipse Velocitas apps) using COVESA Vehicle Signal Specification
and the Eclipse Kuksa.VAL Databroker on virtual devices (QEMU), in Docker,
or on physical consumer-grade devices (Raspberry Pi 4 64-Bit) for development, demonstration and prototyping purposes.
Includes example applications from Kuksa:
Example Seat Service
Example HVAC Service
DBC Feeder replays a Tesla Model 3 CAN-Dump and feeds it into Kuksa.VAL Databroker
Change log 0.1.0-M2
Remove skopeo dependency from packagegroup-sdv-tools.bb
Fix typo in SRCREV_FORMAT for pahocpp
dd kernel config for RAUC stream mode to raspberrypi4-64 and qemuarm64
Switched to a BitBake build using kas for layer management
Added automated system tests using Robot framework and Dockerized environments
General cleanup of recipes, dependencies and structuring of the meta-leda sublayers to improve reusability
Automatic deployment of containers based on container manifests with ad-hoc updates (filewatcher in kanto-auto-deployer)
Preparation for AirGap installation of containers
General improvements, such as Wifi network management
Known Issues
The following issues were known to the development team before starting the 0.1.0-M1 build cycle.
They have been prioritized as non-critical and may be fixed for later releases.
Rule: OCaaS Policy A9 License with no classification
Message: The license LicenseRef-scancode-biosl-4.0 found for package ‘Unmanaged::leda-distro-fork:0716b55ff8f57319263d67ee16d90e64588b391d’ is not categorized and / or evaluated for usage.
Evaluation: This license seems to be detected incorrectly by the tool being used, as it is an internal, proprietary license which is not used in the Eclipse Leda project.
Incorrectly detected license “GPL-1.0” for ORT configuration file
Rule: OCaaS Policy C1 Strict Copyleft
Message: License GPL-1.0-only found for package ‘Unmanaged::leda-distro-fork:0716b55ff8f57319263d67ee16d90e64588b391d’ is categorized as strict-copyleft which must not be used for BT11 Open Source Development service applications.
Evaluation: The scan tool incorrectly detects its own configuration file (.ort.original.yml) as being licensed under GPL-v1.0
Incorrectly detected license “GPL-2.0-only” for standard Leda license header (which is Apache Software License)
Rule: OCaaS Policy C1 Strict Copyleft
Message: License GPL-2.0-only found for package ‘Unmanaged::leda-distro-fork:0716b55ff8f57319263d67ee16d90e64588b391d’ is categorized as strict-copyleft which must not be used for BT11 Open Source Development service applications.
Evaluation: The scan tool incorrectly detects the Apache License header as GPL-2.0 license text
Incorrectly detected license “proprietary”
Rule: OCaaS Policy C3 Commercial
Message: License LicenseRef-scancode-proprietary-license found for package ‘Unmanaged::leda-distro-fork:0716b55ff8f57319263d67ee16d90e64588b391d’ is categorized as commercial and requires special handling.
Evaluation: The scan tool incorrectly detects its own configuration file (.ort.original.yml) as being licensed under proprietary licenses.
The following components are not yet released in public or did not yet finished the project review, and may only be added to the release on shorter notice:
(Eclipse Backend-Function-Bindings)
(Eclipse SommR)
(OTA Client)
Compatibility
Compatibility to previous versions is not considered for this first release.
This page introduces the main concepts around Eclipse Leda, Eclipse Kuksa, Eclipse Velocitas, and Eclipse Kanto for
developing and deploying applications for a software defined vehicle (SDV).
The intention is to introduce the main concepts and how these projects interact. When you are already familiar with the general ideas of the Eclipse SDV,
you can also jump to a hands-on tutorial on how to develop a seat adjuster application or
replicate an Eclipse SDV Blueprint for managing vehicle fleets using Eclipse SDV concepts and technologies.
Abstract Architecture
For the software defined vehicle we may assume the following abstract architecture.
The architecture evolves around actuators and sensors in a vehicle, like the state of a passenger seat or a door, which get controlled by connected ECUs.
These ECUs react to and produce signals, which they communicate over automotive communication systems like CAN or SOME/IP.
To establish a more flexible interaction between these ECUs and make the overall vehicle more software-defined, we assume various vehicle applications which
want to interact with the actuators and sensors, e.g., to control a seat based on a saved driver profile.
The architecture contains a vehicle abstraction layer between the ECUs and the vehicle applications.
This abstraction layer introduces a potential control point for security and safety considerations and generally decouples the application logic
from the more deeply embedded soft- and hardware layers.
Vehicle Abstraction Layer
As the name implies the vehicle abstraction layers offers abstract ways to interact with the underlying vehicle.
Vehicle Signal Specification (VSS)
We need a joint data model for the potential signals with which an application can interact. We propose to use the
Vehicle Signal Specification (VSS) from
the Connected Vehicle Systems Alliance (COVESA) for this.
VSS essentially defines a rule set of how to express the definition of signals in a vehicle.
This definition bases a tree structure where each domain, like body control, gets an individual sub-tree.
The authors of VSS further provide a default tree of signals to be expected in a vehicle.
However, it is common practice to tailor the default tree for a specific vehicle model by adding overlays.
VSS allows modeling and structuring of the data from a vehicle but does not define interfaces for the interaction with this data since this depends on the used
communication technology and further circumstances like whether VSS data gets processed inside the vehicle or off-board.
The Eclipse Kuksa.val databroker acts as a vehicle abstraction layer by brokering VSS signals between vehicle applications
and deeply embedded systems in the vehicle. Enabling this abstraction requires a vehicle-specific component to translate between the Kuksa.val databroker and
the underlying transport systems and ECUs.
With Eclipse Kuksa, we refer to these software components as providers and further differentiate between actuation and data providers.
For actuators, the Kuksa.val databroker stores the desired and the current state. Typically, an application would perform a control operation by setting
the target state and monitoring the current state. It is then the task of the actuation provider to perform the action while the data provider updates
the current state according to signals sent on the vehicle bus.
To get notified of any changes, applications, and providers can subscribe to specific signals at the Kuksa.val databroker.
The Kuksa.val databroker is written in Rust and offers communication over gRCP. To make life easier for developers using the Kuksa.val databroker there is a
Python-client which can be integrated in own applications.
When developing with other languages, you may have to generate client code yourself with the gRPC tooling.
Either way, these clients allow the development of vehicle applications and providers.
Vehicle Application Development
When developing an application to interact with the abstraction layer, there are a couple of aspects to cover, which are not specific to a single application.
Because of that, some projects are evolving around the application development phase.
Eclipse Autowrx and digital.auto Playground
A good starting point to figure out what signals are available is the website of the digital.auto playground based on Eclipse Autowrx.
In the next step, you can ideate on new applications, start coding, and get fast feedback using the prototyping feature of the playground.
Once you are confident with the initial version, you can continue the development journey with the help of Eclipse Velocitas,
which comes with several features making the life of vehicle application developers easier.
Eclipse Velocitas
Eclipse Velocitas™ is an open source project providing a development tool chain to create containerized Vehicle Apps, offering a development experience to increase the speed of a development team (velocity).
Among other things, Eclipse Velocitas provides a template repository.
To kick-start the development of a new application, you can create an individual repository from this template.
As an alternative, Eclipse Velocitas provides a CLI application with which you can configure the creation of a tailored vehicle application repository.
Either way, the resulting repository contains skeleton code for the actual application
and comes with pre-defined GitHub Actions workflows to automate
the testing and releasing of applications as containers.
The repository further contains the Dockerfile for a dev container that setups a development and vehicle environment on the developer machine.
It is then possible to interact with this container through VSCode.
Another aspect of Eclipse Velocitas is the so-called vehicle model. Here it becomes possible to take a custom vehicle model expressed in
VSS and generate a tailored SDK with specific domain classes to interact
with a Kuksa.val databroker using the same model.
This way, we can directly develop against the used vehicle model.
commit and push vehicle applications to trigger tests in GitHub Actions workflows
trigger release workflow in GitHub
As a result of the Release workflow, the generated repository contains a Container image with the vehicle application.
A target device, e.g., a vehicle or test device, can pull and execute this container.
Vehicle Providers and Emulation
The underlying assumption when developing a vehicle application against the vehicle abstraction layer is that components below the abstraction fulfill
the requests coming from the application. In other words: Developers have to assume that there are providers for the signals with which their application interacts.
For a production-ready vehicle, this should be the case. But during development and testing the creation of such providers adds overhead and
is a potential cause for further errors. An alternative is to use pre-developed services or
even a generalized vehicle mock service which acts as such a provider.
Developers can alter the vehicle mock service by defining the desired behavior through a Python-based DSL.
Vehicle Application Runtime
The next step is to bring the application to the target device and the vehicle. There are various options for how to run and orchestrate vehicle application containers.
Some originate from general IT scenarios like Kubernetes or Docker Compose, and others focus more on automotive and IoT-use cases like Eclipse Kanto.
So a vehicle application developer now faces the challenge of picking a runtime and integrating this runtime with required infrastructure components like
the Kuksa.val databroker or respective Kuksa.val providers to enable the vehicle application.
Eclipse Leda
Among other things, Eclipse Leda already provides such a target platform through a Linux-based distribution of pre-integrated Eclipse SDV components.
See the architecture page for more details on the elements in Eclipse Leda.
For the container execution, Eclipse Leda utilizes Eclipse Kanto, which implements lightweight management of OCI-compliant containers and comes by default with containerd.
It is possible to manage the containers either through a CLI or by writing container manifest files and placing them in a dedicated folder on the file system
from where Eclipse Kanto automatically performs them.
Service Exchange
Another challenge when deploying multiple components that need to collaborate as services is how they find and communicate with each other.
In Eclipse Kanto, the discovery and exchange can happen over container indetifiers or topics on a local MQTT broker.
The Eclipse SDV community already came up with other approaches for the service exchange topic like Eclipse uProtocol,
Eclipse Chariott or Eclipse Zenoh.
Seat Adjuster
To see the explained concepts in action, it is best to build your own application. The Seat Adjuster
is good starting point with specific examples.
Note: There are no official releases yet.
The artifacts available on the Release page are for testing the build and release workflows.
They should be considered as unstable nightly builds from the main branch.
Releases marked -M1, -M2, -RC1 etc. are preparations for official releases according to the Eclipse Release process.
Go to the Eclipse Leda Releases page and download the release archive for the respective machine.
The release archives container the disk image and the respective Linux kernel:
Machine
Filename
Description
QEMU x86_64
eclipse-leda-qemu-x86_64.tar.xz
For running QEMU x86 64-Bit
QEMU ARM 64
eclipse-leda-qemu-arm64.tar.xz
For running QEMU ARM 64-Bit
Raspberry Pi 4
eclipse-leda-raspberrypi.tar.xz
For running on Raspberry Pi 4 (SD-Card Image)
Using GitHub CLI tool
To download all files of the latest release using the GitHub CLI:
By using the dockerized Leda quickstart images, the SDV vehicle edge components can be evaluated on emulated X86-64 and ARM64 system images,
without having to install QEMU and dependencies manually.
If you want to execute the image without Docker, please see Running on QEMU.
This allows to tweak the startup script, modify the emulated hardware device and set up advanced network configurations.
There are two options to run Leda:
Docker: Simple, restricted to one container
Docker Compose: Advanced, allows networking between containers
Recommendations
A Linux host with 4 vCPUs, 8GB of RAM and SSD storage is recommended
Docker
Docker
The easiest way is to run a single instance of Leda in a Docker container:
Run the Leda Docker quickstart image:
docker run -it ghcr.io/eclipse-leda/leda-distro/leda-quickstart-x86
Login with root
Stop the Docker container
shutdown now
Note: If you need to stop the container from outside, use the docker stop <id> command from a separate terminal.
Privileged Containers
When run as a privileged container, QEMU will try to set up a TAP network and use KVM acceleration.
Network and CPU will be faster, depending on the host system.
To be able to use these host devices, QEMU needs access to the following devices:
/dev/kvm
/dev/net/tun
Example command:
docker run -it --privileged --device=/dev/kvm:/dev/kvm --device=/dev/net/tun:/dev/net/tun ghcr.io/eclipse-leda/leda-distro/leda-quickstart-x86
Exposing additional ports
To also expose ports to connect to ssh, mqtt or the Kuksa databroker, add the port mappings to the Docker command:
The following ports are specifically of interest and exposed by the docker container:
2222 for SSH (mapped internally to 22)
1880 - free slot reserved for user service
1883 for MQTT
8888 - free slot reserved for user service
30555 for Kuksa Databroker
Note: In unprivileged mode, only these ports are mapped by the Docker container and forwarded to the Leda system.
In privileged mode, all TCP ports can be exposed, which will then be forwarded from the Docker container into the Leda system.
See the
entrypoint script
for details.
Running ARM-64 version
To run the ARM-64 bit version of the image, use the leda-quickstart-arm64 container image:
docker run -it ghcr.io/eclipse-leda/leda-distro/leda-quickstart-arm64:latest
Docker Compose
A more convenient way to setup advanced scenarios is to use Docker Compose.
There is a Docker Compose configuration for an Eclipse Leda setup in resources/docker-compose.
As the networking is a bit more complicated to set up with emulated network inside of QEMU, the following explanation is helpful to understand networking better.
All docker compose containers are attached to a network called leda-bridge and leda-network and can see each other
The QEMU instances use a TAP network inside of each leda-quickstart-xxx container and do a NAT network translation to their own container
The Docker internal DNS server is being used. This is implemented by a DNS Proxy container,
which will forward incoming DNS requests to the Docker DNS running on the 127.0.0.x network.
In unprivileged mode: Only the exposed ports are forwarded from the docker container into the QEMU process:
mosquitto 1883, ssh 2222 and kuksa.val databroker 30555.
In privileged mode, all TCP ports are forwarded from the Docker container into the QEMU process and the special port 2222 is forwarded to ssh port.
Developer Shell
Developer Shell:
docker compose run --rm devshell
From there, you can log in to either Leda on QEMU x86-64, or log in to Leda on QEMU ARM-64.
ssh leda-x86
ssh leda-arm64
To run an additional terminal in the developer shell, execute this:
docker compose exec devshell /bin/bash
Interacting with Eclipse Leda
Check the general system status
sdv-health
Device Provisioning
Run the provisioning script:
sdv-provision
Copy the fingerprints
Go to Azure IoT Hub, create a new device
Use the certificate’s common name (CN) as Device Id - on Leda, this defaults to a part of the MAC Address
Select X.509 Self-Signed authentication type and enter both fingerprints
Click Save
MQTT Broker Bridge
graph LR;
A["MQTT Container on docker host localhost:1883"] -- Bridge --> B[leda-x86:31883];
A -- Bridge --> C[leda-arm64:31883];
B-->B1[mosquitto service leda-x86:1883];
C-->C1[mosquitto service leda-arm64:1883];
The Docker Compose setup will also start an Eclipse Mosquitto message broker as a bridge to both Leda instances.
This allows a user or developer to monitor messages sent by or received by both virtual devices.
Connect your MQTT client to mqtt-broker.leda-network by using the exposed port 1883 on the host:
mosquitto_sub -h localhost -p 1883 -t '#' -v
Docker Networking
You need to enable IP forwarding from Docker containers to make networking work.
The containers (leda-arm64, leda-x86) need to run with --privileged as they change iptables rules for proper forwarding of network packets.
Each Eclipse Leda instance (ARM64, x86_64) is running within a QEMU emulated network (192.168.7.2), which itself is contained
in a containerized network called leda-network (192.168.8.x).
The containers wrapping the QEMU instances will forward the following ports to the respective QEMU process:
SSH on port 2222
Mosquitto on port 1883
DHCP and DNS setup
Each Leda-QEMU container is running a local DHCP on the tap0 network interface and listens for DHCP requests by the Leda Distro running inside of QEMU.
The DHCP server will respond with the same IP address (192.168.7.2) to the request from QEMU.
The DHCP response contains a DNS nameserver pointing to the dns-proxy.leda-network (192.168.8.14) IP,
which in turn forwards to Docker’s internal 127.0.0.11 nameserver.
This allows the QEMU guests to resolve Docker Compose Services by their service name, e.g. leda-bundle-server.leda-network.
Volumes
The /root path inside of the Leda containers is mounted as a volume and contains the raw disk image and runner scripts for the QEMU Leda distribution.
Changes on the QEMU filesystem are made persistent on a copy of the QCOW2 disk image, so that restarting the device will keep any changes.
To reset to the original state, delete the respective docker volumes and restart the containers:
Profiles can be used to determine which containers (services) docker compose should be starting by default.
This is mostly used to have the devshell container not start up by default.
tools: Contains docker containers which are not essential at runtime, must useful for testing and development purposes
2.4 - Running on Raspberry Pi
What you need:
A Raspberry Pi 4B (64 Bit) with 2 GiB of RAM or more, recommended is 8 GiB
Network connection (Ethernet or Wifi) with transparent internet access
Optional keyboard and display (makes it easier to troubleshoot)
Optional: If you need to adapt the network configuration eg Wifi credentials, edit the configuration files on the boot partition.
Shutdown the Raspberry and insert the SD-Card into the Raspberry Pi SD-Card slot at the bottom
Power on your Raspberry to boot the image
Login with root
Check disk space:
The raspberry-growdisk system service will do this automatically on first boot.
To manually enlarge the available disk space on the SD-Card, resize the disk partition: parted /dev/mmcblk0 resizepart 6 100% && resize2fs /dev/mmcblk0p6.
Note: Due to changes in the disk partition, the partition number (6 in the example) may have changed.
Verify with df -h.
Verify and wait until container runtime is started: systemctl status container-management
The Eclipse Leda quickstart image has CAN-Bus kernel modules and some CAN hardware drivers pre-installed.
However, some hardware configuration needs to be adapted at boot time depending on the specific CAN-Extension being attached to the device.
On Raspberry Pi, there is a /boot/config.txt file where you can configure the dtoverlay options accordingly.
Note: After modification, the device requires rebooting for the changes to take effect.
Verify and wait until container runtime is started: systemctl status container-management
Optional: Check the system health: sdv-health
Note: The status of some containers (e.g. cloud connector) are expected to stay in FAILED status as long as the Device Provisioning steps are not completed.
Verify and wait until container runtime is started: systemctl status container-management
Optional: Check the system health: sdv-health
Note: The status of some containers (e.g. cloud connector) are expected to stay in FAILED status as long as the Device Provisioning steps are not completed.
ip link add dev vcan0 type vcan
ip link set vcan0 up
Enabling CAN Bus interfaces (can)
Standalone CAN within Qemu
To run a standalone CAN setup, qemu must be instructed to emulate a specific CAN hardware device. We will be using the kvaser_pci device in this example:
After the image has booted, load the Linux Kernel Module kvaser_pci device driver and configure the CAN-Bus device (eg bitrate) before bringing the interface up:
root@qemux86-64:~# modprobe kvaser_pci
root@qemux86-64:~# dmesg | grep kvaser
[ 9.565149] kvaser_pci 0000:00:04.0: initializing device 10e8:8406
[ 9.569308] kvaser_pci 0000:00:04.0: reg_base=00000000d5a68095 conf_addr=000000002b3c7ef6 irq=20
[ 9.596942] kvaser_pci 0000:00:04.0: xilinx version=13 number of channels=0
root@qemux86-64:~# ip link show type can
4: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10
link/can
Configure the interface:
root@qemux86-64:~# ip link set can0 type can bitrate 1000000
[ 165.519919] kvaser_pci 0000:00:04.0 can0: setting BTR0=0x00 BTR1=0x14
root@qemux86-64:~# ip link set can0 up
[ 186.906065] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
root@qemux86-64:~# ip link show type can
4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can
# ip link show type can
3: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT roup default qlen 10
Continue with configuring the CAN chip and bring up the SocketCAN network interface:
# ip link set can0 type can bitrate 1000000
# ip link set can0 up
# ip link show type can
Linux Kernel Modules
The following Linux Kernel modules are available on the quickstart images:
Note: For QEMU, only kvaser_pci is used
Leda main Kernel
peak_pciefd - Socket-CAN driver for PEAK PCAN PCIe/M.2 FD family cards
m_can - CAN bus driver for Bosch M_CAN controller
m_can_pci - CAN bus driver for Bosch M_CAN controller on PCI bus
m_can_platform - M_CAN driver for IO Mapped Bosch controllers
softing - Softing DPRAM CAN driver
cc770_platform - Socket-CAN driver for CC770 on the platform bus
cc770_isa - Socket-CAN driver for CC770 on the ISA bus
cc770 - cc770CAN netdevice driver
ifi_canfd - CAN bus driver for IFI CANFD controller
kvaser_usb - CAN driver for Kvaser CAN/USB devices
etas_es58x - Socket CAN driver for ETAS ES58X USB adapters
ucan - Driver for Theobroma Systems UCAN devices
peak_usb - CAN driver for PEAK-System USB adapters
kvaser_pciefd - CAN driver for Kvaser CAN/PCIe devices
kvaser_pci - Socket-CAN driver for KVASER PCAN PCI cards
f81601 - Fintek F81601 PCIE to 2 CANBUS adaptor driver
sja1000_isa - Socket-CAN driver for SJA1000 on the ISA bus
plx_pci - Socket-CAN driver for PLX90xx PCI-bridge cards with the SJA1000 chips
sja1000 - sja1000CAN netdevice driver
ems_pci - Socket-CAN driver for EMS CPC-PCI/PCIe/104P CAN cards
peak_pci - Socket-CAN driver for PEAK PCAN PCI family cards
sja1000_platform - Socket-CAN driver for SJA1000 on the platform bus
vxcan - Virtual CAN Tunnel
c_can_platform - Platform CAN bus driver for Bosch C_CAN controller
c_can - CAN bus driver for Bosch C_CAN controller
c_can_pci - PCI CAN bus driver for Bosch C_CAN/D_CAN controller
slcan - serial line CAN interface
can_dev - CAN device driver interface
vcan - virtual CAN interface
can-isotop - PF_CAN isotp 15765-2:2016 protocol
can-gw - PF_CAN netlink gateway
can-j1939 - PF_CAN SAE J1939
can-raw - PF_CAN raw protocol
can-bcm - PF_CAN broadcast manager protocol
can - Controller Area Network PF_CAN core
Raspberry Pi
The following Linux Kernel modules are available on the quickstart image for Raspberry Pi:
can - Controller Area Network PF_CAN core
vxcan - Virtual CAN Tunnel
can-dev - CAN device driver interface
can-bcm - PF_CAN broadcast manager protocol
can-gw - PF_CAN netlink gateway
can-raw - PF_CAN raw protocol
can-isotop - PF_CAN isotp 15765-2:2016 protocol
can-j1939 - PF_CAN SAE J1939
vcan - virtual CAN interface
slcan - serial line CAN interface
mcp251x - Microchip 251x/25625 CAN driver
mcp251xfd - Microchip 251xFD Family CAN controller driver
ems_usb - CAN driver for EMS Dr. Thomas Wuensche CAN/USB interfaces
gs_usb - Socket CAN device driver for Geschwister Schneider UG
peak_usb - CAN driver for PEAK-System USB adapters
2.5.2 - Transferring Files
Sharing a directory with the guest
When you want to copy files between the host and the guest, an easy way is to use an SFTP tunnel.
With sshfs, you can mount a local directory to a remote directory via SSH.
Pre-Requisites
Installation of needed packages:
Run apt-get install sshfs on your host
Enable CORE_IMAGE_EXTRA_INSTALL += " openssh-sftp-server" in local.conf of your image (e.g. in the local_conf_header section in your kas file)
Verify SFTP connection working with sftp -P 2222 root@localhost
Transfering files from host to guest
When you want to copy files from the host to the guest, an easy way is to use an SFTP tunnel.
With sshfs, you can mount a local directory to a remote directory via SSH.
Create a mount point on your host: mkdir remote
Open the SSH Filesystem tunnel: sshfs root@localhost:/ remote/ -p 2222
Check files: ls -al remote/ - you should see the root filesystem of the device now
You can now easily copy files: cp foo.txt remote/home/root/
Transfering files from guest to host
Note: The reverse direction, e.g. initiating an SSH tunnel from within the device to the host, is currently not supported by the installed software on the image.
2.6 - Running on Linux
To run the main components of the SDV EDGE stack on an existing Linux distribution (e.g. Debian, Ubuntu, Raspberry Pi OS),
you need to install the following packages.
Please note that since this is not a full-system installation, but an additional installation, there are some differences
compared to the usual Leda installation on Docker/QEMU/Devices using our Quickstart image:
The Self-Update use case is not used, as the distribution-specific channels apply.
E.g. it does not make sense to use the Leda infrastructure to flash a full system image.
The configuration differs slightly and you need to put some more work into getting the examples to work out of the box.
This may include different port numbers, different paths of volume mounts for containers etc.
Debian-based Linux distributions
Tested on x86_64 via Docker:
Debian 11
Debian 12
Ubuntu 20.04
Ubuntu 22.04
Ubuntu 23.10
Note: Ubuntu 18.04 is not supported, as the glibc is outdated.
Pre-Requisuites
The SDV stack requires the following packages to be present on the target system:
Mosquitto (adapt configuration, see below)
Data folders
Storage for Self Update Bundles: mkdir -p /data/selfupdates
Download the Debian package from the Eclipse Kanto release page
wget "https://github.com/eclipse-kanto/kanto/releases/download/v0.1.0-M3/kanto_0.1.0-M3_linux_x86_64.deb"apt-get install -y ./kanto_0.1.0-M3_linux_x86_64.deb
# Check if Kanto has been installedcommand -v container-management
command -v kanto-cm
systemctl status container-management
Mosquitto must be configured to allow anonymous access and listen on the network interface available to the containers. The easiest (and least secure!) configuration would be:
/etc/mosquitto/conf.d/public.conf:
listener 1883 0.0.0.0
allow_anonymous true
Attention: Only apply this configuration on a device in a secured network, or adapt the configuration accordingly (e.g. specify internal IP address)
2.7 - Cheatsheet
This cheat sheet gives you an overview of common command line commands to interact with the tools available on the quickstart image.
General Commands
Category
Task
Command
General
Overall info
sdv-health
Show device info
sdv-device-info
Device provisioning
sdv-provision
Switch Keyboard layout
loadkeys de
System
System load
htop
Disk free
df -h -t ext4
Memory free
free -h
Network
Interfaces summary
networkctl
Ethernet status
networkctl status enp0s2
Routing table
route
Active listeners
netstat -l -n -t
Multicast for Some/IP
route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0
A failed download of container images may be caused by out-of-sync clock, thus failing the TLS certificate validation.
A hardware device without hardware clock (such as the Raspberry Pi) relies on network time.
In some (corporate) networks, there might be rogue NTP servers and it might be necessary to override the NTP sources.
To reset NTP server to a public server, follow these steps:
When things go really wrong and the container runtime is unable deploy containers properly, it may be necessary to reset the internal state.
This is achieved by stopping the container runtime(s) and deleting the /var/lib/container-management folder:
# Stop all container runtimessystemctl stop container-management
systemctl stop containerd
# Delete the persistence of container management# Attention! Here be dragonsrm -rf /var/lib/container-management
# Restart the container runtimessystemctl start containerd
systemctl start container-management
# Redeploy the containerssystemctl restart kanto-auto-deployer
Running custom ad-hoc containers
To install arbitrary containers, create the container using the kanto-cm command line tool.
If it’s not a background service, but a cli tool, adding the --t --i options allows console access.
root@qemux86-64:~# kanto-cm remove --name python
root@qemux86-64:~# kanto-cm create --name python --t --i --privileged docker.io/library/python:3.8.16-slim-bullseye
bf9deca4-dbf1-4132-9ba7-e0f378bd34a7
root@qemux86-64:~# kanto-cm start --name python --a --i
Python 3.8.16 (default, Jan 24 2023, 00:19:05)[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license"for more information.
>>> quit()
Raspberry Pi Overlays
Edit /boot/config.txt and reboot:
# Disable to fix non-working standard Raspberry Pi 7" display
# dtoverlay=vc4-kms-v3d
# PiCAN 2
# dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
# Waveshare RS485 CAN Hat
# dtoverlay=mcp2515-can0,oscillator=12000000,interrupt=25,spimaxfrequency=2000000
2.8 - Utilities
The quickstart image contains the following utilities.
These utility scripts are meant to be convenience tools for users and developers.
They help to experiment with the container deployment, device provisioning or vehicle data access.
sdv-health: Show SDV software components health status
kantui: A text user interface for kanto-cm to manage containers (start, stop, logs, redeploy all)
sdv-device-info: Show and update device information
sdv-provision: Generate device certificates and configuration of cloud connection
sdv-motd: Message-of-the-Day shown after login prompt
can-forward: Forwarding a CAN-bus network interface into a containerized Vehicle Application
kanto-auto-deployer: Automatically deploys containers on boot. Runs as a systemd service, and can also be invoked by a user directly.
sdv-ctr-exec: Execute arbitrary commands in existing containers
sdv-kanto-ctl: Manage the Kanto Container Management configuration via CLI
blueprint-selector: Deploy and fetch new SDV blueprints easily with an interactive CLI
Note:
These scripts are not meant to be reused or called from production software.
Their behaviour or command line syntax is not a stable API and should not be trusted for automation purposes.
For details, please see leda-utils
2.8.1 - SDV Health
Health check
The sdv-health utility displays a status overview of some important dependencies and device configurations for the SDV edge stack.
The sdv health utility can be configured using the sdv.conf configuration file.
Usage:
# sdv-health
Example output:
Version Information
The Leda image version and build time will be displayed at the top in the first category:
OS Release: Year and codename of the release version
Image Version: Name of the image and more specific version information, such as the git tag or commit id
Build timestamp in yyyMMddHHmmss notation
Note: The information is read from the system base file in /etc/os-release:
If available, vehicle bus network information, such as the status of the CAN-Bus, will be displayed iin its own category.
This helps to quickly identify if there problems with the hardware connectivity for automotive bus networks.
Ports
The health utility checks the TCP ports of specific services.
This helps to identify if these services are up and running and potentiallyconnectable via external network interfaces.
Services and Containers
The services category shows the status of required and optional containers.
The required containers are supposed to be up and running for the SDV.EDGE stack to be correctly up and running.
If any of these core components have a failed state, the functionality is impacted.
The optional containers are for additional features and for example applications.
These containers may not be necessary for each use case and hence will be marked as a warning if they are not up and running.
The overview still helps to identify which containers are working properly.
Errors, Warnings, Failed states
When there are errors or warnings related to the status of SDV related components,
the health utility will print out these error states, and if available also a more detailed error message.
In the following example, the health utility helps the troubleshooting process:
The container runtime is properly started: “Kanto CM” is OK in the “SDV Ports” section and the “container-management” service is OK in the “SDV Services” section".
Some containers are in state “OK”, which means there is no general issue with the container runtime.
The cloud connector is in a “Stopped” state, which indicates that the user manually stopped the container by using “kanto-cm stop -n cloud-connector”.
The sua container is in a “Exited” state, which indicates the process exited with an error code.
2.8.2 - KantUI
The KantoUI tool is a text-based user interface for conveniently managing containers in the Kanto Container Management.
It supports simple navigation using keyboard and mouse to select a specific container.
Commands to start, stop, remove and re-deploy containers are available along with a functionality to retrieve the application logs of a selected container.
Kanto User Interface
Usage:
kantui
Example output:
Command Line Options
Print command line help:
root@qemux86-64:~# kantui --help
kantui 0.2.0
A TUI for Kanto CM that allows easier management of deployed containers. Requires root.
USAGE:
kantui [OPTIONS]OPTIONS:
-c, --config-file-path <CONFIG_FILE_PATH>
Set a custom path for the kantui configuration file [default:
/etc/kantui/kantui_conf.toml] -h, --help
Print help information
-V, --version
Print version information
Note: All config values can be overridden through env variables prefixed with KANTUI_,
e.g. KANTUI_STOP_TIMEOUT=5 overrides the timeout before SIGKILL is sent to be 5 seconds.
Keyboard commands
Arrow keys Up and Down to select a container
Arrow keys Left and Right to select a column
Enter to change the sort ordering of the currently selected column
S to start the selected container which is currently not running
P to stop the selected container
R to remove a container
L to show the log output of a container
D to redeploy an existing container (rereads deployment descriptor)
Q to quit kantui
Note: The mouse can be used to select ui items when holding the Shift key.
Starting, Stopping, Removing containers
To use the lifecycle commands on a container:
Select a container by using the mouse or the arrow keys.
The selected container is highlighted.
Press one of the lifecycle commands, e.g. s, p or r
Wait for the value in the State column to change, before issueing the next command.
Note: When using the lifecycle commands for containers (Start, Stop, Remove), it may take a few seconds before the UI is updated with the status changes.
The amount of time before a container is forcefully killed is determined by the stop_timeout configuration option.
Show container Logs
To view the container’s log output:
Select a container by using the mouse or the arrow keys.
Press the L key
Log output will be displayed (tail, oldest messages first)
Use the arrow keys Up and Down or drag the scrollbar using your mouse to scroll through the log
Close the Log viewer by pressing Enter or clicking on the OK button
Note: The log output is not followed automatically. Close the dialog and reopen to see new output.
Redeploying containers
To redeploy a container, e.g. when a deployment descriptor has changed on disk:
Select a container by using the mouse or the arrow keys.
Press the P key to stop the container
Press the R key to remove the container
Press the D key to invoke the Kanto Auto Deployer, which will redeploy the missing containers
Note: Only containers managed by Kanto Auto Deployer will be redeployed.
Column Sorting
To sort a column:
Select the column using the Left and Right arrow keys
Press Enter to activate sorting
Press Enter again on a sorted column to invert sort order (Ascending -> Descending -> Ascending)
Note: The selected sort order is not persisted and will reset to the default on restart: By ID, ascending
Configuration File
The default location of the configuration file is /etc/kantui/kantui_conf.toml:
# General Configuration Optionssocket_path="/run/container-management/container-management.sock"# Path to kanto-cm unix socketstop_timeout=5# timeout (integer) in seconds before a SIGKILL is sent after a SIGTERM[keyconfig]start_btn_name="[S]tart"start_kbd_key="s"stop_btn_name="Sto[P]"stop_kbd_key="p"remove_btn_name="[R]emove"remove_kbd_key="r"logs_btn_name="[L]ogs"logs_kbd_key="l"quit_btn_name="[Q]uit"quit_kbd_key="q"redeploy_btn_name="Re[D]eploy"redeploy_kbd_key="d"# Includes a shell lexer so anything that would be a valid shell command can be used# No pipes/redirects allowed.# N.B.: Command inherits kantui's privileges (root)redeploy_command="systemctl restart kanto-auto-deployer.service"
2.8.3 - SDV Device Info
Displays the current device configuration, such as Device ID.
Note: Requires the Cloud Connector component to be configured and running.
Usage:
sdv-device-info
Usage
Synposis: ./sdv-device-info [options] [command]
Full help:
root@qemux86-64:~# sdv-device-info --help
sdv-device-info v0.2
Usage: /usr/bin/sdv-device-info [options][command]Show SDV device configuration information
Example: /usr/bin/sdv-device-info show
Commands:
show : Display configuration (default command)help : This message
env : Format output for use in scripts
Options:
--ansi | -a : Don't use colored output.
--norestart | -n : Do not automatically restart services
--verbose | -v : Enable verbose mode.
--help | -h : This message.
Use in scripts
To use device information on other scripts, it may be useful to source the device information variables into the current environment variable context:
The provisioning helper script can be used to manually perform a device provisioning with a cloud backend.
It is meant as a convenient tool for developers, who wish to connect their device to a selfmanaged cloud backend directly.
In a production environment, the device provisioning functionality is implemented either by the Cloud Connector component.
The provisioning script currently supports the following backend and authentication options:
Azure IoT Hub
Connection String
Device Certificates
Azure IoT Device Provisioning Service
Device Certificates
Usage
The sdv-provision script is interactive and asks for the type of backend and authentication option:
root@qemux86-64:~# sdv-provision
Checking Eclipse Leda Device Provisioning configuration...
- Certificates directory exists
Checking Device ID
- Based on network device: eth0
- Device ID: 52-54-21-4c-f9-5a
Checking whether either IdScope or ConnectionString is configured
- Neither Id Scope file nor ConnectionString found, needs manual configuration
Do you want to use the global Azure IoT Device Provisioning Service (DPS) by using an Id Scope, or do you want to use a direct connection to a specific Azure IoT Hub using a Connection String?
d) Azure IoT Device Provisioning Service (DPS) with Id Scope
h) Azure IoT Hub with Connection String
Choose:d
Please enter your Id Scope of the Azure IoT Device Provisioning Service:example
Recreating the Cloud Connector container...
Checking device certificates
- All device certificates are present
- Primary device certificate: /data/var/certificates/device.crt
- Primary device private key: /data/var/certificates/device.key
- Secondary device certificate: /data/var/certificates/device2.crt
- Secondary device private key: /data/var/certificates/device2.key
Fingerprints (add these to the Azure IoT Hub Device)- Primary thumbprint: 1B172ED3D06F4E25AFFEF675ADCE519457FFFFFF
- Secondary thumbprint: B6CD5EACE96E9D0448BCB0BAED2DEE87AFFFFFFF
Once a configuration has been selected, the script will:
Generate a random Device Id (based on physical network address)
Store the Device Id in /etc/deviceid
Generate a primary self-signed device certificate pair
Generate a secondary self-signed device certificate pair
Store the certificates in /data/var/certificates/
Reconfigure the container descriptor in /data/var/containers/manifests_dev/cloudconnector.json
Restarting the Cloud Connector container
Print the key fingerprints, used for onboarding the device in Azure IoT Device Provisioning Service
Reconfiguration
Note: Re-running the script will only print the existing configuration.
To reconfigure the device and use different options, perform the following steps:
The sdv-motd script provides an alternative motd profile, which displays some additional information after login.
The script does not have any command line options.
Example output:
2.8.6 - CAN Forward
The can-forward help script can be used to forward an existing CAN-Bus interface on the host system to a container process.
Note: Warning! The script does not yet support Kanto (or containerd) as a container runtime. It has been implemented for k3s.
Usage
root@qemux86-64:~# can-forward --help
Usage: /usr/bin/can-forward {-h}{-p PID}{-c container} <hw_can>
hw_can Host CAN hw interface to forward. Default: can0
-c container Attemmpt to get netns PID from a running container: (docker, ctr). Default: seat_service
-p PID Use provided PID for transferring vxcan interface (e.g.: docker inspect -f '{{ .State.Pid }}' container) -h Prints this message
The script performs the following steps:
Find the process ID of the target container process
Check and modprobe vxcan
Check and modprobe can-gw
Create a new virtual CAN interface (vxcanX)
Create a new virtual CAN interface (vxcanX+1)
Link both interfaces together
Move the second interface (vxcanX+1) into the namespace of the target container
Set up a bi-directional CAN-Bus packet forwarding between both interfaces using cangw
2.8.7 - Kanto Auto Deployer (KAD)
Automatically deploys containers to the Kanto Container Management based on deployment descriptors from a given path.
All deployment descriptors in the manifests folder will be deployed (created and started) on startup of the service.
The directory will then be monitored for creation of/changes to manifests and those changes will be redeployed.
Usage
Usage:
$ kanto-auto-deployer --help
kanto-auto-deployer 0.2.0
Automated deployment of Kanto Container Management Manifests
USAGE:
kanto-auto-deployer [OPTIONS][MANIFESTS_PATH]ARGS:
<MANIFESTS_PATH> Set the path to the directory containing the manifests [default: .]OPTIONS:
-d, --daemon Run as a daemon that continuously monitors the provided path for changes
-h, --help Print help information
-s, --socket-cm <SOCKET_CM> Set the path to the Kanto Container Management API socket
[default: /run/container-management/container-management.sock] -V, --version Print version information
Example:
# Use container manifests from current working directoryroot@qemux86-64:/data/var/containers/manifests# kanto-auto-deployer
[2023-04-18T10:27:21Z INFO kanto_auto_deployer] Running initial deployment of "/data/var/containers/manifests"[2023-04-18T10:27:21Z INFO kanto_auto_deployer] Reading manifests from [/data/var/containers/manifests][2023-04-18T10:27:21Z WARN kanto_auto_deployer::manifest_parser] Failed to load manifest directly. Will attempt auto-conversion from init-dir format.
[2023-04-18T10:27:21Z INFO kanto_auto_deployer] Already exists [cloudconnector][2023-04-18T10:27:21Z WARN kanto_auto_deployer::manifest_parser] Failed to load manifest directly. Will attempt auto-conversion from init-dir format.
[2023-04-18T10:27:21Z INFO kanto_auto_deployer] Already exists [databroker]# Use container manifests from specified directoryroot@qemux86-64:~# kanto-auto-deployer /data/var/containers/manifests/
[2023-04-18T10:27:44Z INFO kanto_auto_deployer] Running initial deployment of "/data/var/containers/manifests"[2023-04-18T10:27:44Z INFO kanto_auto_deployer] Reading manifests from [/data/var/containers/manifests][2023-04-18T10:27:44Z WARN kanto_auto_deployer::manifest_parser] Failed to load manifest directly. Will attempt auto-conversion from init-dir format.
[2023-04-18T10:27:44Z INFO kanto_auto_deployer] Already exists [cloudconnector][2023-04-18T10:27:44Z WARN kanto_auto_deployer::manifest_parser] Failed to load manifest directly. Will attempt auto-conversion from init-dir format.
[2023-04-18T10:27:44Z INFO kanto_auto_deployer] Already exists [databroker]
root@qemux86-64:/lib/systemd/system# systemctl status kanto-auto-deployer.service
* kanto-auto-deployer.service - Kanto Auto Deployer
Loaded: loaded (/lib/systemd/system/kanto-auto-deployer.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2023-04-18 10:22:10 UTC; 3min 55s ago
Main PID: 525(kanto-auto-depl) Tasks: 10(limit: 4708) Memory: 1.4M
CGroup: /system.slice/kanto-auto-deployer.service
`- 525 /usr/bin/kanto-auto-deployer /data/var/containers/manifests --daemon
Apr 18 10:22:48 qemux86-64 kanto-auto-deployer[525]: [2023-04-18T10:22:48Z INFO kanto_auto_deployer] Creating [sua]Apr 18 10:23:04 qemux86-64 kanto-auto-deployer[525]: [2023-04-18T10:23:04Z INFO kanto_auto_deployer] Created [sua]Apr 18 10:23:04 qemux86-64 kanto-auto-deployer[525]: [2023-04-18T10:23:04Z INFO kanto_auto_deployer] Starting [sua]Apr 18 10:23:05 qemux86-64 kanto-auto-deployer[525]: [2023-04-18T10:23:05Z INFO kanto_auto_deployer] Started [sua]Apr 18 10:23:05 qemux86-64 kanto-auto-deployer[525]: [2023-04-18T10:23:05Z WARN kanto_auto_deployer::manifest_parser] Failed to load manifest directly. Will attempt auto-conversion from init-dir format.
Apr 18 10:23:05 qemux86-64 kanto-auto-deployer[525]: [2023-04-18T10:23:05Z INFO kanto_auto_deployer] Creating [vum]Apr 18 10:23:10 qemux86-64 kanto-auto-deployer[525]: [2023-04-18T10:23:10Z INFO kanto_auto_deployer] Created [vum]Apr 18 10:23:10 qemux86-64 kanto-auto-deployer[525]: [2023-04-18T10:23:10Z INFO kanto_auto_deployer] Starting [vum]Apr 18 10:23:11 qemux86-64 kanto-auto-deployer[525]: [2023-04-18T10:23:11Z INFO kanto_auto_deployer] Started [vum]Apr 18 10:23:11 qemux86-64 kanto-auto-deployer[525]: [2023-04-18T10:23:11Z INFO kanto_auto_deployer] Running in daemon mode. Continuously monitoring "/data/var/containers/manifests"
2.8.8 - SDV Container Exec
The sdv-ctr-exec wrapper allows to execute arbitrary user commands in existing containers.
Kanto Container Management cli tool (kanto-cm) only allows to manage the lifecycle of a container,
but does not allow to specify or override the entrypoint or command definitions of an existing container.
The ctr command line tool of containerd allows the execution of additional tasks in a running container.
Usage
As a convenient tool, sdv-ctr-exec allows the simple execution of arbitrary commands inside of containers.
This is especially useful for non-service-containers, or containers which have additional binaries (e.g. cli tools) embedded.
Usage:
root@qemux86-64:~# sdv-ctr-exec
/usr/bin/sdv-ctr-exec -h to print this message
Usage:
/usr/bin/sdv-ctr-exec <container-id> <command>
or
/usr/bin/sdv-ctr-exec -n <container-name> <command>
Note: nerdctl is currently not installed on the Leda Quickstart images.
containerd: ctr and mounting
To execute a binary natively (outside of a containerized environment), the container image may be mounted to the host filesystem using the ctr snapshots mount commands.
This approach only works if the binary is compatible with the host environment (dependencies, libraries etc.).
Manage the Kanto Container Management configuration via CLI.
Note: Requiresjq to be installed.
Features:
Add and remove container registries (for authentication purposes)
Set primitive values in configuration
Restart container-management.service on configuration changes
Automatically back up configuration file
Display changes to user
Usage
Synposis: ./sdv-kanto-ctl <command> [<options>]
Full help:
$ ./sdv-kanto-ctl --help
Eclipse Kanto Container Manager Configuration Utility
See https://eclipse.dev/kanto/docs/references/containers/container-manager-config/
Usage: ./sdv-kanto-ctl <command> {options}Commands:
add-registry -h <hostname> -u <username> -p <password>
Adds or replaces a container registry authentication configuration
-h or --hostname: Configure the hostname of the container registry (e.g. hub.docker.io, ghcr.io, ...) -u or --username: Configure the username
-p or --password: Configure the password
remove-registry -h <hostname>
Removes the specified container registry
-h or --hostname: The hostname of the container registry
remove-all-registries
Removes all configured container registries
list-registries
Prints all configured container registries
show-config
Print the container management configuration
set <key> <value>
Set a primitive configuration value. Key in JSON Dot-Notation
Examples: ./sdv-kanto-ctl set containers.registry_configurations.MyRegistry.credentials.password foobar
./sdv-kanto-ctl set things.enable trueOptions:
--no-reload : Do not reload the configuration and restart the container-management service automatically
--ansi : Don't use colored output.
--verbose | -v : Enable verbose mode.
--help : This message.
Example: Private Container Registries
To be able to pull container images, the container runtime needs access to the container registry.
Some container registries require authentication.
The Kanto Container Manager can be configured to use credentials when accessing remote container registries.
In the Leda images, the sdv-kanto-ctl tools allows to easily add authentication to the container manager configuration:
For example, to access container images from GitHub Packages in a private repository, you need a GitHub Personal Access Token (PAT) with the read: packages scope.
Then, add the repository as shown below:
sdv-kanto-ctl will make the necessary modifications to /etc/container-management/config.json and restarts the container-management.service systemd unit,
so that the changes take effect. You may need to recreate or restart the container if a previous pull failed.
Enable the container manager digital twin representation.
sdv-kanto-ctl set things.enable true
Example: Container Stop Timeout
Kanto waits for a timeout before forcefully stopping a container.
The default is 30 seconds in Kanto, and 10 seconds in the Leda quickstart image.
To change this behavior at runtime:
sdv-kanto-ctl set manager.default_ctrs_stop_timeout 2
2.8.10 - Blueprint Selector
A Rust application that reads all blueprint files in a directory and provides the user with an
interactive (supports filtering) menu to select the one to be deployed on the edge device via MQTT.
If no directory is provided the default one on a Leda Quickstart Image is: /data/var/containers/blueprints.
The “blueprint” files are desired state messages, that have the extension “.blueprint.json” (configurable) and an additional metadata header (required):
{"blueprintMetadata":{"name":"<NAME>","description":"<Short Description>"},"activityId":"correlation-id","timestamp":1235466"payload":{}// This is the desired state message
}
The metadata header will be used to construct the list of options presented to the user. You can find example blueprints under the
example_blueprints directory in the leda-utils repository.
The selected blueprint is then published as an MQTT message on the vehicleupdate/desiredstate topic.
CLI options
To get all available configuration options use the --help/-h flag:
A user-friendly tool to select and deploy SDV blueprints
Usage: blueprint-selector [OPTIONS]Options:
-d, --blueprints-dir <BLUEPRINTS_DIR>
The directory containing the SDV blueprints [default: /data/var/containers/blueprints] -f, --fetch-blueprints
Start in fetch mode (presents a menu to fetch new/updated blueprints) from a remote repository
-e, --blueprints-ext <BLUEPRINT_EXTENSION>
Extension to use when iterating over the files in the blueprints directory [default: .blueprint.json] --mqtt-broker-host <HOST>
Hostname/IP to the MQTT broker where the desired state message would be posted [default: 127.0.0.1] --mqtt-broker-port <PORT>
Port for the MQTT broker [default: 1883] --mqtt-topic <TOPIC>
Topic on which to publish the blueprint desired state message [default: vehicleupdate/desiredstate] -h, --help
Print help -V, --version
Print version
Normal mode
To run in normal mode use:
blueprint-selector
or if you’d like to provide a directory different from the default one, use:
blueprint-selector -d </path/to/dir>
Fetch mode
When starting the blueprint-selector with the -f/--fetch-blueprints flag, you will be presented with a selection of different
fetchers that allow you to download/update blueprints directly in the directory specified with the -d/--blueprints-dir flag
(or in the default directory if not specified).
For example:
blueprint-selector -fd </path/to/dir>
When you choose a fetcher, you will be asked for an URI and blueprint-selector will attempt to fetch the blueprints inside the directory specified by -d.
After providing a URI, pressing Enter, and a successful fetch, you will be brought back to the usual
selector menu, this time including all successfully fetched manifests.
2.9 - Wifi Configuration
BSP packages for emulated WiFi devices (QEMU) and hardware device drivers are provided in meta-leda for supported hardware.
They usually do not require extra configuration.
The required kernel modules and binary blobs are provided with the sdv-wifi-kernel-config.inc config file and the packagegroup-sdv-rpi4wifi packagegroup. These
are included in sdv-image-full.bb and sdv-image-minimal.bb by default.
If you, however, decide to define your own custom image based on Custom Distros,
you would have to make sure the packagegroup is installed to enable WiFi connectivity.
QEMU
QEMU images provide the kernel modules necessary to set-up a virtual wlan interface and connect it to a virtual wifi network. This can be useful in various testing scenarios.
To create and link a virtual WiFi interface to eth0, boot your QEMU image and run:
$ ip link add link eth0 name wlan0 type virt_wifi
The SSID of the virtual network you can connect to is VirtWifi.
Note: Leda Quickstart QEMU images set the name of the default virtual ethernet interface to eth0 through kernel CMDLINE configurations (net.ifnames=0 biosdevname=0).
If you are building a custom image with a different kernel CMDLINE replace eth0 with the name of your virtual interface (check ifconfig).
2.9.1 - Connecting to Wi-Fi networks
Here we will describe the basic steps on how to identify and connect to a WiFi network in interactive or headless mode.
Initial steps (identifying wlan interfaces)
Start by running:
$ ip a
...
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000 link/ether <MAC> brd ff:ff:ff:ff:ff:ff
...
Note: Usually the name of the interface would be wlan0. It might however follow the newer “predictable interface names” standart.
Then the interface name would start with wl* with the remaining characters identifying a physical bus/chip/number/etc
corresponding to the interface. For simplicity we will wlan0 in all examples below.
Most likely your wlan interface would be in the state DOWN. To bring it up:
$ ip link set wlan0 up
Scanning for wireless networks
You can scan for wireless networks using either iw or wpa_cli.
$ iw wlan0 scan
Note: The output of this command can be quite verbose. You can grep for SSID to find the SSIDs of the networks around you.
$ wpa_cli scan && wpa_cli scan_results
The output of wpa_cli is cleaner and more readable so it is recommended to use that.
Connecting to a network
Once you have identified the SSID of your network you can connect to it by ussing the following commands:
You should now be connected to the wireless network. To confirm that, you can once again use ip a to check that wlan0 has been configured with an IP.
This configuration shall be remembered from now on and your interface will try to connect automaticatically to that network whenever it is available.
Headless Wi-Fi configuration
Similarly to the Raspbian, meta-leda provides a mechanism for headless configuration of Wi-Fi credentials for your device (Headless Raspberry Pi Setup).
To use this feature you have to prepapre your wpa_supplicant.conf ahead of time (check the reference above):
IMPORTANT: It is recommended that if you are creating this configuration file on Windows to use an editor such as Notepad++ that can save files using the
“Unix Line endings” (DOS vs. Unix Line Endings), or run it through a tool such as dos2unix
that can convert between the two file formats. Otherwise wpa_supplicant.conf might not be read properly in the Linux image.
Once you have your wpa_supplicant.conf put your SD-card in your Desktop machine and place the configuration file in the root of the BOOT partion.
When you boot your device it should now automatically connect to your Wi-Fi network.
2.10 - GPS Connectivity
GPSD
Leda Quickstart Images provide (within meta-leda) recipes for the integration and setup of GPSD.
GPSD is a service daemon that monitors one or more GPSes or AIS receivers attached to a host computer through serial or USB ports,
making all data on the location/course/velocity of the sensors available to be queried on TCP port 2947
of the host computer. To find out more about GPSD, check out its official documentation.
For easier interaction and debugging gpsd client utilities such as installed gpsfake,
gpspipe, etc. are installed.
Service
GPSD is installed on Leda Quickstart Images as a service. To check its status and/or logs you can use the following two commands:
root@leda-525400123502:~# systemctl status gpsd.service
* gpsd.service - GPS (Global Positioning System) Daemon
Loaded: loaded (/lib/systemd/system/gpsd.service; disabled; vendor preset: disabled) Active: active (running) since Mon 2023-10-02 11:19:54 UTC; 41min ago
...
and the socket:
root@leda-525400123502:~# systemctl status gpsd.socket
* gpsd.socket - GPS (Global Positioning System) Daemon Sockets
Loaded: loaded (/lib/systemd/system/gpsd.socket; enabled; vendor preset: enabled) Active: active (running) since Mon 2023-10-02 11:19:30 UTC; 42min ago
...
With the location of the default config file being:
/etc/default/gpsd.default
By default, the GPSD service on Leda is configured to automatically discover USB devices (plug-and-play). In some cases, a system reboot might be required
after plugging the USB GPS device.
Kuksa.val FeederGPS
The Kuksa GPS Feeder consumes gpsd as a data source and pushes location data to the kuksa.val server (databroker). It is installed as a pre-configured container on Leda Images
through the feedergps.json container manifest.
The container has an internal gpsd server (on port 2948) that connects to the host’s gpsd instance (on port 2947). With the provided container manifest
feedergps should be plug-and-play.
Using pre-recorded GPS traces with gpsfake
Recording NMEA traces
It sometimes might be useful to mock gps services when testing, especially on QEMU virtual machines where emulated USB GPS hardware is not available.
Pre-recorded traces should be in the NMEA-format.
To record a GPS trace in the NMEA format, on a device with physical GPS hardware, gpsd, and gpsd-client utilities installed, run:
gpspipe -R > gps_log.nmea
A sample NEMA file that can be used for testing is provided in the kuksa.val.feeders repository - simplelog_example.nmea.
Feeding NMEA traces to feedergps
Since the running gpsd service will interfere with the following steps, make sure to stop it first by running:
To start gpsfake on port 2946 with gps_log.nmea as an input,
either in the background (by adding & at the end of the shell line) or in a separate shell session run:
root@leda-525400123502:~# gpsfake -P 2946 gps_log.nmea
/usr/bin/gpsfake:21: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632for potential alternatives
from distutils import spawn
Processing gps_log.nmea
gpsfake: log cycle of gps_log.nmea begins.
Note: you can safely ignore the distutils warning.
Then, run a foreground instance of gpsd that reads from gpsfake on port 2946 on the loopback interface only and forwards
the traffic on port 2947 for all interfaces:
gpsd -GNS 2947 gpsd://127.0.0.1:2946
These extra steps are needed as feedergps requires the gpsd server on port 2947 to be available on the kanto-cm0 bridge, as it’s running as a
container and gpsfake cannot be configured to listen on an interface different from the loopback.
Sometimes the feedergps container is started before the databroker and/or gpsd which leads to the container not being able to connect to either
of those services. In such cases, after you’ve made sure the databroker and gpsd are up and running, restart feedergps with:
The device needs to be configured before it can make a connection to the cloud.
The following initial configuration steps are required:
Create a device in the cloud backend, such as Azure IoT Hub
Configure authentication on device
Configure credentials for accessing private container registries
3.1 - Manual Provisioning
Follow these steps to do a manual device provisioning:
Generate the device certificate (eg using openssl) and sign it with your CA.
Log in to Azure Portal, Go to Azure Iot Hub and create a new device
Select the proper authentication type, e.g. X.509 Self-signed or X.509 CA Signed
Copy the device certificate (cert file and key file) to the device to /data/var/certificate
Restart cloud connector service or container.
Create a device in Azure IoT Hub
For the device to be connectable, it needs to be known to the cloud service first. In these steps, we will create a new device identity by using Azure IoT Hub.
Pre-Requisites:
Virtual device must already be started with runqemu ... or leda
Note: For Raspberry Pi, please follow the manual steps below and adapt the SSH connection options to the IP of your Raspbery Pi.
The virtual device needs to be remotely accessible via ssh port 2222 on the host’s localhost (Qemu port forwarding in userspace)
or via ssh port 22 on the IP address 192.168.7.2 (Qemu virtual networking using TAP network interface)
The container runtime needs to have started successfully, check with sdv-health
A Device has been created in Azure IoT Hub
Note: Do NOT create an “edge” device.
Configure authentication on device
For the proper device authentication, the device management backend authority needs to issue a device-specific certificate and sign it. This is a complex process and subject to the specific situation.
For the Leda quickstart images, the software configuration is prepared with dummy certificates which need to be replaced.
ATTENTION: The Leda example device certificates are public and insecure, they only serve demonstration purposes. You need to replace the intermediate certificates and device certificates with your own.
Generate a device certificate using openssl
Sign it with your intermediate CA certificate
Put it into /data/var/certificate/
Restart the cloud connector service or container: systemctl restart cloud-connector or kanto-cm stop -n cloudconnector --force; kanto-cm start -n cloudconnector
Please refer to the Container Registries on how to configure private container registries.
3.2 - Provisioning with sdv-provision
Meta-leda and the Leda-quickstart image provide a utility sdv-provision that simplifies the device provisioning procedure.
Connecting to the device
Since the procedure includes copying and pasting device IDs, it is recommended to connect to the device over a ssh connection. sdv-motd provides an
easy way to find your device’s ip. More information on connecting via ssh can be found here.
Provisioning via a connection string
Device-side
After connecting via ssh run sdv-provision.
Example output:
root@qemux86-64:~# sdv-provision
Checking Eclipse Leda Device Provisioning configuration...
- Certificates directory exists
Checking Device ID
- Based on network device: eth0
- File does not exist, creating: /etc/deviceid
- Device ID: XX-XX-XX-XX-XX-XX
Checking whether either IdScope or ConnectionString is configured
- Neither Id Scope file nor ConnectionString found, needs manual configuration
Do you want to use the global Azure IoT Device Provisioning Service (DPS) by using an Id Scope, or do you want to use a direct connection to a specific Azure IoT Hub using a Connection String?
d) Azure IoT Device Provisioning Service (DPS) with Id Scope
h) Azure IoT Hub with Connection String
Choose:
Note the generated Device ID (XX-XX-XX-XX-XX-XX).
Type h /Azure IoT Hub with Connection String/ and press Enter.
Paste your Azure IoT Hub Connection String: HostName=<IoT Hub in Azure>.azure-devices.net;DeviceId=<XX-XX-XX-XX-XX-XX> and press enter. Where <IoT Hub in Azure> is your Azure IoT Hub name.
The Vehicle Update Manager delegates two different types of updates:
The Desired State on the container layer
The Self Update on operating system layer
Desired State
The Desired State is applied at runtime on the container layer.
This type of update mechanism can update vehicle applications, vehicle services and other containers together with configuration resources or data files at runtime.
If the applications support it, the rollout can also use high-availability strategies, such as rolling deployments. You can find out more about more about
the Container Update Agent here.
Self Update
The Self Update is applied on reboot of the device only.
This type of update mechanism is used for system-level updates which require the operating system to be rebooted to take effect.
You can find out more about the Self Update Agent in the tutorial.
3.3.1 - Configuration
Config file
The default location for the VUM service on the Leda Distro image can be found at /etc/update-manager/config.json.
The location of the config file is specified with the --cfg-file [PATH] flag when starting the binary.
Minimal configuration
A minimal configuration (that is used by the Leda Distro) is the following:
“domain”: specifies the prefix for the MQTT topic, e.g. in this case it’s set to vehicle, so all VUM related topic are prefixed with vehicleupdate/[TOPIC]
“agents”: configures the update agents that would be available to VUM. Here the “readTimeout” key specifies how long should VUM wait for a response from the configured agent.
“thingsEnabled”: whether VUM should use the Kanto Things API for communication or not.
Full configuration
An example configuration file for VUM with all available options is the following one:
Here keys (other the ones above) are self-explanatory. The “connection” section object specifies configuration options for the MQTT connection.
Allowed log leves (in order of increasing verbosity)are: ERROR, WARN, INFO, DEBUG, TRACE.
3.3.2 - Message Flow
Note: This part of the Leda OSS stack is still in active development and there might be differences between the documented and the current version.
As described in Vehicle Update Manager takes a full update message for all domains, identifies the domains affected, the current component versions,
actions to be taken, etc., and delegates those actions to the correct update agent (e.g. self-update/container update).
The update manager (UM) in Leda-distro is configured as specified in UM’s config.json,
which on the final image is usually located in /etc/update-manager/config.json. The standard two domains supported are containers and self-update,
with the latter requiring a reboot on a successful update.
Note: UM allows a custom prefix for all of its topics to be defined (“domain”) in its config.json On the Leda Distro image the default prefix is “vehicle”.
If you decide to change it, replace “vehicle” in all MQTT topics mentioned below with your custom prefix.
A full specification of UM’s API and the relevant MQTT topics can be found in its documentation.
Update Message
The general structure of the update message is as follows:
Where multiple domains and components per domain (each with multiple configuration key-value pairs) are allowed. To trigger an update, publish
your full update message on the vehicleupdate/desiredstate MQTT topic. When UM receives your message, it splits it across the required domains and
publishes messages to the topics that the domain-specific agents are monitoring.
Similarly, update progress can be monitored on the vehicleupdate/desiredstatefeedback topic.
Self-update
The messages for triggering a self-update (image update) are the same as in The Self Update Tutorial.
The only difference here is that when you publish a self-update message on the vehicleupdate/desiredstate topic,
UM will automatically take care to forward your message to the self-update agent, including
forwarding back the update feedback on the vehicleupdate/-namespaced topics.
Containers update (desired state)
Similarly to the self-update, you should start by understanding the operation of the Container Update Agent.
After constructing the desired state message you can publish it on the vehicleupdate/desiredstate and UM will, again, forward it to CUA automatically,
based on the domain specified in the update message.
Combined update messages
The real strength of UM is deploying updates accross multiple domains with a single update message. For example, if you’d like to deploy an image update bundle
(self-update) and a single hello-world container image with the environment variable FOO=BAR set, you can construct the following message:
And publish the message on the MQTT topic vehicleupdate/desiredstate. UM will take actions to identify the affected update domains and publish the correct
messages on the respective topics. All feedback from the specific update agents will be forwarded back to the UM and published on the vehicleupdate/desiredstatefeedback
topic. All these messages will use the same activityId so they can be correlated with each other.
3.4 - Self Updates
In general, the self-update mechanism for operating system level updates is done with two separate partitions. While one partition is the actively booted partition and in use, the other partition can be updated by writing a partition image to it, as it is unused or inactive.
Once the download and writing is done, a reboot is triggered and the boot loader will now switch to the newly updated partition.
If the booting of the updated partition fails, the self update mechanism can revert back to the previous partition or boot to a rescue partition.
As updating the running operating system cannot be done at runtime, the approach requires additional disk space, a second partition and also requires the device to be rebooted for the updates to take effect.
In a vehicle, the self-updater cannot decide on its own when to do a reboot, as the vehicle must be in a safe condition (eg parked, state of charge etc.). Hence, the trigger for performaing the switch to another slot and a subsequent reboot is handed over to a higher level component, such as the vehicle update manager, which may in turn rely on driver feedback or other conditions.
Implementation with RAUC Update Service
RAUC is a lightweight update client that runs on your embedded device and reliably controls the procedure of updating your device with a new firmware revision.
For general usage of the RAUC tool, please see the RAUC User manual
Reference configuration
The project contains an example reference implementation and configuration using RAUC, which allows the evaluation of the concepts, mechanisms and involved software components in an emulated, virtual environment.
The Leda quickstart image contains the following disk partitions:
a small rescue partition
a full SDV installation with a container runtime, pre-loaded SDV container images and deployment specifications and additional developer tools such as nerdctl and kantui.
a minimal SDV installation with a container runtime, but no additional examples or developer tools. This partition is used to demonstrate the self-update functionality.
additional boot and data partitions for keeping system state information
Note: All three rootfs partitions (rootfs) initially contain the same identical copies of the base operating system. Both SDV Root partitions will use the same shared data partition for the container persistent state.
3.4.1 - Self Update Tutorial
This chapter describes the steps necessary to perform a local (without cloud) self update of the operating system.
Self-Update using RAUC Update Bundles
On host: Update bundle sdv-rauc-bundle-qemux86-64.raucb is in current folder
Note: In the development environment, the update RAUC Update Bundle is located in the BitBake machine-specific output folder
Example location is tmp/deploy/images/qemux86-64
On host: Start a dummy web server for serving the update file
python3 -m http.server --bind 192.168.7.1
On host: open two new terminals - one for monitoring and one for triggering the self-update
Terminal 1: To view the progress, watch the MQTT topics selfupdate/desiredstate and selfupdate/desiredstatefeedback:
Initial response message on startup from self update agent in topic selfupdate/currentstate, or upon request by sending message to selfupdate/currentstate/get
{"activityId":"1234567890","timestamp":1687786390,"payload":{"status":"IDENTIFYING","message":"Self-update agent has received new desired state request and is evaluating it.","actions":[]}}
{"activityId":"1234567890","timestamp":1687786390,"payload":{"status":"IDENTIFIED","message":"Self-update agent is about to perform an OS image update.","actions":[{"component":{"id":"self-update:os-image","version":"v0.0.10-194-g3d48cb8"},"status":"IDENTIFIED","progress":0,"message":"Self-update agent is about to perform an OS image update."}]}}
External trigger to download command on topic selfupdate/desiredstate/command:
{"activityId":"1234567890","timestamp":1687786931,"payload":{"status":"DOWNLOADING","message":"Self-update agent is performing an OS image update.","actions":[{"component":{"id":"self-update:os-image","version":"v0.0.10-194-g3d48cb8"},"status":"DOWNLOADING","progress":0,"message":"Downloading 0.0 MiB..."}]}}
{"activityId":"1234567890","timestamp":1687786936,"payload":{"status":"DOWNLOAD_SUCCESS","message":"Self-update agent is performing an OS image update.","actions":[{"component":{"id":"self-update:os-image","version":"v0.0.10-194-g3d48cb8"},"status":"DOWNLOAD_SUCCESS","progress":100,"message":"Downloaded 106.3 MiB..."}]}}
External trigger to update command on topic selfupdate/desiredstate/command:
{"activityId":"1234567890","timestamp":1687787145,"payload":{"status":"UPDATING","message":"Self-update agent is performing an OS image update.","actions":[{"component":{"id":"self-update:os-image","version":"v0.0.10-194-g3d48cb8"},"status":"UPDATING","progress":0,"message":"Checking bundle version and version in desired state request."}]}}
{"activityId":"1234567890","timestamp":1687787302,"payload":{"status":"ACTIVATING","message":"Self-update agent is performing an OS image activation.","actions":[{"component":{"id":"self-update:os-image","version":"v0.0.10-194-g3d48cb8"},"status":"UPDATING","progress":0,"message":"Self-update agent is performing an OS image activation."}]}}
{"activityId":"1234567890","timestamp":1687787303,"payload":{"status":"ACTIVATION_SUCCESS","message":"Self-update agent has activated the new OS image.","actions":[{"component":{"id":"self-update:os-image","version":"v0.0.10-194-g3d48cb8"},"status":"UPDATED","progress":0,"message":"Self-update agent has activated the new OS image."}]}}
External trigger to cleanup command on topic selfupdate/desiredstate/command:
{"activityId":"1234567890","timestamp":1687787382,"payload":{"status":"CLEANUP_SUCCESS","message":"Self-update agent has cleaned up after itself.","actions":[{"component":{"id":"self-update:os-image","version":"v0.0.10-194-g3d48cb8"},"status":"UPDATE_SUCCESS","progress":0,"message":"Self-update agent has activated the new OS image."}]}}
{"activityId":"1234567890","timestamp":1687787382,"payload":{"status":"COMPLETE","message":"Self-update completed.","actions":[{"component":{"id":"self-update:os-image","version":"v0.0.10-194-g3d48cb8"},"status":"UPDATE_SUCCESS","progress":0,"message":"Self-update agent has activated the new OS image."}]}}
Rollback command
External trigger to rollback command on topic selfupdate/desiredstate/command:
Downloading (when it is waiting for DOWNLOAD command)
Installing (when it is waiting for UPDATE command)
Installed (when it is waiting for ACTIVATE command)
Failed (when it is waiting for CLEANUP command)
3.4.2 - RAUC Integration
Leda integrates RAUC as a reference implementation and example configuration. It allows the evaluation of the concepts, mechanisms and involved software components in an emulated, virtual environment or on physical devices.
Checking the RAUC Status
Get the current RAUC boot status:
rauc status
Example output:
root@qemux86-64:~# rauc status=== System Info===Compatible: Eclipse Leda qemu86-64
Variant:
Booted from: rootfs.1 (SDV_B)===Bootloader===Activated: rootfs.1 (SDV_B)=== Slot States===o [rootfs.1](/dev/sda5, ext4, inactive) bootname: SDV_B
mounted: /
boot status: good
x [rootfs.0](/dev/sda4, ext4, booted) bootname: SDV_A
boot status: good
Forcing to boot the other slot
To manually force the device to boot into another slot, mark the current booted slot as bad, mark the other partitions as active and perform a reboot:
rauc status mark-bad booted
rauc status mark-active other
reboot now
Testing the rescue system
By marking both root slots as bad, the bootloader is supposed to boot the rescue system:
rauc status mark-bad rootfs.0
rauc status mark-bad rootfs.1
reboot now
Example output of rauc:
o [rootfs.1](/dev/sda5, ext4, inactive) bootname: B
boot status: bad
o [rootfs.0](/dev/sda4, ext4, booted) bootname: A
mounted: /
boot status: bad
Customizations
The configurations can be customized by applying or patching the following files:
The GRUB bootloader has a configuration file which describes which partitions are bootable, which partition they are located at and a reference to RAUC’s slot name.
The configuration also contains RAUC specific logic and variables required for a proper integration. Please see the full grub.cfg in the source repository and RAUC Documentation - Integration - GRUB for details.
Excerpt:
...
menuentry "SDV Slot A (OK=$SDV_A_OK TRY=$SDV_A_TRY)" {
linux (hd0,4)/boot/bzImage root=/dev/vda4 $CMDLINE rauc.slot=SDV_A
}
menuentry "SDV Slot B (OK=$SDV_B_OK TRY=$SDV_B_TRY)" {
linux (hd0,5)/boot/bzImage root=/dev/vda5 $CMDLINE rauc.slot=SDV_B
}
U-Boot Bootloader Configuration
Similarly to GRUB, integration of RAUC with U-Boot requires custom boot scripting. A highly detailed explaination can, again, be found in the official RAUC Documentation - Integration - U-Boot.
Meta-Leda provides such integration recipes and scripts for all U-boot based targets, for which a Leda Quickstart image is available (qemuarm64, qemuarm and rpi4-64). For example:
Note: A custom U-Boot device defconfig might be required for some devices to be integrated with RAUC. Leda Quickstart images patch the default defconfigs for qemuarm64 and qemuarm to save the U-Boot environment in a VFAT BOOT partition.
Disk Partitioning with OpenEmbedded Image Creator (WIC)
The OpenEmbedded Image Creator is used in BitBake to actually create full disk images with multiple partitions.
These disk images are machine specific and the structure of the partitions are configured in OpenEmbedded Kickstart files (*.wks).
Excerpt qemux86-grub-efi.wks
Note: The excerpt is exemplary, please see the sources for a full representation and documentation.
bootloader --ptable gpt
part --fixed-size 50M --source rawcopy --sourceparams="file=efi-boot.vfat" --fstype=vfat --label boot --active
part --fixed-size 10M --source rawcopy --sourceparams="file=grubenv.vfat" --fstype=vfat --label grubenv
part /rescue --source rootfs --fstype=ext4 --label rescue
part / --source rootfs --fstype=ext4 --label root_a
part / --source rootfs --fstype=ext4 --label root_b
part /data --fixed-size 4G --fstype=ext4 --label data
3.4.3 - API Reference
The self update agent (SUA) is a component responsible for the OS Update process
SUA is communicating on MQTT interface via usage of defined messages. Internally, SUA uses RAUC to perform the update
Following sequence diagram shows the happy path example of communication between components.
Process Overview
sequenceDiagram
participant m as MQTT Broker
participant s as SUA
participant r as RAUC
s -->> m: connect
loop Wait for OTA trigger
Note left of s: Initial start
s ->> m: Current state (installed version from booted partition)
Note left of s: Trigger for OTA
m ->> s: Desired state request (new version and url to bundle)
s ->> m: Feedback (update actions are identified)
Note left of s: Command for Download
m ->> s: Download command
s ->> s: Download bundle
s ->> m: Feedback (downloading/downloaded/failed)
Note left of s: Command for Update
m ->> s: Update command
s ->> r: Flash image to partition
r ->> r: Flashing...
s ->> m: Feedback (updating with percentage)
r ->> s: Flash completed/failed
s ->> m: Feedback (updated/failed)
Note left of s: Command for Activate
m ->> s: Activate command
s ->> r: Switch partitions (booted <-> other)
r ->> s: Switch completed/failed
s ->> m: Feedback (activated/failed)
Note left of s: Command for Cleanup
m ->> s: Cleanup command
s ->> s: Remove temporary files
s ->> m: Cleanup completed + status from previously failed state (completed/failed)
end
stateDiagram
Uninitialized --> Connected: Connected
Connected --> Identified: Start (OTA trigger)
Identified --> Downloading: Command download
Identified --> Failed: If OTA trigger is invalid
Downloading --> Updating: Command update
Downloading --> Failed: If download has failed
Updating --> Activate: Command activate
Updating --> Failed: If update has failed
Activate --> Cleanup: Command cleanup
Activate --> Failed: If activate has failed
Failed --> Cleanup: Command cleanup
Cleanup --> Idle
Important: Uninitialized state is the default entry state or state in case connection is lost.
To simplify reading of the diagram arrows from other states to Unitialized have been removed.
MQTT communication is done over 5 MQTT topics:
Trigger OTA
Topic
Direction
Description
selfupdate/desiredstate
IN
This message triggers the update process
The payload shall contain all data necessary to obtain the update bundle and to install it
Trigger self-update step/action
Topic
Direction
Description
selfupdate/desiredstate/command
IN
This message triggers the single step in update process (download/flash/activate/cleanup)
Report current state
Topic
Direction
Description
selfupdate/currentstate
OUT
This message is being sent either once on SUA start or as an answer to response received by selfupdate/currentstate/get
It contains information about the currently installed OS version
Get current state
Topic
Direction
Description
selfupdate/currentstate/get
IN
This message can be received at any point of time
Indicates that SUA should send back the version of the installed OS as current state.
Report status of self-update process
Topic
Direction
Description
selfupdate/desiredstatefeedback
OUT
This message is being sent by SUA to share the current progress of the triggered update process
This is the OUT counterpart of selfupdate/desiredstate input message
Checkout
SUA links to some 3rd party libraries, which are fetched as submodules, therefore the cloning shall be performed with recursive option:
Leda is using Kanto Container Management as the upper-layer container runtime and container orchestration engine.
Besides the command line tool kanto-cm, Kanto also has remote interfaces to manage containers.
Remote Interface
Kanto’s container-management service offers a remote interface via local messaging (MQTT) to interact with a digital twin on the cloud side.
This feature can be easily enabled by setting "things": { "enabled": true } in /etc/container-management/config.toml.
When one of the cloud connector components, such as leda-contrib-cloud-connector or Kanto’s azure-connector, is connected to a cloud backend, the container-management will publish its own information using Eclipse Ditto and Eclipse Hono messages. For this, container-management only needs the device Id, gateway Id and tenant Id.
3.5.1 - Cloud Connectivity
Simulation of cloud connectivity
Container Management starts and subscribes to edge/thing/response
Cloud Connector starts and publishes the following message to edge/thing/response as soon as the connection is online:
namespace is azure.edge for Kanto’s Azure Cloud Connector
gatewayId indicates the hostname of the Azure IoT Hub
deviceId is the identifier for the device, this can either be part of the Azure Connection String or part of the device authentication certificate (CN)
tenantId is a configuration setting in the cloud connector
Note: You can simulate the cloud connector trigger by issueing the MQTT message manually on command line:
The container update agent is a component of kanto container management, that can be enabled in the Container Management’s config.json.
When it receives a desired state message on the containersupdate/desiredstate topic it compares the containers (with their current versions and configuration)
that are managed by Kanto Container Management and those described in the desired state messages. When it has identified the differences between the two,
it resolves them by deleting, downloading, or re-creating containers.
The desired state message
A basic desired state message has a similar structure to all update messages. To deploy the hello-world docker container (removing all other containers
currently deployed on the device), you can publish the following desired state message:
You can configure port mappings, environment variables, device mapping, logging, and more, by adding additional key-value pairs
to the “config” array of the given container. For example, if you want to set the environment variable FOO="BAR" inside the container, you can
specify:
A full list of all key-value pairs with their defaults can be found in this doc for CUA.
System containers
If a container is not specified in the desired state message, it would be deleted by CUA when the message is received. This might be undesirable for containers
that are supposed to run as system services from the first boot of the device through its operation. Such a container might be the Self Update Agent container
on the Leda Distro image, which we do not want to specify in every desired state message and deleting/recreating-it during an update might lead to unexpected behaviour.
That’s why in Container Management’s config.json
in the CUA section, you can specify in the “system_containers” array the names of those containers that would like to be treated as such.
MQTT Topics
Since the MQTT interface of the update agent is abstract, the following message flows are similar to those for the self-update agent mentioned in its tutorial
Getting the current state
On initialization, CUA will publish the current state of all containers on the containersupdate/currentstate topic,
the activityId for such a message would be initial-current-state-<TIMESTAMP>. This message can be understood as the “current container inventory”.
An example inventory from a running Leda image is currentstate-leda.json.
You can request an update of the current state at any point by publishing an empty message on the: containersupdate/currentstate/get:
The updated inventory will, again, be published on the containersupdate/currentstate topic with correlation ID of <UUID>.
Deploying a desired state message
A desired state message describing the containers and their environments of a typical Leda Distro deployment is leda-desired-state.json.
To trigger a desired state deployment directly from CUA, publish the message above on containersupdate/desiredstate, e.g. by running:
You can monitor the update feedback from CUA, by listening on the topic containersupdate/desiredstatefeedback.
Note: Since the desired state feedback can be quite verbose and happens in real time during the update it could be hard to understand manually.
However it’s structured json, so it could be easily machine-parsed and monitored for specific key-value pairs.
3.5.3 - Orchestration
Container Management
The container management will respond to the cloud connectivity status message by initially sending a list of containers:
Container Management responds with a list of containers in the topic e/<tenantId>/<gatewayId>:<deviceId>:edge:containers
Container-level metrics, such as CPU utilization or memory usage, can be retrieved on-demand and continuously by enabling the container metrics events.
This is done by sending a request to the topic command//<namespaceId>:<gatewayId>:<deviceId>:edge:containers/req/<correlationId>/request:
When deploying containerized applications, the container runtime will pull container images from a (remote) container registry.
The pulled container images and their layers are then stored in a local storage.
Private Container Registries
To be able to pull container images, the container runtime needs access to the container registry.
Some container registries require authentication.
The Kanto Container Manager can be configured to use credentials when accessing remote container registries.
In the Leda images, the sdv-kanto-ctl tools allows to easily add authentication to the container manager configuration:
For example, to access container images from GitHub Packages in a private repository, you need a GitHub Personal Access Token (PAT) with the read: packages scope.
Then, add the repository as shown below:
sdv-kanto-ctl will make the necessary modifications to /etc/container-management/config.json and restarts the container-management.service systemd unit,
so that the changes take effect. You may need to recreate or restart the container if a previous pull failed.
The seat adjuster is an example to showcase how to create a vehicle application which senses and actuates signals in the vehicle
for Eclipse Leda with help of Eclipse Velocitas and Eclipse Kuksa
. The aim is not to build the best available seat adjuster application possible but to show how one can use the applied technologies
to build a companion app for the interaction with a vehicle.
If you are new to the concepts around Eclipse SDV and the mentioned projects
we recommend to read the SDV Tutorial first.
Description
The idea of the seat adjuster application is to have a custom application to move the driver seat to positions defined
in a driver profile hosted by a third-party web service.
The setup contains the following components:
Cloud or mobile trigger: not part of the Leda image, but we simulate it by issuing MQTT messages
Seat Adjuster : Developed with Eclipse Velocitas to be deployed by user
Eclipse Kuksa.val - KUKSA Databroker (pre-installed with Eclipse Leda)
Mock Service: Example provider for Eclipse Kuksa.VAL which mocks the behavior of the vehicle.
Seat ECU and the separate Seat Motor hardware can be emulated using a virtual CAN-Bus, which is beyond the scope of this guide.
The seat adjuster application interacts with the vehicle through a Vehicle Abstraction Layer created by the KUKSA Databroker,
which uses the Vehicle Signal Specification (VSS)
to express the current value and in case of actuators also the desired state of the vehicle signal.
By developing against the abstraction layer, the application becomes independent from the actual physical seat.
To control the position of the driver seat, the seat adjuster sets the target value of the Vehicle.Cabin.Seat.Row1.Pos1.Position signal in the KUKSA Databroker.
The architecture assumes so-called actuation providers that apply the changes to the actual vehicle as indicated in the target value, e.g.,
through interaction with the responsible ECUs.
For this tutorial, we do not expect you to interface with an actual vehicle and thus abstract the vehicle by using the Kuksa.Val vehicle mock service.
This vehicle mock service allows the definition of behavior toward the KUKSA Databroker like we would expect from the vehicle, for example,
setting the current value after reacting to changes to the target value of a signal.
Notify subscriber of changed target Vehicle.Cabin.Seat.Row1.Pos1.Position" --> mockservice
As interface to the user, we assume a client that can, for example, be a local app in the infotainment domain with a user interface
or an off-board application sending the request from a backend.
Either way, the client controls our seat adjuster application through a JSON encoded message over MQTT using the topic setPosition/request.
The position parameter can be any value between 0 and 1000.
Getting Seat Position
When the seat moves, the provider gets this information, for example, from the seat ECU over the CAN-bus.
We use the mock service as a provider and configure it to set the current value for the Vehicle.Cabin.Seat.Row1.Pos1.Position signal in the KUKSA Databroker
after the target value for the signal changes.
To receive the changes to the seat position, the seat adjuster application already subscribed to the current value of the signals and thus gets notified.
As a result, the seat adjuster constructs a JSON message and sends the new seat position to the MQTT-topic seatadjuster/currentPosition
where any client can consume it.
The seat adjuster also sends responses to each request received at the MQTT-topic seatadjuster/request with a message to the MQTT-topic seatadjuster/response
indicating whether it accepted the incoming request and set the target value or whether there was an error like the vehicle currently moving.
We use Eclipse Velocitas to develop the seat application against the API of the Kuksa.val Databroker:
In the first step, you create a copy of the Eclipse Velocitas template repository.
You create the copy by opening the repository in GitHub and selecting: Use this template -> Create a new repository.
In the next step, you choose under which organization to place the created repository and whether it should be public.
If you set the repository to private, you have to perform additional configuration steps mentioned below.
In addition to the Python template used in this guide, there is a C++ template available.
Execute Development Container in VSCode
You then checkout the repository on your development machine and open it in VSCode. From VSCode
you can execute the development container (DevContainer) configured in the repository.
For this to function, you need to install the following tools on your computer:
In the best case, VSCode may detect that the repository contains a DevContainer configuration and ask you whether to execute it.
Alternatively, you can press F1 in VSCode and then enter DevContainers: Reopen in container to start the DevContainer.
In either case, VSCode should reopen and then connect to the DevContainer.
Because of the DevContainer, we do not need to make further modifications to the developer machine.
Develop the application
In the next step, we work on the actual application. You find the skeleton code in /app/src/main.py of the Eclipse Velocitas template and thus the DevContainer.
Eclipse Velocitas provides the code
to realize the described seat adjuster application.
One way to get the code is to use a pre-configured task in VSCode by pressing ‘F1’ and then typing ‘Run Task’.
As an alternative, you can check the latest version of the seat adjuster example code
in the Eclipse Velocitas SDK repository
in the Velocitas SDK directory.
There is a chance that the latest code for the seat-adjuster example in the main-branch of the Eclipse Velocitas SDK
is a bit different compared to the code snippets below.
Let us walk through some lines of the code where the logic is in the vapp.py while the entry point is in main.py.
In the on_start(self) function we subscribe to any changes of the current value of the VSS signal Vehicle.Cabin.Seat.Row1.Pos1.Position in the KUKSA Databroker.
asyncdefon_start(self):"""Run when the vehicle app starts"""awaitself.Vehicle.Cabin.Seat.Row1.Pos1.Position.subscribe(self.on_seat_position_changed)
When the seat position changes, the on_seat_position_changed function is triggered and publishes the new seat position value as MQTT-message to the topic seatadjuster/currentPosition.
In addition, we have the function on_set_position_request_received which is triggered for every MQTT-message to the topic seatadjuster/setPosition/request.
If the vehicle speed is zero, meaning that the vehicle does not move, we set the target value in the KUKSA Databroker for the position signal of the seat
to the value requested in the incoming MQTT message.
The get() and set() functions are created based on a VSS model, and we assume that the KUKSA Databroker instance uses the same VSS model.
In many cases, like the default Eclipse Leda, one may rely on the upstream VSS model, but some scenarios require further signals, e.g., by applying an overlay.
You can configure the used VSS model in the app/AppManifest.json file. This file includes an interface definition with the entry for the default vehicle_signal_interface.
The VSS signals in this guide are part of VSS in version 3.0.0.
The DevContainer generates the respective Eclipse Velocitas SDK based on this configuration.
For more details see the Eclipse Velocitas Model Generator.
At this point, you may wonder how the application actually knows to which MQTT broker to connect and where to find the correct instance of the KUKSA Databroker.
This service discovery is abstracted within the Velocitas SDK and involves the usage of so-called middleware to find and call the other components.
As of writing this page, Eclipse Velocitas supports DAPR as middleware or uses the native approach to configure the correct address directly.
The details of how to set and configure the used middleware are part of the deployment.
Signal Description: The signal indicates the seat position on the vehicle x-axis, where the value 0 is the frontmost position supported by the seat.
The value is the distance measured in millimeters.
The example implementation supports values between 0 and 1000 millimeters.
Note: This range of valid values is not reflected in the standard Vehicle Signal Specification. OEMs would overlay the VSS tree with actual Min/Max values,
depending on the seat hardware available in the vehicle model.
Start Runtime in DevContainer to test application
You may skip the application testing since we already provide the example code.
But it still makes sense to get a general idea of how to test and debug the code with the tooling in the DevContainer.
As mentioned before, the execution and, thus, the testing of the application requires a set of other components to be available
like the KUKSA Databroker or an MQTT-broker.
Furthermore, the deployment, the configuration, and the behavior of the application may change depending on the used (container) management solution.
Therefore, Eclipse Velocitas allows the deployment of the required components and the application with the container management approach of choice inside the DevContainer.
We use the Eclipse Kanto runtime here since we later deploy the seat adjuster application to Eclipse Leda, which uses Eclipse Kanto for container management.
Once the runtime is available, we add our application by executing:
You can now test the application by interacting with it through the local MQTT broker.
To send and receive MQTT messages, use the VSMQTT plugin with a cloud icon
in the left side of the VSCode instance connected to the DevContainer.
We do not get into details for the topics and messages here since we will run the application in Eclipse Leda again later in this guide.
Once you finish the application testing and development, you can shutdown the runtime with:
velocitas exec runtime-kanto down
Eclipse Velocitas provides Tasks to abstract the mentioned calls of the velocitas CLI. As an alternative you can thus press F1 -> Run Task
and scroll for the respective task like Kanto runtime Up.
Commit and Release Application
When you are confident about the application, you want to be able to distribute it.
Here, pre-configured workflows from Eclipse Velocitas for GitHub Actions are helpful.
You now commit your changes and push them to your copy of the Eclipse Velocitas template repository in GitHub.
Before you create the commit, we recommend running the pre-commit task, which performs similar checks and linting as the CI workflow from Eclipse Velocitas.
You can trigger the pre-commit as a task in VSCode:
Press F1
Write Tasks: Run Task and press enter
Write Pre Commit Action and press enter
The pre commit action should start in a terminal inside VSCode.
You can check the available tasks configured by Eclipse Velocitas in .vscode/tasks.json.
If the pre-commit was successful, you may push your changes and open the repository in the browser.
In the meantime, the push should trigger the CI workflow and the Build multiarch image workflow, which you can track in the Actions tab.
If you set your copy of the template repository to private, the CI workflow may fail due to missing permissions to write container images to GitHub packages.
You can grant more Workflow permissions in the Settings tab of the repository under Actions-> General.
To deploy your application to a target and if the two workflows have finished successfully, you can perform a release in GitHub.
The subsequent release workflow will make the application available as a built container in the container registry of GitHub (Code -> Packages).
To do the release in GitHub, go to the Code tab and click Releases on the right side of the page.
Then you can Draft a new release, create a new tag and title for the release, and click Publish Release, which triggers the Release workflow.
We now want to deploy the application to a target device.
You may follow the remainder of this guide on a separate device like a RaspberryPi, but you can emulate such a device on your development machine too.
Either way, we use Eclipse Leda in version 0.1.0-M2 as the target system, which is a Linux-based distribution with pre-installed SDV components like the KUKSA Databroker
and Eclipse Kanto for container management.
For more details on how to download and run Eclipse Leda, follow the respective guides:
We recommend to get started with the QEMU setup.
In any case, you now need to configure Eclipse Kanto to execute the application.
For this, it helps to get an overview of which containers are currently running in Eclipse Kanto. You can get this either through the command:
kantui
or
kanto-cm list
From this list, ensure that at least the KUKSA Databroker runs, which should be the case since it is are pre-configured
with the Eclipse Leda release.
In Eclipse Kanto, you can manage a container with the command line application kanto-cm or container manifest files describing a desired container execution.
The advantage of using the container manifests is that the configuration is persisted across a reboot of the system and is easier to use
to describe a desired software state for the overall vehicle.
Eclipse Leda has the kanto-auto-deployer systemd service, which applies any changes to the manifests in /data/var/containers/manifests to Eclipse Kanto.
Thus, the typical way to add or adapt containers is to modify the corresponding container manifest.
Disable other containers
The release 0.1.0-M2 of Eclipse Leda comes with a number of pre-configured and automatically executed containers.
One of these containers is the feedercan that feeds changing values from a recording for signals such as Vehicle.Speed to the KUKSA Databroker.
These values interfere with the seat adjuster application, which only moves the seat if the vehicle speed is zero.
Another interfering container is the seatservice-example which reacts to changes in the signal Vehicle.Cabin.Seat.Row1.Pos1.Position
and which we replace later with the mock service.
Therefore, we need to stop the feedercan and the seatservice-example container.
This is possible in kantui by selecting the respective entry and pressing R.
In addition, you need to remove the corresponding container manifests in /data/var/containers/manifests to avoid that the Eclipse Kanto
auto-deployer re-deploys these containers. Another approach is to change the ending of the not-needed manifests to something other than .json.
If the feedercan container still runs, the seat adjuster application app will later respond with the following error message:
seatadjuster/setPosition/response{"requestId":"12345","result":{"status":1,"message":"Not allowed to move seat because vehicle speed is 9.0 and not 0"}}
Since they consume resources and are not needed for the seat adjustment, you may remove the containers and manifests for cloudconnector,
hvacservice-example, sua, or vum as well.
As an alternative to using kanto-cm, you can add a container manifest to the directoy watched by the kanto-auto-deployer (data/var/containers/manifests).
To add the container manifest, create a new file inside this folder.
touch seat-adjuster.json
nano seat-adjuster.json
and copy the manifest from below. You can save the file with strg+s and close the window with strg+q.
You can create the file on the development machine and copy it via scp too:
The example deployment descriptor below is available in
meta-leda-components
too.
An interesting aspect of the snippet is the config.env section at the bottom of the container manifest.
There, we define a number of environment variables for the container
which configures the Eclipse Velocitas SDK to use the native middleware and where to find the MQTT-broker and the KUKSA Databroker to use.
We did the same in kanto-cm call behind the parameter --e=.
If the GitHub packages in which you stored the container image are private, Eclipse Kanto needs a valid access token to download the container image.
You can create a personal access token in the Developer Settings of your GitHub account. Select Personal access token -> Tokens (classic)
and generate a new token that at least has the read:packages permission. Copy the generated token to a secure location or to Eclipse Kanto
because GitHub will not show it again.
You can now configure Eclipse Kanto in Eclipse Leda to use the token by executing:
sdv-kanto-ctl add-registry -h <registryhostname> -u <your_username> -p <your_password>. In the case of GitHub, the registryhostname is ghcr.io
, the username is your GitHub handle, and the password is the generated token.
See Container Registries for more details.
To make sure that Eclipse Kanto detects the changes in the manifests folder, you can restart the respective system services:
systemctl restart kanto-auto-deployer
Mock Service
As explained in the description of the code, the seat adjuster application sets the target value for the seat positions in the KUSKSA Datbroker
and waits for the current position to update.
For this to function, there needs to be a component that reacts to this change by moving the seat and updating the current value accordingly.
Because we cannot assume that you have an actual ECU availabe for running this guide, we mock the vehicle behavior
with the vehicle mock service from the Eclipse Kuksa project.
The mock service allows the definition of custom interaction sequences with the KUKSA Databroker. For instance, one can react to changes to specific signals
or update signals with a time trigger. You can define the sequences in a Python file like the example mock.py below.
The snippet shows how to use a change to the target value for the seat position signal as a trigger to update the current value to the target value step-wise
over a duration of 10 seconds.
For the deployment, you create another container manifest in /data/var/containers/manifest with the content from below.
The container manifest also mounts a custom mock.py into the container to replace the configuration of the default mock.py.
With the container manifest below, Eclipse Kanto instead mounts from /data/var/mock/mock.py.
Therefore, you need to create this directory and the file with the content from below.
You may now check with kantui or kanto-cm list whether all components (databroker, seatadjuster-app, and mock-service) are running well.
The next step is to interact with the seat adjuster.
seat-application.json
This is the Eclipse Kanto container manifest for the seat adjuster application.
The container manifest for the mockservice may look like the following snippet. Note, that the files referenced in the source of the mount_points
needs to be present in the file system of your Eclipse Leda instance.
We interact with the seat application through MQTT messages to emulate the behavior of an offboard application.
To see the responses from the seat adjuster app, subscribe to the MQTT topic `seatadjuster/#``.
mosquitto_sub -t 'seatadjuster/#' -v
To initiate the moving of the seat, publish an MQTT message for the seat adjuster application to set the position to 1000 (which is the equivalent of 100%):
You may need to open a second terminal session to send the message.
In the QEMU setup, you can do this through an SSH connection from the host machine by running ssh -p 2222 root@localhost.
After publishing the setPosition-message, the expected output for the seatadjuster/# subscription should look like this:
If you encounter an issue or want to look deeper into the state of the container, you can check the logs by executing:
kanto-cm --name <container-name> logs
Run Kuksa Client
Besides trusting the log information and the MQTT messages that the seat position in the KUKSA Databroker has changed you can read the values
directly from the KUKSA Databroker with the KUKSA Client.
Through the sdv-ctr-exec it becomes possible to interact with the CLI of the Eclipse KUKSA Client:
Congratulations, you have reached the end of the seat adjuster guide. Based on the used code, you can now continue to realize other applications by using other signals.
You may need to adapt your mock.py accordingly.
In addition, you can connect the seat service to a CAN-environment.
Within the seat adjuster guide, we so far mocked the behavior of the actual vehicle.
In the following, we give an overview of how to create a virtual CAN-bus and interact with it to send CAN-frames for moving a seat.
Instead of the mock service you use the seat service as a provider, which is another pre-installed container
acting as the connection between the KUKSA Databroker and the underlying hardware.
More specifically, it subscribes to the target value of the Vehicle.Cabin.Seat.Row1.Pos1.Position signal,
can send CAN-frames, and updates the current value of the signal in small steps until it is equal to the target value.
For more details, visit the Kuksa.val.services repository,
which hosts the code for the seat service.
With a new installation of Eclipse Leda, the seat adjuster comes by default.
If you performed the steps from the deploy the seat adjuster in Eclipse Leda guide,
you need to re-add the seatadjuster container manifest and remove the mockservice.
More details on how to do this are available in that guide.
The default configuration of the Seat Service is using simulated VCAN. If you want to switch to a physical CAN-Bus interface,
the container needs to have access to the CAN-Bus hardware.
Such a CAN-Bus device might be a Raspberry Pi setup with an MCP251x-based CAN-Hat extension or a QEMU image with an emulated kvaser_pci device
(enabled on the Leda QEMU Quickstart images by default).
This setup would require some adjustments to the container manifest in order for the container to have access to the physical CAN-Bus.
Make Seat Service container privileged and run on the host network interface:
Remove all port mappings and extra hosts (set "extra_hosts": [] and "port_mappings": []) for the container as it’s now running in host-networking mode
(host_ip variable no longer available) and all ports are directly exposed.
Set the address to the databroker to localhost:30555:
Attention: Safety considerations are not in scope for this example tutorial. This example is for demonstrating the general approach.
Actual safety requirements must be handled within the Seat ECU as the lowest level component to guard against non-safe use of the seat motors.
Non-ASIL domains are not certified for safety requirements. Please pay attention when following the physical CAN tutorial and attaching physical actuators to
not harm anybody by accidental movements of seat motors or any other actuator.
However, the Seat Adjuster example application contains a rudimentary “Safe State” condition check: it will only allow to move the seat
when the vehicle is not moving.
The condition is using VSS path notation: Vehicle.Speed == 0 (see main.py#L82 in v0.9.0)
Note: The Kuksa.VAL CAN Feeder, which is deployed by default on Eclipse Leda is constantly updating the Vehicle.Speed
You need to disable the feedercan container (see step 7 of Getting started), otherwise the Seat Adjuster application
will decline the request and not move the seat.
In the Dog Mode use case, an existing vehicle service (such as HVAC for Heating, Ventilation and Air Conditioning) is used for another use case.
When a driver enables the dog mode, the vehicle will keep the climate in a status to accomodates the pet while the driver is gone for a few minutes.
The focus on this example is to show how an additional application can reuse existing functionality for new use cases. The vehicle service being used does not need to be adapted for the new use case. The new use case is deployed as an additional functionality, separated from the rest of the existing system.
Architecture Overview
Cloud or mobile trigger: not part of the Leda image, but can be simulated by issueing MQTT messages
Eclipse Velocitas - Vehicle Application: Dog Mode (to be deployed by user as part of the Velocitas tutorial)
Eclipse Kuksa.VAL - Example Service: HVAC Service (pre-installed)
Eclipse Kuksa.VAL - Data Broker (pre-installed)
Getting started
Follow the Velocitas tutorial: build and deploy your clone of the dog mode example
Download and run the Leda quickstart image
Deploy the application to the container runtime, either manually by using kanto-cm create or by providing a deployment descriptor in /var/containers/manifests. An example deployment descriptor can be found in meta-leda-components. Details on the deployment can be found in Leda Vehicle Applications
Ensure the databroker and the service containers are running and you know how to check their log files
To generically interact with the Vehicle Signals which are managed in the Eclipse Kuksa.VAL Databroker,
you can either use the natively installed databroker-cli command line tool, or use the CLI tool from an updated and released containerized image.
Kuksa Databroker CLI
To install a new version of the Kuksa Databroker CLI container, follow these steps:
However, if you want to add additional custom signals or mappings from CAN-Bus for the
Kuksa.VAL dbc2val feeder,
the VSS data model needs to be customized and regenerated.
The following steps can be performed on a development machine to regenerate VSS data model with custom a vspec mapping.
Concepts
Setup workspace
Defining the VSS Overlay
Regenerate VSpec JSON
Generate a candump
Databroker and dbc2val containers
Testing with data
Concepts
VSS Overlay
The VSS Overlay concept allows to override the
standard signals in the specification with custom signals. It defines metadata attributes like signal name, datatype, description etc.
In addition, the vspec file allows to add custom metadata, such as the dbc node in the following example:
You need the following files in your workspace folder:
./custom.dbc - The vehicle-specific DBC file.
You can use the Tesla Model 3 example
or check out the opendbc project.
./custom.vspec - The VSS overlay from the previous step
Defining the VSS Overlay
The definition of an VSS overlay is a manual process.
It requires research, browsing the existing VSS catalog and deep knowledge of the vehicle signals.
Especially knowing the semantic of a signal and how to map it between DBC and VSS is a complex task.
Note: The Leda team is not aware of any advanced tooling to support the automation of this task.
Create a new file custom.vspec. Use YAML format
For each identified signal:
Look up if there already is a corresponding signal in VSS. You may use the Digital.Auto Playground or the spec directly.
Add a new top-level entry to the custom.vspec file. The key is the full VSS path name in dot notation.
Add the corresponding dbc node
Add the signal attribute and enter the name of the CAN-Bus signal name in the DBC
Add additional attributes such as interval_ms, message or transform.
Note: The attributes signal, interval_ms and transform are evaluated by dbc2val.
The attribute message is only evaluated by the below demo script and is optional.
Example:
# CAN Message: Kombi_01Vehicle.Speed:type:sensordatatype:floatdbc:message:Kombi_01signal:KBI_angez_Geschwinterval_ms:1000# CAN Message: FS_Position_01Vehicle.Cabin.Seat.Row1.Pos1.Position:type:sensordatatype:floatdbc:message:FS_Position_01signal:FSS_Laenge_Posinterval_ms:1000
These two extensions will be added to the combined VSS tree:
Regenerating VSpec
The script vspec2json.py from COVESA VSS Tools can then be used to merge the overlay file with the standard specification.
For Leda devices, you can use kanto-cm to run the tool as a container:
# Copy custom.dbc and custom.vspec to /home/root# Run in /home/rootkanto-cm create --name vspec2json --rp no --mp="/home/root:/data" ghcr.io/eclipse-leda/leda-vss-vspec2json:main
kanto-cm start --a --i --name vspec2json
For developer workstations, there is a convenient pre-built Docker container:
docker run --name vspec2json --rm -v `pwd`:/data ghcr.io/eclipse-leda/leda-vss-vspec2json:main
Or, if you want to run vspec2json from the sources, clone the repository and invoke it like this:
With the resulting file custom_vss_dbc.json and the corresponding DBC file, the dbc2val feeder can relay the signals to the databroker.
dbc2val can either read from a CAN-Dump file (generated by candump from can-utils) in an endless loop, or can listen on actual virtual or physical CAN interfaces.
The output should look like this:
$ ls
custom.dbc custom.vspec
$ docker run --name vspec2json --rm -v `pwd`:/data ghcr.io/eclipse-leda/leda-vss-vspec2json:main
INFO Output to json format
INFO Known extended attributes: dbc
INFO Added 54 units from /vss/spec/units.yaml
INFO Loading vspec from /vss/spec/VehicleSignalSpecification.vspec...
INFO Applying VSS overlay from /data/custom.vspec...
INFO Autocreating implicit branch Vehicle
INFO Autocreating implicit branch Cabin
INFO Autocreating implicit branch Seat
INFO Autocreating implicit branch Row1
INFO Autocreating implicit branch Pos1
INFO Calling exporter...
INFO Generating JSON output...
INFO Serializing pretty JSON...
INFO All done.
$ ls
custom.dbc custom.vspec custom_vss_dbc.json
Databroker Container
Ensure the databroker container is up and running:
On developer workstation:
docker run --name databroker --detach --rm -p 55555:55555/tcp ghcr.io/eclipse/kuksa.val/databroker:0.3.1
On Leda device (if not already running)
kanto-cm start --name databroker
Testing with data
To see actual data, we need to use the candump or another CAN source and feed that data into the databroker.
After that is running, we can use the databroker-cli tool to subscribe to the example VSS signals.
Generate a candump
To generate a candump for testing purposes, start the candump tool and listen for some packets.
In the following example, the first 20 CAN frames are being recorded and the command will exit.
candump -L -n 20 vcan0 > candump.log
If you do not have an external CAN source, you may want to simulate CAN frames.
There is a Python library for parsing DBC files, which also let’s you encode and send the actual CAN messages.
An example script could look like this:
Note: Due to GPL-3 licensing, the Leda quickstart image does not contain some Python standard libraries. This script will not run on a Leda quickstart image.
import random
import timefrom pprint import pprint
import yaml
import cantools
import can
can_bus= can.interface.Bus('vcan0', bustype='socketcan')db= cantools.database.load_file('custom.dbc')with open("custom.vspec", "r") as stream:
try:
vspec= yaml.safe_load(stream)for key in vspec:
message_name=vspec[key]['dbc']['message']signal_name=vspec[key]['dbc']['signal']example_message= db.get_message_by_name(message_name)# Initialize an empty messagedata={}for signal in example_message.signals:
data[signal.name]= False
pprint("Message: %s" % example_message)# Send 10 frames with random datafor x in range(10):
data[signal_name]= random.uniform(0,100)encoded_data= example_message.encode(data)message= can.Message(arbitration_id=example_message.frame_id, data=encoded_data) pprint("CAN Frame: %s" % message) can_bus.send(message)# Wait up to 1 second time.sleep(random.random()) except yaml.YAMLError as exc:
print(exc)
# CAN must be set up up front, e.g.# modprobe vcan# ip link add dev vcan0 type vcan# ip link set vcan0 upkuksa.val.feeders/dbc2val/dbcfeeder.py \
--canport vcan0 \
--use-socketcan \
--server-type kuksa_databroker \
--dbcfile /custom/custom.dbc \
--mapping /custom/custom_vss_dbc.json
dbc2val on Leda device
To run the dbc2val feeder on Leda, you can use kanto-cm (instead of docker) to create the respective containers.
Note: Due to Issue #73,
the container ghcr.io/eclipse/kuksa.val.feeders/dbc2val:v0.1.1 cannot be used with SocketCAN.
Please use a later release or build the container from the sources after fixing the bug.
Alternatively, use the candump file instead of SocketCAN.
Remove any existing dbc2val container:
kanto-cm remove --force --name dbc2val
Create the new container in Kanto Container Management:
Note: The host networking and privileged is used to allow the container access to the CAN sockets.
Start the container:
kanto-cm start --a --i --name dbc2val
Check the logs to verify container is running:
kanto-cm logs --name dbc2val
Querying via CLI
To be able to see the changes, you may want to use the Kuksa Databroker CLI:
docker run --rm -it --network host ghcr.io/eclipse/kuksa.val/databroker-cli:0.3.1
Now, depending on the way how the dbc2val feeder has been started (candump vs. socketcan), you will either already see data from the candump loop.
4.4 - CarSim
The CarSim example provides basic Vehicle Signals based on a physical model simulation and feeds them to the databroker.
Architecture Overview
Description
CarSim is a simple physical model implementation, based on the kinematic bicycle model.
It can be used as a mock implementation in development, testing and simulation scenarios.
It takes three external inputs:
accelerator position
brake position
steering wheel angle
It propagates the physical model in time with a pre-defined step interval (10ms), recalculates the acceleration components,
speed and position, and finally publishes the numeric values as standard VSS datapoints to the databroker.
To simulate the input from a human driver, the optional DriverSim component can be run in parallel.
DriverSim toggles between two different types of driver style in a pre-defined time interval:
Good driver - slowly accelerates and moves the steering angle accordingly and then slowly brakes.
Bad driver - accelerates hard (full throttle), moves the steering wheel randomly in both directions, brakes hard.
Background
Decoupled Design
CarSim and DriverSim only communicate through the databroker by using standardized Vehicle Signals.
Each component can be replaced individually at runtime, e.g. by more advanced or real implementations.
There is no need to adapt, recompile or redeploy any of the other applications.
This is important for decoupling and standardizing vehicle signals,
to enable future vehicle application platforms to evolve.
Loose coupling and standardizing of vehicle signal interfaces enable thirdparty applications to use signals
in higher-level applications or value-add services.
Both implementors (imagine separate organizations), can agree to use the Vehicle Signal Specification
to decouple the development lifecycle for vehicle applications and vehicle services. This decoupling approach
reduces the time and effort for proprietary design specifications processes tremendously.
Vehicle Signals
The CarSim application reads the following input signals from the databroker:
For local deployment without a cloud backend, deployment specifications for Eclipse Velocitas Vehicle Apps may be put directly onto the device.
Create a Kanto deployment specification for your vehicle app. You may copy one of the existing JSON files in /data/var/containers/manifests as a template
Copy the specification file to the device, e.g. scp -P 2222 myapp.json root@localhost:/data/var/containers/manifests/
Apply the specification: systemctl restart kanto-auto-deployer
To update an existing container when the configuration has changed, delete the container and restart kanto-auto-deployer:
Attention: The current implementation requires all fields to be present in the JSON, even if the values are not set or used. Do not remove any fields, as it may break the functionality.
In order to verify that the device and the cloud connector can successfully receive messages sent by the cloud backend, we will send a dummy message to the device.
First, let’s check that the cloud connection is active.
Login as root
Run sdv-health and check for the SDV Connectivity section:
sdv-health
Start watching the output of the cloud connector:
kantui
Select the cloud-connector container and press L to watch the logs
Note: When an unknown type of message is received, the cloud connector will log an error:
2022/04/13 16:04:41.911727 [agent] ERROR Handler returned error err="cannot deserialize cloud message: invalid character 'H' looking for beginning of value
Start watching on the MQTT message broker:
mosquitto_sub -h localhost -t '#' --pretty -v
Note: When a known type of message is received, the cloud connector will forward the message to the MQTT broker into the corresponding topic $appId/$cmdName
Sending a Device Message
Go to the Web Console of Azure IoT Hub
Select the device
Click on “Send Message”
Enter a C2D payload and click “Send”
Alternatively, on command line, use the Azure CLI client. Replace DeviceId and IotHubName with the appropriate names of your IoT Hub and device.
Vehicle.IsBrokenDown (Vehicle breakdown or any similar event causing vehicle to stop on the road, that might pose a risk to other road users. True = Vehicle broken down on the road, due to e.g. engine problems, flat tire, out of gas, brake problems. False = Vehicle not broken down.)
Vehicle.IsMoving (Indicates whether the vehicle is stationary or moving.)
Vehicle.PowerOptimizeLevel (Power optimization level for this branch/subsystem. A higher number indicates more aggressive power optimization. Level 0 indicates that all functionality is enabled, no power optimization enabled. Level 10 indicates most aggressive power optimization mode, only essential functionality enabled.)
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
The UUID for Vehicle.Connectivity is 89c267fccea35f3da9871cca2b4dc4df
Children
This vehicle signal is a branch or structure and thus has sub-pages:
Vehicle.Connectivity.IsConnectivityAvailable (Indicates if connectivity between vehicle and cloud is available. True = Connectivity is available. False = Connectivity is not available.)
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
Indicates if connectivity between vehicle and cloud is available. True = Connectivity is available. False = Connectivity is not available.
Comment:
This signal can be used by onboard vehicle services to decide what features that shall be offered to the driver, for example disable the ‘check for update’ button if vehicle does not have connectivity.
Navigation
flowchart LR
Vehicle-->Connectivity
Connectivity-->IsConnectivityAvailable
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Connectivity.IsConnectivityAvailable
[get] OK
Vehicle.Connectivity.IsConnectivityAvailable: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Connectivity.IsConnectivityAvailable false[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Connectivity.IsConnectivityAvailable is b6d11be2a6565996b68ffb07a96595a7
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Exterior.AirTemperature
[get] OK
Vehicle.Exterior.AirTemperature: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Exterior.AirTemperature 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Exterior.AirTemperature is a38d3f5dfeb35317aca8b90453dc1a75
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Exterior.Humidity
[get] OK
Vehicle.Exterior.Humidity: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Exterior.Humidity 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Exterior.Humidity is 6c785ec5d9a5534f98be7ce198d25d6b
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Exterior.LightIntensity
[get] OK
Vehicle.Exterior.LightIntensity: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Exterior.LightIntensity 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Exterior.LightIntensity is 9b46b70490f853e891e1cc35dd08dddc
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
Vehicle.Service.IsServiceDue (Indicates if vehicle needs service (of any kind). True = Service needed now or in the near future. False = No known need for service.)
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Service.DistanceToService
[get] OK
Vehicle.Service.DistanceToService: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Service.DistanceToService 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Service.DistanceToService is 6f4347ce149759819572c8c3a17e8d93
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Service.IsServiceDue
[get] OK
Vehicle.Service.IsServiceDue: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Service.IsServiceDue false[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Service.IsServiceDue is 3e28f85ccccd5702b9adbe9a761ea1b4
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Service.TimeToService
[get] OK
Vehicle.Service.TimeToService: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Service.TimeToService 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Service.TimeToService is c968be91a5685fa9ae30b84a0f91934e
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
Vehicle.Driver.DistractionLevel (Distraction level of the driver will be the level how much the driver is distracted, by multiple factors. E.g. Driving situation, acustical or optical signales inside the cockpit, phone calls.)
Vehicle.Driver.FatigueLevel (Fatigueness level of driver. Evaluated by multiple factors like trip time, behaviour of steering, eye status.)
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Driver.AttentiveProbability
[get] OK
Vehicle.Driver.AttentiveProbability: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Driver.AttentiveProbability 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Driver.AttentiveProbability is fcd202467afb533fbbf9e7da89cc1cee
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
The following is a list of VSS supported built-in datatypes:
Name
Type
Min
Max
uint8
unsigned 8-bit integer
0
255
int8
signed 8-bit integer
-128
127
uint16
unsigned 16-bit integer
0
65535
int16
signed 16-bit integer
-32768
32767
uint32
unsigned 32-bit integer
0
4294967295
int32
signed 32-bit integer
-2147483648
2147483647
uint64
unsigned 64-bit integer
0
2^64 - 1
int64
signed 64-bit integer
-2^63
2^63 - 1
boolean
boolean value
0/false
1/true
float
floating point number
-3.4e -38
3.4e 38
double
double precision floating point number
-1.7e -300
1.7e 300
string
character string
n/a
n/a
Min, max and default values defined in a Vehicle Signal Specification must be in the supported range of the data type.
5.1.4.2 - DistractionLevel
Full qualified VSS Path:
Vehicle.Driver.DistractionLevel
Description:
Distraction level of the driver will be the level how much the driver is distracted, by multiple factors. E.g. Driving situation, acustical or optical signales inside the cockpit, phone calls.
Navigation
flowchart LR
Vehicle-->Driver
Driver-->DistractionLevel
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Driver.DistractionLevel
[get] OK
Vehicle.Driver.DistractionLevel: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Driver.DistractionLevel 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Driver.DistractionLevel is cb35ec0b924e58979e1469146d65c3fa
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Driver.FatigueLevel
[get] OK
Vehicle.Driver.FatigueLevel: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Driver.FatigueLevel 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Driver.FatigueLevel is 49b1626295705a79ae20d8a270c48b6b
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Driver.HeartRate
[get] OK
Vehicle.Driver.HeartRate: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Driver.HeartRate 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Driver.HeartRate is d71516905f785c4da867a2f86e774d93
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Driver.IsEyesOnRoad
[get] OK
Vehicle.Driver.IsEyesOnRoad: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Driver.IsEyesOnRoad false[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Driver.IsEyesOnRoad is 625e5009f1145aa0b797ee6c335ca2fe
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Driver.Identifier.Issuer
[get] OK
Vehicle.Driver.Identifier.Issuer: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Driver.Identifier.Issuer Foo
[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Driver.Identifier.Issuer is ee7988d26d7156d2a030ecc506ea97e7
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.Driver.Identifier.Subject
[get] OK
Vehicle.Driver.Identifier.Subject: ( NotAvailable )sdv.databroker.v1 > set Vehicle.Driver.Identifier.Subject Foo
[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.Driver.Identifier.Subject is b41ec688af265f10824bc9635989ac55
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.AbsoluteLoad
[get] OK
Vehicle.OBD.AbsoluteLoad: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.AbsoluteLoad 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.AbsoluteLoad is b3dd889a42ce5de9a7904b7196ae325c
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.AcceleratorPositionD
[get] OK
Vehicle.OBD.AcceleratorPositionD: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.AcceleratorPositionD 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.AcceleratorPositionD is 7e63256081ac5a7b8a28a6fa3c2c2ff9
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.AcceleratorPositionE
[get] OK
Vehicle.OBD.AcceleratorPositionE: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.AcceleratorPositionE 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.AcceleratorPositionE is 4104e7fc25355e25b4522d233565d84b
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.AcceleratorPositionF
[get] OK
Vehicle.OBD.AcceleratorPositionF: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.AcceleratorPositionF 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.AcceleratorPositionF is 95f5c2a209a857ff930e2f8e32ac2d3f
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.AmbientAirTemperature
[get] OK
Vehicle.OBD.AmbientAirTemperature: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.AmbientAirTemperature 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.AmbientAirTemperature is 220a90f183c5583ea8b8b6454d774517
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.CommandedEquivalenceRatio
[get] OK
Vehicle.OBD.CommandedEquivalenceRatio: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.CommandedEquivalenceRatio 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.CommandedEquivalenceRatio is 104e39e816f65fa791d0afa24603292b
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.ControlModuleVoltage
[get] OK
Vehicle.OBD.ControlModuleVoltage: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.ControlModuleVoltage 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.ControlModuleVoltage is 59e072b932605ffc88a299c874d885c4
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.DriveCycleStatus.DTCCount
[get] OK
Vehicle.OBD.DriveCycleStatus.DTCCount: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.DriveCycleStatus.DTCCount 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.DriveCycleStatus.DTCCount is 312856f746ff560e8098c19196964d3b
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.DriveCycleStatus.IgnitionType
[get] OK
Vehicle.OBD.DriveCycleStatus.IgnitionType: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.DriveCycleStatus.IgnitionType Foo
[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.DriveCycleStatus.IgnitionType is 1aeb7b6d025f5a8693104824abaa1c49
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.DriveCycleStatus.IsMILOn
[get] OK
Vehicle.OBD.DriveCycleStatus.IsMILOn: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.DriveCycleStatus.IsMILOn false[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.DriveCycleStatus.IsMILOn is e367394c9a075eef8fd66499e3d9cf14
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.EthanolPercent
[get] OK
Vehicle.OBD.EthanolPercent: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.EthanolPercent 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.EthanolPercent is a207e7de17e1520c894b412af6f2522c
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.EVAPVaporPressureAbsolute
[get] OK
Vehicle.OBD.EVAPVaporPressureAbsolute: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.EVAPVaporPressureAbsolute 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.EVAPVaporPressureAbsolute is ef188a1e1a1356f7bc425081e3e00805
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community:
$ databroker-cli
sdv.databroker.v1 > connect
[connect] OK
sdv.databroker.v1 > get Vehicle.OBD.EVAPVaporPressureAlternate
[get] OK
Vehicle.OBD.EVAPVaporPressureAlternate: ( NotAvailable )sdv.databroker.v1 > set Vehicle.OBD.EVAPVaporPressureAlternate 0[set] OK
Digital Auto: Playground
playground.digital.auto provides an in-browser, rapid prototyping environment utilizing the COVESA APIs for connected vehicles.
The UUID for Vehicle.OBD.EVAPVaporPressureAlternate is 68eaba3c79975d61bc35b92cd3e5e8d0
Feedback
Do you think this Vehicle Signal specification needs enhancement? Do you want to discuss with experts? Try the following ressources to get in touch with the VSS community: