Tutorial: Adding FreeRTOS to where there is no FreeRTOS

FreeRTOS is pretty much everywhere because it is so simple and universal, and it runs from the smallest to the biggest systems. But it still might be that for the microcontroller device you have selected there is no example or SDK support for it from your vendor of choice. In that case: no problem: I show how you could easily add FreeRTOS plus many more goodies to it.

Binky on NXP LPC845-BRK Board

Binky on NXP LPC845-BRK Board

Outline

FreeRTOS requires only few resources, and I have it running in projects on microcontrollers with as less as 1 KByte RAM and 16 KByte FLASH. Of course more leg room is better. The advantage of FreeRTOS is that it is very generic and not really microcontroller specific, except the ‘port’ part. But that port part is generic for Cortex-M0/M0+, M4 o M7 too, so basically you only need a port for your architecture and your are ready to go. At the university we are using FreeRTOS in many projects, and to simplify things even further across all Cortex-M cores of all the different vendors you can imagine, we are using a ‘McuLib’ which includes a unified and extended FreeRTOS port to cover all the architectures we are using. This makes using FreeRTOS for us even easier and simpler, and that port is available as open source on GitHub.

In this tutorial I show how to add FreeRTOS to a ‘bare metal’ project using the NXP LPC845 and the Eclipse based NXP MCUXpresso IDE with the NXP MCUXpresso SDK. The process itself is generic too, so you could use that for your IDE of choice too.

Base project

First you need to have (of course) the bare metal project ready. I recommend to start with a working example where you can add FreeRTOS.

initial bare metal project

initial bare metal project

Adding McuLib

Next, add the McuLib. One easy way is to download the repository .zip file https://github.com/ErichStyger/McuOnEclipseLibrary.git.

McuLib Zip File

McuLib Zip File

One way would be using just FreeRTOS, but to keep things simple we just add the full library to the project (don’t worry: what is not used won’t add to the code/data size). What we need is that ‘lib’ folder from above zip. Copy that into the project root folder and rename it as ‘McuLib’ (we will use that folder name later on).

McuLib in the project

McuLib in the project

By default in Eclipse, added folders won’t be added to the build. So go to the folder properties and have it included into the build. The Eclipse Icon Decorator shall show that blue ‘c’.

Included into build

Included into build

Selecting FreeRTOS Port

The McuLib contains multiple FreeRTOS ports. The folder ‘McuLib\FreeRTOS\Source\portable\GCC\ARM_CM4F’ has the ports for Cortex-M0/M4/M7 in it.

Disable the other ports (Cortex-M33 and RISC-V): set the folder properties to ‘Exclude resource from Build’:

Other FreeRTOS ports excluded from Build

Other FreeRTOS ports excluded from Build

Configure the McuLib

The library uses a flexible way to configure it (see “Different Ways of Software Configuration“). The library comes with a default configuration header file. Copy the template header file into your sources folder and rename it:

copied and renamed template configuration

copied and renamed template configuration

This header file will configure the library, and for this we add it to the ‘-include’ gcc compiler option:

"${ProjDirPath}/source/IncludeMcuLibConfig.h"

Add this to the project settings for the compiler:

-include compiler setting

-include compiler setting

The same time we can tell the compiler about the where to find all the header files. An easy way is to copy the list below and paste it into the ‘Include Paths’ dialog:

../McuLib
../McuLib/config
../McuLib/config/fonts
../McuLib/fonts
../McuLib/src
../McuLib/FreeRTOS/Source/include
../McuLib/FreeRTOS/Source/portable/GCC/ARM_CM4F
../McuLib/SEGGER_RTT
../McuLib/SEGGER_Sysview
../McuLib/TraceRecorder/config
../McuLib/TraceRecorder/include
../McuLib/TraceRecorder/streamports/Jlink_RTT/include
../McuLib/HD44780
../McuLib/FatFS
../McuLib/FatFS/source
Pasted Include paths

Pasted Include paths

HardFault Handler

If your SDK comes with a hard fault handler: you can remove it as the McuLib comes with its own (and probably better) handler. Remove an existing handler otherwise you might face a linker error:

Remove existing hardfault handler

Remove existing hardfault handler

Optional: Disabling other Middleware

The McuLib comes with extra middleware like a GUI, FatFS or Trace libraries. If rebuilding the project that middleware gets recompiled too (but won’t add to the code size). If not used, the extra middleware folders can be deleted. Or what I recommend: simply exclude them from the build so they can be easily added later on if needed:

Disabled not needed middleware

Disabled not needed middleware

This completes the setup, and the project shall compile without errors.

Running FreeRTOS

Now it is time to test it and run a first FreeRTOS task. For this I initialize the middleware (needed in case I want to use things like FreeRTOS Trace), create a task and start the scheduler:

#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "LPC845.h"
#include "fsl_debug_console.h"

#include "McuRTOS.h" /* access to all FreeRTOS API functions */

static void MyTask(void *pv) { /* simple task */
  for(;;) {
    vTaskDelay(pdMS_TO_TICKS(100));
  }
}

int main(void) {
  	/* Init board hardware. */
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitBootPeripherals();
  	/* Init FSL debug console. */
    BOARD_InitDebugConsole();

    McuRTOS_Init(); /* initialize FreeRTOS middleware */
    if (xTaskCreate(  /* create task */
        MyTask,  /* pointer to the task */
        "App", /* task name for kernel awareness debugging */
        200/sizeof(StackType_t), /* task stack size */
        (void*)NULL, /* optional task startup argument */
        tskIDLE_PRIORITY+2,  /* initial priority */
        (TaskHandle_t*)NULL /* optional task handle to create */
      ) != pdPASS) {
       for(;;){} /* error! probably out of memory */
    }
    vTaskStartScheduler(); /* start RTOS scheduler */
    return 0 ;
}

Build and Debug:

Debugging with FreeRTOS

Debugging with FreeRTOS

Summary

Because FreeRTOS is very generic for ARM Cortex, it is possible to add it to any Cortex-M microcontroller. The McuLib includes an even more generic port plus it is implemented and configured to work with extra middleware like USB stacks, FatFS, RTT, SystemViewer or Percepio trace.

Happy FreeRTOSing 🙂

Links

2 thoughts on “Tutorial: Adding FreeRTOS to where there is no FreeRTOS

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.