

PROJECT
We were recently contracted to develop firmware for a device designed to facilitate communication with cloud services via both cellular and satellite networks. This project leverages our expertise in embedded Linux, C++, and Python, ensuring robust and efficient performance. This communication device will ride along with many different types of vehicles, including cars, trucks, semis, and potentially even ships and aircrafts.
The device was responsible for communicating with cloud-based services and performing routine check-in requests with location-based information. Additionally, a service tech could log into the device by accessing a self-hosted website provided through a WIFI access point the device broadcasted.
In our project, we utilized C++ to manage communication with various hardware components, prioritizing efficiency and performance. C++ was chosen for its ability to provide low-level access to hardware and its efficient use of resources, which is crucial in embedded systems where performance and response times are critical. Such hardware included other embedded devices, modems for communication, satellite interfaces, GPS providers, and others.
We also utilized Python to address common high-level needs, such as hosting a website and managing communication through HTTPS. Python was selected for its simplicity and versatility, allowing us to quickly develop and deploy web-based interfaces and secure communication protocols. Communication from our Python app to our C++ app was handled through MQTT using Mosquitto.

Wrapping this all into Yocto, we built a custom firmware image for this embedded device that included all of the needs for this project.
CHALLENGES
Retry Loops
Some hardware can be a bit stubborn. We learned pretty quickly that we needed a method to ensure messages and commands passed to our C++ app could be repeated, idempotently, in the event an unexpected error occurs. For example, we need to send a message to the cloud application through satellite communication, but we could not communicate to a satellite. This message will need to be preserved and retried at a later time. Additionally, embedded systems just really need atomic message queues overall.
Python Library Dependencies
Python brings some great high-level programming features to low-level embedded devices, but keeping dependencies, some often built for specific architectures, in line with your Yocto project can be pretty fickle. We adopted a strategy called an “overlay”, which allowed us to overlay any and all files we needed into our Yocto file system when we built the final firmware image. This does not come without some drawbacks, however. Python’s pipenv library handles contained environments for dependencies, but maintains them with absolute file paths. Meaning, if one were to copy these pip-environments from one location to the other, they would cease to function. We solved this issue by installing our dependencies on our device in the proper location, then moving all files into our project overlay for their final home.