ChibiOS Presenting ChibiOS - EPFL-MICRO-315/TPs-Wiki GitHub Wiki

⚠ wiki page used in TP3

ChibiOS

  • ChibiOS is an open source embedded development environment including ChibiOS/RT real-time microkernel and ChibiOS/HAL hardware abstraction layer (HAL)
  • These are the most important features of ChibiOS:
    • High performance: Execution efficiency is one of the main goals
    • Small size: Configurable feature set. Can run even on memory constrained microcontrollers
    • Fully static architecture: Data structures and threads can be statically allocated
    • Complete API: All common RTOS API features are supported
    • Complete set of drivers: GPIO, ADC, TIMER, PWM, SPI, I2C, I2S, CAN, USB, ETH, etc
    • Compatibility: Compatible with a large set of ARM's architecture based microcontrollers

Hardware abstraction layer (HAL) and drivers

  • The HAL is used to provide a full set of functionalities completely portable through the different MCUs supported by ChibiOS

  • Only the configuration of some peripherals is dependent on the platform, but all the functions are the same and keep the compatibility

  • code block 1 is an example of a configuration of a serial port on a STM32F4XX architecture :

    Code block 1

    static const SerialConfig sdcfg = {
        SERIAL_DEFAULT_BITRATE,
        0,
        USART_CR2_STOP1_BITS | USART_CR2_LINEN,
        0
    };
    
  • This configuration can vary depending on the MCUs used but all the functions using it will have the same declaration for all the MCUs supported

  • Only their internal implementation will be different

  • code block 2 is an example of some portable functions to use the serial port :

    Code block 2

    /* Activating and configuring the serial port SD1.*/
    sdStart(&SD1, &sdcfg);
    
    /* Using the peripheral through the standard API.*/
    sdWrite(&SD1, "Hello World!", 12);
    
    /* Delay in order to allow the transmission of the string.*/
    chThdSleepMilliseconds(50);
    
    /* De-activating SD1.*/
    sdStop(&SD1);
    

ChibiOS configuration

  • ChibiOS requires 3 header files for its configuration, there we can enable certain features via definitions:

    • chconf.h: ChibiOS/RT kernel configuration. e.g. RTOS API features, debug options and scheduling frequency
    • halconf.h: ChibiOS/HAL configuration. e.g. enable HAL subsystems
    • mcuconf.h: microcontroller configuration. e.g. enable peripherals and configure the system clock
  • The possibility to enable or disable some functionalities is used to ends up with the minimal code base after compilation

  • For example if we don't plan to use the PWM driver, then all the code of the PWM driver is removed from the compilation, thus the code can remain very small

  • For each peripheral we want to use, we need to enable the corresponding settings in these files

    • e.g: in the code provided for the EPuck2, HAL_USE_GPT and STM32_GPT_USE_TIM11 in the respective files halconf.h and mcuconf.h are is set to TRUE in order to let us use the Timer 11
    • 💡 GPT: General Purpose Timer
  • The same logic goes for all the drivers of ChibiOS

Board configuration

  • A configuration structure is needed for the pins definitions
  • In ChibiOS, it is called a board configuration
  • You will find in the folder epuck2_board some files :
    • board.c: contains functions called during the init of the system, we can fill if needed
    • board.h: configuration of the board (GPIOs, frequency of the connected clock, ...)
    • cfg/board.chcfg: File used to automatically generate the three others with ChibiOS tool, won't be used in the labs

Change EPuck2's default pin configuration

  • It is possible to manually change the default pin configuration (without ChibiOS's specific tool), for instance the e-puck2's LED1 default state
  • For this, open board.h and change the default level of LED1 to LOW
    • 💡 the pin on which the LED1 is connected must be first known

Threads

  • Every thread in ChibiOS has a working area
  • Working area:
    • a reserved memory zone used to store every variables the thread will use
    • acts exactly as a stack
    • having a stack for each thread is more secure and is required to do context (variables must not be changed by other threads)
    • must be big enough for the thread to work
      • ⚠ Otherwise errors will occur
  • ChibiOS creates at startup two special threads:
    • Main thread executing the int main(void) function and has a normal priority
    • Idle thread, called when no other thread is running (hence it has the lowest priority)

To define a thread, we must declare its working area and the thread itself

  • code block 3 is an example showing the declaration of a static thread (we won't talk about dynamic thread as it is a dangerous way to code):

    Code block 3

    static THD_WORKING_AREA(waMyThread, 128);
    static THD_FUNCTION(MyThread, arg) {
    
        chRegSetThreadName(__FUNCTION__);
        (void)arg;
    
        while(1){
            //do some stuff and sleep for 100ms
            chThdSleepMilliseconds(100);
        }
    }
    
  • 💡 The number 128 which tells the size in byte of the working area
  • Once declared, the thread must be instanciated (see code block 4):

    Code block 4

    chThdCreateStatic(waMyThread, sizeof(waMyThread), NORMALPRIO, MyThread, NULL);
    
  • The instanciation is to be called from another thread, like the main for example
  • 💡 NORMALPRIO indicates the priority of this thread
    • To increase or lower the priority, one must write NORMALPRIO + x
    • tune x to give more or less priority to this thread
  • 💡 The last argument (NULL) is an argument of our choice we can give to the thread when instanciated
  • 💡 A detailed explanation of multithreading in ChibiOS/RT at https://www.playembedded.org/blog/explanation-multithreading-chibios/