In the previous post we discussed what RIOT is, what it tries to be and who it is for. With this in mind we will focus in a more theoretical manner on some Software Architectural aspects of RIOT.
Architectural views
We’ve taken the architectural views of Rozanski and Wood. They describe 7 of them in their book Software Systems Architecture1. The 7 views are: context, functional, information, concurrency, development, deployment and operational.
1. Context view
The context view is relevant to this system, it describes the relations, dependencies and other interactions between its components. Because RIOT is developed by an international community, a view like this can bring new contributors up to speed more quickly. It doesn’t explain everything in detail however, but a developer can get the gist of how components in the software are related.
2. Functional view
In order to know what components do exactly, a functional view is needed. This view is also relevant to this system for the same reason as the context view. It is very beneficial to get new contributors up to speed but also for existing developers to refresh their knowledge and take design decisions.
3. Information view
The information view describes how information is stored, manipulated, managed and distributed. Although memory management is crucial for RIOT to keep the memory footprint as small as possible, this view is more about the management of information in the sense of data. Memory management to keep the memory footprint small is more part of the functional view, and managing data for installing and upgrading falls more under the operational view. Therefore the information view is not as relevant to this system.
4. Concurrency view
RIOT offers full multithreading and interprocess communication, so a concurrency view is somewhat relevant to the system. In order to prevent deadlock or corruption of information, having this view to describe how threads are coordinated and how variables are shared is useful.
5. Development view
The development view is definitely relevant to the system, it might even be the most relevant view. Since RIOT is developed by an international community, one where anyone can join, it is worthwhile to describe how the development process works. If not, everyone does it the way they think is best which can result in messy and unclear code.
6. Deployment view
When anyone can download and build the software it is very practical to describe for which environments the software was intended. If someone wants to run RIOT, it is useful to know which hardware you need and what third-party software to install, but this view is also valuable for developers. For them it is helpful to know what third-party software is available for them to work with and for what platforms they should develop. So for RIOT, having a deployment view is relevant.
7. Operational view
Because RIOT is under active development, upgrades are bound to happen. RIOT’s common use case is to be run on a multitude of different IoT devices, all of which need installation and software updates. And since many devices need over the air updates, describing how the software is supposed to be installed and upgraded will ease this process for the user. Upgrading is more complex than just installing because existing data and settings need to be considered. Considering these challenges, an operational view is valuable to have.
Architectural style
The main architectural style of RIOT is described as a microkernel architecture 2.
Such an architecture consists of two parts, namely the core and plug-in modules.
In RIOT’s case the core consists of the core
module and the plug-in modules are cpu
, boards
, drivers
, pkg
and sys
.
This style is very applicable to RIOT, because it requires the core to be the near-minimum amount of software to implement an operating system. Next to this it has multiple (almost) independent plug-in components to expand the functionality.
Development view
According to Chapter 20 of Software Systems Architecture1, the Development Viewpoint describes the architecture that supports the software development process. This concerns aspects like organizing the code in functional modules, standardization of design and test procedures and control over the build, test and release process.
The Development Viewpoint can be described using six concerns:
Module Organization
: organizing the code in functional modulesCommon Processing
: isolating a common process for reusability and configurabilityStandardization of Design
: using standardized design methods to assure maintainability and reliabilityStandardization of Testing
: implementing testing infrastructure and means to automate testsInstrumentation
: capability to provide logging informationCodeline Organization
: Ensuring overall maintainability and deployability by means of the previous concerns
While all six concerns apply to RIOT, two interesting ones will be highlighted.
The Module Organization
is described in RIOT’s documentation3, which shows that the code base is structured into five groups.
These groups and the actual modules in the code base, are listed below:
- The kernel (
core
) - Platform-specific code (
cpu
,boards
) - Device drivers (
drivers
) - Libraries and network code (
sys
,pkg
) - Applications for demonstrating features and for testing (
examples
,tests
)
The modules and their high-level dependencies are illustrated in the Figure3 below. An application will communicate with the hardware-independent modules, which in it turn communicate with the hardware-dependent modules. Finally, the hardware-dependent modules communicate with the actual hardware, thus creating a nice separation of dependencies irrespective of the hardware.
An example of the Instrumentation
concern can be found in core/include/debug.h
.
This globally available implementation can be used to print debug messages by setting #define ENABLE_DEBUG (1)
and using DEBUG("myMessage")
.
Note that a define is used to enable this functionality.
If the code used to provide debug information is contained within #ifdef ENABLE_DEBUG
and #endif
, it will not be compiled if ENABLE_DEBUG
is not defined.
This provides a flexible way to include debug output for development, but minimize the binary size of production code.
Run time view
The run time view will describe the interaction between different components of RIOT, the user and RIOT, the boot order and the dependencies.
Looking at the schematic below4, most of the modules defined before can be traced back.
Starting at the bottom, the hardware corresponds to the cpu
and board
modules.
The hardware interacts with 3 different parts, namely the core, network device drivers and the sensor and actuator drivers, via respectively CPU abstractions or peripheral APIs.
The core interacts via core APIs with potential libraries and the developed applications.
The network stacks are dependent on libraries and interact with the network device drivers and provide a socket to the applications.
Finally, the sensor and actuator drivers interact via a sensor/actuator abstraction layer (called SAUL) with the applications.
Since RIOT is an OS, in almost all cases the interaction with the user is via a user-defined application, that either starts automatically at boot or is called via the shell, or standard RIOT shell commands.
When developing an application, dependencies such as drivers or libraries can easily be included by adding them to the USEMODULE
or USEPKG
variable of the application’s Makefile.
The standard board can be specified in the Makefile, but might also be set in the make command.
The Figure5 below shows the boot procedure of RIOT. First the board is initialized (cpu, clock, peripherals and optionally on-board peripherals), after which the OS (idle thread and main thread) can be initialized. The main thread might also initiate more threads and add extra commands to the RIOT shell.
Deployment view
Based on Chapter 21 of Software System Architecture1, the Deployment Viewpoint is a description of the physical environment that this piece of software is designed to work in. To be more specific, the physical environment includes:
- the hardware or hosting environment
- the technical environment requirements each type of processing nodes has
- the runtime environment of the software
Concerns
In the following discussion, we will first provide a general idea of RIOT from a deployment viewpoint while considering these 7 concerns:
1. Runtime Platform Required
RIOT is an OS designed for IoT applications, where a computational node capable of running real-time application and wireless communication is required. It could be hosted on three types of computational nodes: IoT devices, open-access testbed hardware and the PC. The physical IoT devices act as its working environment. The open-access testbed hardware and the PC are mainly used as development and testing platforms for the IoT applications build with RIOT.
2. Specification and Quantity of Hardware or Hosting Required
RIOT supports a variety of typical IoT devices (8-bit, 16-bit and 32-bit micro controllers)6. The open-access testbed hardware is mainly referring to the service provided by IoT-LAB. The PC host should be a Linux/FreeBSD/OSX machine in order to run RIOT virtually as a process.
3. Third-Party Software Requirements
RIOT has a couple of software requirements to be able to build, flash and debug7:.
- Build-essentials: make, gcc(depending on board used)
- Native dependencies if running in a virtual environment: host dependent8
- OpenOCD, for debugging purposes
Furthermore developers can use supported libraries while developing an application. These libraries will automaticly be downloaded (and patched) at compile time.
4. Technology Compatibility
RIOT is compatible with the following hardware platforms9:
- ARM
- ATmega
- ESP
- MSP430
- MIPS
- native
- SmartFusion2
- RISC-V
5. Network Requirements
Considering RIOT is aimed at IoT devices it obviously requires networking capabilities. Depending on the type of application, an Internet connection or other networking technologies might be required like Bluetooth or LoRa. To accomodate this, the hardware should provide the necessary networking capabilities.
6. Network Capacity Required
RIOT is running as the OS and that implies it actually helps to coordinate network communications.
7. Physical Constraints
RIOT is mainly deployed on Embedded platforms and it is light-weighted due to limited storage. Also, power consumption is an important part of IoT applications.
Models
Runtime Platform Models
This is the core part of the deployment view. The following UML diagram illustrates the runtime platform models for RIOT.
Non-functional properties
According to Chapter 12 of Software Systems Architecture10 a non-functional property is a constraint on the manner in which the system implements and delivers its functionality.
An interesting non-functional property is related to the use of third-party software.
To make sure that all required tools for hardware-independent development and testing with RIOT are available, a lot are included in RIOT’s code base in dist/tools
.
This ensures that developers have all required tools at hand, and prevents the cumbersome process of finding, compiling, and installing them.
However, since the provided tools are snapshots and not updated regularly there might be issues with outdated or buggy versions of a tool.
Since RIOT is open-source and everyone can contribute, this can easily be solved by opening a Pull Request with the updated code of a tool.
-
Rozanski, Nick, and Eóin Woods. Software systems architecture: working with stakeholders using viewpoints and perspectives. Addison-Wesley, 2012. ↩ ↩2 ↩3
-
https://riot-os.github.io/riot-course/slides/03-riot-basics/#2 ↩
-
https://riot-os.github.io/riot-course/slides/03-riot-basics/#7 ↩
-
https://github.com/RIOT-OS/RIOT/wiki/Family:-native#dependencies ↩
-
Taylor, Richard N., Nenad Medvidovic, and Eric Dashofy. Software architecture: foundations, theory, and practice. John Wiley & Sons, 2009. ↩