Port a ChibiOS based application to another platform

Port a ChibiOS based application to another platform

1 Intro

We already talked about ChibiOS/HAL design and its multiple architectures support. This is very important for regular developers: imagine a scenario in which you design an application using a certain MCU and after a first stage you decide to upgrade your application. Imagine also that hardware resources on the MCU you decided to use are not enough to make that upgrade. At that point you have to port application on another MCU and this could cost a big effort in terms of time/money.
If your application is ChibiOS based and you followed some guidelines already introduced in C Library design for embedded applications or HAL portability, the effort needed to port you application could be reduced.

2 Some clarifications

To make things simplest let’s do some clarifications:

  • When we say MCU or platform we are talking about the specific microcontroller, when we say board we are talking about the pcb containing, among other devices, the MCU; so STM32F303 is a MCU and STM32F3 Discovery is a board;
  • There is a big difference between architecture and family. ARM-Cortex M is an architecture, STM32 is a family; TIVA, SAM and STM32 have the same architecture but they belong to different families;
  • If ChibiOS/HAL supports a certain peripheral of a certain MCU it is not true that it supports the same peripheral for the whole family. This because substantially some peripherals could be different from MCU to MCU even if they are from the same family;

So, before to port our application ChibiOS based on a new platform we have to answer some questions. This will define what we need to do:

  • Is ChibiOS/RT or ChibiOS/NIL supporting our new MCU?
  • What peripherals is our application using? Is ChibiOS/HAL supporting these peripherals for the new considered platform?
  • There is an official demo for our board?

continue reading…

ChibiOS/HAL design: an object-oriented approach

ChibiOS/HAL design an object-oriented approach

1 HAL stands for Hardware Abstraction Layer

We already introduced ChibiOS/HAL in early tutorial Hello ChibiOS and we used it in almost every article ChibiOS related. We had often ignored its design or how it works, indeed read its documentation is all you need to use it. Anyway, this article is for those who want to go into detail and see how stuff works. Starting from ChibiOS 3.0, ChibiOS/HAL became essentially a separate product that is not rigidly attached to the OS and can be used on bare metal or in conjunction with any other RTOS.

ChibiOS/HAL aspires to provide a hardware abstraction allowing nevertheless a custom use of peripherals and, in our opinion, it fully reaches the goal. Talking with Giovanni Di Sirio, founder of ChibiOS project, HAL has undergone a lot of changes following community’s suggestions. After years of upgrades and bug fixes, it has reached a high level of stability, a good level of abstraction and moreover an excellent level of flexibility.
To pursue its goals, HAL has to:

  • Encapsulate the driver complexities, allowing, in any case, the hardware-dependent setup: this way, user can adapt the driver to his application purpose;
  • Provide an hardware-independent and constant high level API keeping the general application code as portable as possible;
  • Ensure an intrinsic optimization and provide also non-blocking API. This makes HAL eligible to be used in Real Time applications;
  • Be able to work as stand-alone in OS-less applications;
  • Support most common peripherals like:ADC, CAN, DAC, GPIO, ICU, PWM, SPI, TIM, UART, USB and many others.

2 Achieve abstraction using a layered architecture design

ChibiOS/HAL hierarchy
Fig.1 – A screenshot of the ChibiOS/HAL hierarchy.

HAL is organized in a multi-layered way, precisely it has two layer. We could imagine this architecture as a LEGO wall which we can directly approach only its top part. Indeed, since bricks are interconnected we can indirectly approach lower layers too.
While the first layer remains the same second (interfacing hardware) changes. This way API remains constant but driver works with different hardware. In order to understand well how this “lower block change” is performed lets see HAL hierarchy (Figure 1).
HAL higher layer is contained in folders include and src: the first contains header like adc.h, spi.h, hal.h, etc., the second source file like adc.c, spi.c, hal.c, etc.. The lower layer is contained under the folder ports and grouped for architecture in sub-folders: they represent what is called low-level driver.

continue reading…

C Library design for embedded applications: tips and hints

C Library design: tips and hints

1 Why a library

Write reusable code is one of the most powerful and time-saving thing that an embedded programmer should learn. Compose well-arranged libraries makes things easiest, especially when we want to add old code in a new project. Citing one of the most talented programmers I have ever met, “Well done code should be like a LEGO: must fit perfectly and without any effort”. So a good library should be quite abstract, with a simple hierarchy and should provide some well documented APIs.

Even if this is a generic embedded article, we will provide some concrete example.

2 Organizing hierarchy

When we want to include new header or source files to a project we need to edit makefile because compiler requires the list of source file to compile and list of folder in which look for headers. When we create a new library a good idea is create a file (typically .mk or .mak) that contains these lists. This file and their new entries are included in makefile, this way our file act like a piece of makefile.

Library hierarchy
Fig.1 – An example of a library hierarchy

This way if we add new headers or source files to our library we don’t need to re-edit main makefile. This method is also used in ChibiOS/HAL to connect higher level layer with hardware dependent low-level.

In what follows as example we will consider a simple library containing 2 header and 1 source file (Figure 1). File user.mk should contain two include directories and a source file.

There is a statement for the lib relative path, one for source files (USERSRC) and another for included directories (USERINC). Note that we need to include userlib folder since we need for userconf.h.
That file follows makefile syntax that could be found in GNU make documentation. Always remember that to continue a statement on the next line you need for a straight(\) and that TAB spaces are denied.

continue reading…