Wearable devices represent just one area of the Internet of Things (IoT). Health- and fitness-oriented wearable devices tend to dominate this arena, but a range of form factors and devices provide everything from biometric measurements such as heart rate and perspiration levels to security information (Fig. 1). A number of these devices have displays that allow them to operate in a standalone fashion, and most have some type of wireless-communication support.
It’s possible to have a dedicated application run on bare metal. Though many of these compact devices use a microcontroller to provide low-power operation, having an operating system can make programming easier. It often helps improve performance, safety, and security, since the services provided by the operating system have been examined and optimized for a wider range of environments rather than a single application.
1. Wearable IoT devices can take advantage of a compact operating system since they typically include a wireless stack.
A plethora of operating systems (OSs) and real-time operating systems (RTOSs) are vying for developers’ eyes when it comes to this space, including a large number of commercial and open-source alternative—even when IoT is brought into the mix. The discussion these days goes beyond just connectivity (e.g., a wireless stack), and now includes the IoT communication stack that’s a superset. Features like security and over-the-air updates need to be integrated with the OS. That’s a lot of software to pack into a small space.
Today we take a closer look at Zephyr, which started as a derivative of Wind River’s Microkernel OS. Wind River Professional Services provides commercial support for Zephyr, something that many developers will want. In fact, this type of support is available from various sources for the other operating systems listed above—it’s why commercial operating systems are often a preferred choice for IoT applications.
What is Zephyr?
Zephyr is now an open-source project. The code is available under an Apache License 2.0.
Built on a unified kernel as of Zephyr 1.60, its architecture originally included a nanokernel (Fig. 2). The nanokernel version was designed for resource-constrained platforms using as little as 2 kB of code space. Additional functionality was provided by the microkernel version that required at least 50 kB of code space.
Zephyr shares a number of features with similar compact operating systems, including a single address space and no dynamic runtime support. The former is typically a limitation of the hardware, while the latter is a design choice because most devices address a fixed set of application features. Likewise, resources are fixed and defined at compile time or build time. This can reduce the memory footprint and boost performance. Systems typically have minimal run-time error checking, although Zephyr has an optional error-checking infrastructure for debugging a system during application development.
Part of the scalability of the unified kernel is the multi-threading services that can handle priority-based, non-preemptive threads as well as preemptive threads with an optional round-robin time-slicing scheduler. Interrupt-services support uses compile-time registration of interrupt handlers.
2. Zephyr’s original nanokernel/microkernel platform has been replaced by a single, unified kernel that can be configured to address resource-constrained environments targeted by the nanokernel. In addition, it’s able to provide all functionality originally found in the microkernel.
Zephyr provides the usual OS services such as dynamic memory allocation. The Inter-thread Synchronization Services support binary semaphores, counting semaphores, and mutex semaphores. The Inter-thread Data Passing Services uses basic message queues as well as enhanced message queues, and byte streams. And Power Management Services supports tickless idle. Applications can also take advantage of an advanced idling infrastructure, with the commensurate increase in code size.
So far, Zephyr looks a lot like a typical compact operating system, which happens to be the case. Things become more interesting moving up the stack.
Zephyr includes support for wireless stacks like Bluetooth and Wi-Fi as well as wired connections such as three- and five-wire serial ports. Zephyr also supports standard communication middleware like LoWPAN, and support for the Thread Group’s Thread is on the roadmap set by the Zephyr Project's Technical Steering Committee. By the way, the Linux Foundation supports Zephyr. Encryption and encrypted communication support is provided by TinyCrypt 2 and mbed’s mbedTLS stack.
The standard middleware part of Zephyr is what makes it interesting in an IoT context.
Static-Checking Open-Source Projects
I also wanted to mention Zephyr’s static-analysis aspect because that’s important when it comes to safety and security. Zephyr, like many projects, is written in C. C has many advantages, but it also lets a programmer shoot themselves in the foot, usually by accident.
Static analysis can find many of the bugs that C programmers unintentionally incorporate on a regular basis. Unfortunately, the typical C/C++ compiler doesn’t provide a static-analysis tool with the possible exception of basic lint checking.
There are a number of commercial static analysis tools on the market. A host of commercial C/C++ toolsets also include this support, such as MISRA C/C++ checking. One of the commercial solutions is from Coverity, part of Synopsys.
Zephyr is just one of many options for IoT developers who typically need to deal with resource-constrained platforms for applications like wearable devices.