Mbed OS is an operating system for embedded devices developed by ARM. As it provides a very extensive, easy-to-use C++ API, it is very well suited towards rapid prototyping and development of embedded applications. We were first approached by a customer with a request to port Anjay to Mbed OS in late 2017.
One of the primary challenges was the Mbed OS build system, which aims to be completely automated, including the entire directory structure of a project. Only limited configurability is possible through simple JSON files, in lieu of more traditional build scripts as used by Make, Autotools or CMake. This makes building typical applications simpler, but was a problem for Anjay with its extensive compile-time configurability through CMake. We initially used elaborate
.mbedignore configurations to work around that, but Anjay 2.3 introduced official support for alternate build systems, making the whole process much simpler.
After getting the library itself to compile, the bulk of porting effort, as you may guess from reading the porting guide in Anjay documentation, was focused on getting the networking layer to work. Mbed OS’ networking layer is very easy to use directly from native projects, but did not match well to the socket abstraction used by Anjay, largely modeled after traditional BSD sockets.
Some of the challenges we faced at that phase were:
connect()call even on UDP sockets, this needed to be simulated with another abstraction layer.
getsockname(). It turned out that there is no 100% reliable fix or workaround to this issue, as many devices used with Mbed OS rely on network stacks implemented on external chips (e.g. cellular modems or WiFi controllers) that do not expose such functionality at all. We needed to make sure that Anjay can work without it.
Testing on multiple boards with different network interfaces was very important. At various development stages, we ran Anjay code on a NUCLEO-F429ZI board with an Ethernet port, a GR-LYCHEE with an external network stack on an ESP32 MCU acting as a WiFi controller, and an STM32L496G-DISCOVERY board interfacing with a Quectel BG96 cellular modem. On each of the boards we needed to address various limitations and problems of respective network interfaces, but in the end, almost no platform-specific code is necessary.
Once the Anjay library and its network stack was working, implementing the actual client functionality was quite simple – it was just a matter of putting calls to appropriate Mbed OS APIs for connected sensors etc. inside the Anjay data model object code skeletons. It is worth noting, though, that the Mbed OS port was one of the motivators for having a C++ mode in the Anjay Object stub generator, that can be used as follows:
./tools/lwm2m_object_registry.py --get-xml 3 | ./tools/anjay_codegen.py --c++ -i - -o device.cpp
The instruction above creates a C++ source file with all the boilerplate code necessary to implement - in this case - the LwM2M Device object, so that the developer only needs to focus on the actual logic and hardware integration.
We decided to base most of the functionality around the X-NUCLEO-IKS01A2 board, as we had it on hand in our lab, it works well with a variety of boards from ST Microelectronics, and it has a driver library readily available for Mbed OS.
Now we have published the Mbed OS integration and a sample client application as open source. They can be compiled and run using any of the environments supported by Mbed OS - Mbed Studio, Mbed Online Compiler or Mbed CLI. We hope that together with the new Try Anjay platform, it will help introduce many people to Anjay and the LwM2M protocol in general.