This project was implemented by Ioana CULIC (ioana_maria.culic@upb.ro), PhD candidate at the Politehnica University of Bucharest, and Alexandru VOCHESCU (alexandru.vochescu@stud.acs.upb.ro) as part of his bachelor thesis at the Politehnica University of Bucharest. All the contributions are open source and are part of the Tock project, available on github.
1. Context
When it comes to embedded devices applications, Real Time Operating Systems are widely used as support for running multiple concurrent applications on resource-constrained devices. However, most of the RTOSes available emphasise the efficient resource usage, while lackin in default security mechanisms such as fault isolation.
In this context, Tock OS comes as the first operating system for embedded devices that is developed with security in mind. Tock is described as “an embedded operating system designed for running multiple concurrent, mutually distrustful applications on low-memory and low-power microcontrollers”. Tock OS implements memory isolation through the MPU (Memory Protection Unit) already existent in the ARM Cortex-M devices. It is an open-source project developed by researchers at universities such as UC Berkeley, Stanford or MIT which is written in Rust, a secure-oriented programming language which relies on compile-time memory checking. Rust supports unsafe code snippets, where the compiler does not enforce memory safety.
Architecturally speaking, Tock OS is structured on three main layers (Figure 1):
Figure 1. The TockOS stack. (Source: https://github.com/tock/tock/blob/master/doc/tock-stack.png)
In order to extend the usage of this Operating System, we created support for a new board: the i.MX RT 1052 EVKB, which features an ARM Cortex-M7 processor with a 600 MHz frequency and up to 512 kB Tightly Coupled Memory.
2. Process overview - adding a new board to Tock OS
When we are talking about the code, the Tock OS project is structured in the following folders, which contain modules (that in Rust are called crates
In order to add support for a new board in Tock OS, we first have to make sure that the MCU architecture is supported by the OS by checking the arch component of the project. Otherwise, we need to port it first by creating a crate for the new architecture in the arch/ folder. After that, we need to create a new chip crate if the MCU is not supported yet (which was also the case for i.MX RT 1050 MCU). As the final step, we need to create a board crate which instantiates the modules implemented in the correspondent MCU crate. This component will also set the clock frequency for the peripherals used, load the applications from flash, and finally start the kernel loop (essentially starting the Operating System).
Last step in the process is to make the code available to use for other users, by creating a Pull Request on Tock OS github.
3. The porting process
The porting process takes place only in the Core Kernel part of the Operating System so the code can contain unsafe sections since it is fully trusted. However, the aim is to keep the unsafe snippets to minimum.
The first thing we had to do in the porting process, since Tock OS did not support the ARM Cortex-M7 architecture was to include it as a new module. However, since the ARM Cortex-M4 was already supported, we have created the ARM Cortex-M7 crate based on it, the only major difference being that M7 supports 16 MPU regions instead of 8 (which is the case for M4).
The next step is related to the chips/ component of the project, where the MCU-specific implementations are contained. Therefore, we started implementing a few of the core features of the board as different modules in the i.MX RT 1050 MCU crate such as:
The final stage of the process was to create a new crate in the boards/ folder where we instantiated the features implemented in the i.MX RT 1050 MCU crate. This crate functions as a start-up configuration file for the Tock Operating System.
4. The result
Through this process, we managed to create a working Tock OS instance on the i.MX RT 1052 EVKB board and created a pull request on Tock OS github in order to make the code be available for everyone to use. The functionalities implemented were tested using a simple C application in userspace, with which we interact through the serial line (using the Lpuart module) and through which we can turn the User LED on or off using the GPIO module (Figure 2), or print information from the accelerometer sensor (through the I2C module).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <timer.h>
#include <led.h>
#include <ninedof.h>
#include <console.h>
static bool ninedof = false;
int main(void) {
char c = 0;
char str[10];
int i = 0;
printf("What is your name?\r\n");
c = getch();
while (c != 13) {
str[i++] = c;
c = getch();
}
printf("Welcome %s!\r\n"
"Type \"o\" to turn led on, or \"f\" to turn led off!\r\n"
"Type \"s\" to print accelerometer data!\r\n"
"Press \"e\" to exit!\r\n", str);
while (1)
{
c = getch();
printf("You typed: %c!\r\n", c);
if (c == 'o')
led_on(0);
else if (c == 'f')
led_off(0);
else if (c == 's') {
ninedof = driver_exists(DRIVER_NUM_NINEDOF);
int ninedof_x = 0, ninedof_y = 0, ninedof_z = 0;
if (ninedof) {
ninedof_read_acceleration_sync(&ninedof_x, &ninedof_y, &ninedof_z);
printf("FXOS8700CQ: X: %d\r\n", ninedof_x);
printf("FXOS8700CQ: Y: %d\r\n", ninedof_y);
printf("FXOS8700CQ: Z: %d\r\n", ninedof_z);
}
}
else if (c == 'e')
break;
}
printf("Good\r\n");
delay_ms(1000);
printf("Bye!\r\n");
delay_ms(2000);
return 0;
}
Figure 2. LED on example.
In order to create a project using Tock OS for the i.MX RT 1052 EVKB, we need to clone the repositories for tock and libtock-c from GitHub. Afterwards, we compile an application for the userspace from the examples in libtock-c by going into the examples directory and running make in the folder of a project such as c_hello/. For the next step, we have to modify the APP variable in boards/imxrt1050-evkb/Makefile to point to the binary generated in the previous step.
Example:
APP=../../../libtock-c/examples/c_hello/build/cortex-m7/cortex-m7.tbf
After that, we run make program in the board’s folder.
In order to flash the application on the board, we need to use the MCUXpresso IDE and the SDK for the IMXRT1050 board. We import an SDK example such as Hello World in order to generate the hierarchy for the project. Next, we copy the app image from target/thumbv7em-none-eabi/debug/imxrt1050-evkb-app.axf to the Debug folder in MCU Expresso via drag and drop (Figure 3).
Figure 3. Importing the app image.
Afterwards, we modify the LinkServer in order to point to the Tock OS binary instead of pointing towards the hello_world example as depicted in figure 4.
Figure 4. Edit LinkServer.
Finally, we simply press debug in order to flash the application on the board and enjoy!
5. Future work
For the moment, we are working on the created pull request in order for it to be accepted and afterwards, we will work on exposing all the other functionalities such as SPI or Ethernet and we will enable cache for instructions and data. Furthermore, we are looking into porting the other boards in the i.MX RT family such as the i.MX RT 1060 EVKB.
When the Pull Request will be accepted, the board will appear as an experimental board supported by Tock OS, since not all features are implemented and the project is not thoroughly tested.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.