This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

FreeRTOS 8.2.1 for the nRF51 SDK 8 - is the interrupt handling ok?

I just published my port of a new FreeRTOS operating system version for the nRF51x22 and the nRF51 SDK 8.x.x to github.com/.../freertos_nrf51, the README is copied below.

It seems to work without problems for me. I red everything I found in this forum about disabling interrupts, softdevices, sd_nvic_critical_region_enter() etc. but the interrupt code probably is not exactly what is should be. I would be grateful if someone more experienced with the softdevice interrupt handling had a look at the intergation (file port.c) and let me know is something should be changed.

Pertti


FreeRTOS (V8.2.1) port for the nRF51 MCUs using the GCC ARM Toolchain

This is a new port of the FreeRTOS (V8.2.1) for the Nordic Semiconductor nRF51x22 (Bluetooth LE and ANT+ chips with a ARM Cortex-M0 MCU). This works with the S110/S120/S130 softdevices in the nRF51_SDK_8.x.x.

Installation

Install both sourceforge.net/.../ and developer.nordicsemi.com/.../ under a same directory. Recursively merge the files in this repository with the directory ./FreeRTOSV8.2.1. This does not replace anything, it just adds two new directories under ./FreeRTOSV8.2.1/: the actual port and a demo app.

You need to have the GCC ARM Toolchain (arm-eabi-none-gcc, etc.) installed. Configure the path of the GCC ARM installation in the file nRF51_SDK_8/components/toolchain/gcc/Makefile.posix or nRF51_SDK_8/components/toolchain/gcc/Makefile.windows.

Run 'make' in the demo directory ./FreeRTOSV8.2.1/FreeRTOS/Demo/CORTEX_M0_nRF51_GCC. Install first the softdevice and then this application with whatever tools you are using with your nRF51 board.

The settings you may need to configure should be within the first ten lines of the Makefile. The Makefile reuses the current nRF_SDK_8 setup as much as possible to minimize duplicate files.

Description

This port.c is based on the FreeRTOS ARM_CM0 code. The main modification to that is the use of a nRF51 softdevice timer for the FreeRTOS SysTick. The port*_INTERRUPTS() cpsid/cpsie has been replaced with sd_nvic_critical_region_enter() / _exit() The interrupt handling port is probably not exactly what is should be with the softdevice, my experience ended here. This package contains a simple blinky demo based on an earlier FreeRTOS port from Shawn Nock [email protected] (thanks!).

The options in the FreeRTOSConfig.h have been set for a quite full FreeRTOS setup - useful for experimenting with how FreeRTOS works on the nRF51. The setup is optimized for the newer nRF51 chips with 32KB of RAM. Depending on the configuration, using FreeRTOS is likely to use 20 - 40 KB of flash memory and a few kilobytes of RAM. It can run in less than that by changing the FreeRTOSConfig.h and by excluding optional components of FreeRTOS in the Makefile and configuration.

The vApplicationIdleHook() is implemented to call sd_app_evt_wait() so the MCU goes to sleep when there is no code that needs to be running. This can be disabled e.g. by changing the configUSE_IDLE_HOOK to 0 in FreeRTOSConfig.h.

Including FreeRTOS in your own projects

This FreeRTOS port can be included in any application that uses a softdevice from the nRF51_SDK_8.

  • Take a look at the Makefile in the demo directory FreeRTOSV8.2.1/FreeRTOS/Demo/CORTEX_M0_nRF51_GCC. Merge all the lines that contain "freertos" to your own Makefile.
  • Copy the code from the demo nrf51_freertos.c file functions timers_init() and application_timers_start(). Merge those lines to your application's timers_init() and application_timers_start() functions in the file where the softdevice is initialized.
  • Add #include:s from the demo *.c files if needed to compile.
  • Copy the FreeRTOSConfig.h from the demo to your application. Configure and use FreeRTOS as needed in your application.
  • If you like to have your own hooks for handling FreeRTOS error conditions, copy and modify the functions from the end of the nrf51_freertos.c to your own project.

Testing status and feedback

This successfully compiled and linked with S110, S120 and S130 softdevices (just change the softdevice definition in the beginning of the Makefile) but so far it has been tested only with S110. Stack overflow checking in FreeRTOS did not work; I will look at that later (by default that feature is disabled in the FreeRTOSConfig.h).

I have a test running with a couple of FreeRTOS tasks and queues, multiple nRF timers, I2C peripherals and all this seems to work properly with Bluetooth LE connections. I just finished this port and test, many things have not been tested yet.

This has been developed in an OSX machine and it should run without modifications at least in Linux. Please let me know if any changes are needed to compile the demo in a Windows machine.

Please comment, ask questions, provide patches etc. This has been posted also as a user contributed port to the the FreeRTOS forum as instructed in www.freertos.org/RTOS-contributed-ports.html and FreeRTOS related questions can be discussed there.

  • Nice work Pertti! Did you get any second opinion from the Nordic people regarding the interrupt handling? (bump bump up the feed to the support team)

    We are about to port an existing FreeRTOS application to nRF, and using this port could be really helpful.

    // Henrik

  • There is an updated version in github. I managed to sort it out and the newer implementation seems to work reliably with FreeRTOS timers, BLE stack advertising/connected, relatively high BLE traffic and several peripherals.

    Also the stack overflow detection now works, I'm running it with about 5 kB heap memory + the stack/queues configured for the FreeRTOS tasks. I have used the port with both nRF_SDK_8 and nRF_SDK_9.

    Please try if it works for you and let me know it there are any problems.

  • I also tried this Pertti Kasanen's port. I used earlier 8.0.1 port but with both i have issues heavy interrupt load. I use Nordic spi_master.c and I just have FreeRTOS wrapper around it that signals semaphore when SPI transfer is done. It crashes randomly after thousands of SPI transfers. It looks that there is some race condition and when interrupt happens inside of small window, crash happens.

    Boths of the FreeRTOS pors use sd_nvic_critical_region_enter and exit calls that are internally using svc-call to softdevice. Interupt handlers use portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); macro that sets pendSVC flag to schedule context switch

    There is something odd because about similar drivers works without problems in STM32.

Related