ChibiOS: Lightweight RTOS


In this article, I want to introduce and briefly describe a member of the real-time OS family - ChibiOS.

License


First of all, about licensing. ChibiOS is free RTOS and has several licensing options - GPL 3.0, GPL 3.0 with some exceptions when linking and a commercial license.
The driver code in most cases is licensed under Apache-2.0.
All licensing options can be found on the project website. The presented options should fully satisfy amateurs, as well as companies that do not want to pay for using this operating system.

Structure


The project is logically divided into several subsystems:
  • HAL layer with the implementation of drivers for various devices,
  • basic kernel functions for a specific architecture (interrupt service, context switching, etc.),
  • code of the kernel of the operating system itself.

In addition to everything, there are several add-ons on this whole thing.
ChibiOS itself is implemented in C and assembler but there are also wrappers for C ++.

Core


ChibiOS, like any other self-respecting RTOS, has a task scheduler with extrusion support and currently has two functioning options:
  • cooperative time sharing between tasks with one priority
  • Round-Robin task scheduling with the same priority indicating the time slice for the task

At this point, the scheduler options are set globally at compile time.
To switch context, the kernel scheduler uses a system counter, which is also used for virtual timers.
Naturally, any interruption can lead to a context switch if necessary.

In the current version of ChibiOS (2.x), the period of the system timer is fixed (at the assembly stage).
In a future version (3.0), developers plan to move on to the functioning of the kernel without periodic interruptions (tickless scheduler).

The kernel itself provides the basic elements of synchronization (mutex, semaphore), memory management (heap, mempool), a variety of queue management primitives (including mbox and events) and of course task management tools.
ChibiOS has the ability to create tasks both statically and dynamically.

Devices and architectures


A notable feature of ChibiOS is support for a fairly wide range of architectures.
Officially supported architectures: ARMv5-7 (LPC1x, LPC2x, STM32), STM8, PPC, MSP430, MegaAVR.
Of the unofficial ones, Mips32 (qemu, pic32mx), AVR32, Coldfire, and NiosII can be noted.
Of course, this list cannot compete with FreeRTOS, but from personal experience I will say that adding a new architecture is not as difficult as it might seem.

The basic set of drivers from HAL includes a fairly wide range of peripherals: ADC, CAN, DMA, TMR, I2C, I2S, ICU, GPIO, PWM, RTC, SPI, UART, USB. In general, almost all common components of modern SoC.
In HAL, there are several add-ons for the above components (USB ACM, MMC / SPI and others), which I would take outside this layer. But this, apparently, happened historically.

Little things


From the "goodies" you can distinguish the ability to connect uIP, lwIP and FATFS (implementation from a certain Mr. ChaN).
There is also a fairly convenient shell to use - a trifle, but nice.

The API of most subsystems is quite simple and readable (especially the kernel), although in some cases an example is indispensable.
Sometimes the API dependency of some drivers upsets the platform under which the driver was originally developed, but as I understand it, drivers are not the main priority of the OS and are developed artificially for the current task. Dense clusters of duplicate code come across in places.
It seems like it is planned to move the entire HAL to a separate repository. There is also a potential danger that in future versions of ChibiOS HAL will be rewritten in C ++.

Of the particularly weak points, I would note the configuration of the system with macros (a set of drivers, features of the functioning of subsystems, etc.). This complicates the support of out-of-tree projects when deleting or adding certain options to mainstream.

There are some design decisions that I don't like, but maybe it's a personal preference.

Example


And for starters there is a small example of system initialization and shell creation. The code is presented without comment intentionally.
#include "ch.h"
#include "hal.h"
#include "shell.h"
#include "chprintf.h"
static void oNotifySD1(GenericQueue *qp) {
  msg_t b;
  b = sdRequestDataI(&SD1);
  if (b != Q_EMPTY)
    sd_lld_putc(&SD1, b);
}
#define SHELL_WA_SIZE   THD_WA_SIZE(1024)
static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[]) {
  chprintf(chp, "ChibiOS test suite\n");
  TestThread(chp);
}
static const ShellCommand shCmds[] = {
  {"test",      cmd_test},
  {NULL, NULL}
};
static const ShellConfig shCfg = {
  (BaseSequentialStream *)&SD1,
  shCmds
};
int main(void) {
  Thread *sh = NULL;
  halInit();
  chSysInit();
  {
    const SerialConfig sc = {
      .sc_baud    = SERIAL_DEFAULT_BITRATE,
      .sc_rxirq   = EIC_IRQ_UART1_RX,
      .sc_port    = _UART1_BASE_ADDRESS
    };
    sdObjectInit(&SD1, NULL, oNotifySD1);
    sdStart(&SD1, &sc);
  }
  shellInit();
  for (;;) {
    if (!sh)
      sh = shellCreate(&shCfg, SHELL_WA_SIZE, NORMALPRIO);
    else if (chThdTerminated(sh)) {
      chThdRelease(sh);
      sh = NULL;
    }
    chThdSleepMilliseconds(1000);
}


I almost forgot to mention that the head and dictator of the project is Mr. Giovanni Di Sirio.
And of course the link to the site: ChibiOs .

Thanks for attention.

Also popular now: