/freertos-teensy

FreeRTOS port with C++ std::thread support for ARM boards Teensy 3.5, 3.6, 4.0 and 4.1 (cortex-m4f and cortex-m7f)

Primary LanguageC

FreeRTOS Port for Teensy 3.5, 3.6, 4.0, 4.1

This is a basic port of FreeRTOS for the Teensy 3.5, Teensy 3.6, Teensy 4.0 and Teensy 4.1 boards.

Introduction

To make FreeRTOS work on the teensy boards I had to adjust the EventResponder class of the Teensy Arduino core library and optimized some minor parts. Therefore a custom platform setting is used (platform = https://github.com/tsandmann/platform-teensy). It uses a more recent compiler toolchain (e.g. to support C++20) and a slightly modified Arduino core library. The latter is needed because FreeRTOS needs some interrupt vectors that are also used by the Arduino core (SysTick and PendSV for EventResponder) to be set up for the RTOS. The modified core library supports these services by running them ontop of the RTOS.

Notice

Consider this as experimental code and work in progress. If it breaks, you get to keep both pieces.

Current Limitations

  • Updated libraries may cause some incompatibilities with the custom core library. More testing and documentation is needed before the custom core library change may be integrated in the official library.
  • This is a port of FreeRTOS to run its kernel on the Teensy boards. It does not include thread-safe peripheral drivers, thread-safe teensy libraries and so on! If you want to use peripherals (e.g. serial ports, I2C, SPI, etc.) from different tasks, you may have to synchronize the access. On the other hand C-library calls like malloc or free are thread-safe due to provided guards for newlib.
  • Documentation is very limited (including this readme).

PlatformIO Usage

  1. Install PlatformIO core as described here
  2. Clone this git repository: git clone https://github.com/tsandmann/freertos-teensy
  3. Open an example of the cloned repo, e.g. freertos-teensy/example/blink
  4. Select the correct project environment PlatformIO toolbar for your Teensy board, e.g. teensy41
  5. Build project: use Build button on the PlatformIO toolbar or shortcut (ctrl/cmd+alt+b)
  6. Upload firmware image
    • Connect USB cable to teensy board
    • Use Upload button on the PlatformIO toolbar or shortcut (ctrl/cmd+alt+t) and select "PlatformIO: Upload"
  7. Use a terminal program (e.g. minicom) to connect to the USB serial device
    • If you use minicom: goto Serial port setup settings and set Serial Device to your serial device (typically sth. like /dev/cu.usbmodemXXXXXXX or /dev/tty.usbmodemXXXXXXX)

Teensyduino Usage

There is a test version available which can be used with Teensyduino. If you want to try it out:

  1. Download the library here as a zip archive.
  2. In Teensyduino select "Sketch -> Include Library -> Add .ZIP Library" and specify the downloaded zip archive.
  3. Create a new sketch in Teensyduino, e.g. blink.ino.
  4. Copy the contents of main.cpp to it.
  5. Compile and upload the sketch as usual.

Currently there are the following limitations for Teensyduino projects:

  • There is no support for C++'s std::thread, std::jthread or Futures (custom compiler options for the library would be necessary which is currently not possible with arduino's IDE).
  • If the sketch (or any included library) uses the EventResponder class, the EventResponder::attachInterrupt() variant must not be used, otherwise FreeRTOS will stop working. An update of the Teenys core library is required to make this work (this Pull request needs to be merged for this).
  • For Teensy 4.x: To print useful stack traces (see void HardFault_HandlerC(unsigned int* hardfault_args) and _Unwind_Reason_Code trace_fcn(_Unwind_Context* ctx, void* depth)) in case of a crash or an exception, the code must be compiled by using the -fasynchronous-unwind-tables option to tell gcc to generate the needed unwind tables. Furthermore, an updated linker script is needed to put .ARM.exidx and .ARM.extab in the right place and some (startup) code to copy these tables into RAM. (libgcc's unwind code requires the unwind table at an address reachable by a 31-bit signed offset (+/- 0x3FFFFFFF) from executed instructions). To support call traces over C-library calls, newlib has to be compiled with -fasynchronous-unwind-tables option as well.
  • I haven't done much testing so far as I don't use Teensyduino for my projects.

Continuous Integration Tests

TBD