Support for FreeRTOS

Status
Not open for further replies.

Bill Greiman

Well-known member
I was planning to drop support for my FreeRTOS library. I didn't realize how many people were using my old port. I should have known by looking at GitHub traffic.

Since there are so many users, I will upgrade to FreeRTOS V9, not just fix issues. Supporting an RTOS on Arduino is a challenge since it involves use of internal features that were not intended for use by libraries.

I have been looking at 2017 surveys of embedded developers and FreeRTOS is by far the most popular RTOS for new projects. It is even more popular than embedded Linux or "In House Solutions" for new projects.

FreeRTOS is three times more popular than the next RTOS, Micrium uC/OS-III. Micrium is not free. There is just no free popular alternative.

I am beginning to understand why FreeRTOS so popular. It's not technical superiority, I wouldn't have minded if Paul said that EventResponder prevents use of FreeRTOS. I haven't really supported the FreeRTOS port very well since, in my opinion, it is technically just OK.

I received an interesting email today from a user developing a medical device. This user is trying to get FDA approval for a medical device using my SdFat library. He needs to reduce risk as much as as possible because:

FDA approval requires that the device forever operate exactly as released, and any code change is a big issue.

Here is a quote from the FreeRTOS website:
Developed in partnership with the world's leading chip companies over a 12 year period, FreeRTOS is the market leading real time operating system (or RTOS), and the de-facto standard solution for microcontrollers and small microprocessors.

With millions of deployments in all market sectors, blue chip companies trust FreeRTOS because it is professionally developed, strictly quality controlled, robust, supported, free to use in commercial products without a requirement to expose proprietary source code, and has no IP infringement risk.

FreeRTOS has a great business message, it's about risk, they don't claim their product is fastest or has the best features.
FreeRTOS is downloaded every 260 seconds (on average).
FreeRTOS came top in class in the 2011, 2012, 2013, 2014 and 2015 EETimes embedded systems market surveys in two categories: The RTOS kernel currently being used, and the RTOS kernel being considered for the next project!
FreeRTOS offers lower project risks and a lower total cost of ownership than commercial alternatives because:

It is fully supported and documented.
Most people take products to market without ever contacting us, but with the complete peace of mind that they could opt to switch to a fully indemnified commercial license (with dedicated support) at any time.

I won't be able to support features that would improve I/O performance since that would require changes to the Arduino core. I can't see trying to get Paul to modify the Teensy core since my port will run on AVR, SAMD, SAM3X, STM32, and more, not just Teensy.

I can't make use of callbacks in SPI, Wire, or other core libraries. I look at FreeRTOS as a scheduler, not a true RTOS with a HAL.

I can provide the CMSIS-RTOS API since it is supported by FreeRTOS.
 
Last edited:
Which changes to the core are needed to improve the io performance ?

I will describe what needs to happen for an SPI DMA transfer.


If the SPI call is:

Code:
SPI.transfer(txBuffer, rxBuffer, count);

When the DMA transfer starts, transfer() must wait on a semaphore by calling:

Code:
xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait);

Where xTicksToWait is an infinite delay or maybe very large.

When the DMA transfer completes, this function must be called from the DMA done ISR to end the wait in transfer().

Code:
xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore);

You can't use the EventResponder since FreeRTOS uses SVCall, PendSV, and SysTick.

FreeRTOS thinks it has total control.


I am exploring FreeRTOS V9. I am amazed by FreeRTOS business skills. They have so many important partners.

If you do an IoT application you really need SSL/TLS to talk to the cloud. I looked at OpenSSL and it is huge and awful.

FreeRTOS has a deal with WolfSSL and it is supported "with an open source GPLv2 version or learn more about commercial license options".

WolfSSL is 20x smaller and more reliable than OpenSSL.

No small company or group of hobbyists can do stuff like the group of FreeRTOS partners.
 
You can't use the EventResponder since FreeRTOS uses SVCall, PendSV, and SysTick.

FreeRTOS thinks it has total control.

Oh, it's easy to give it total control. Just overwrite the Interrupt vectors. They are stored in RAM (Was my suggestion, years ago... :rolleyes: ) - the EventResponder will never be called. Ok, you have to add either the old version of yield(), or disable it completely ( void yield(){}; ), too. This works, at least at the moment. I can only hope there will be no additional hurdles in the future.

[offtopic]
The whole idea with the serial events for Arduino was a bad idea, from the beginning on. What now happens is, it gets more and more complicated and slower, adds more overhead, gets more complexity instead of removing it - which would be the better solution. It would break some old programs - yes. But the current extension breaks things, too. Some poeple forget that the serial events can be substituted by just one line of code, a simple if statement.[/offtopic] For multiple tasks, an rtos is the better solution.
 
Last edited:
Yes I overwrite the vectors. I was trying to say EventResponder is disabled so you can't use it to solve the problem of making the call look synchronous to the thread by using this call.

Code:
	bool transfer(const void *txBuffer, void *rxBuffer, size_t count,  EventResponderRef  event_responder);

People using FreeRTOS want to make what looks like a synchronous call and not use callbacks or EventResponder. They want their libraries to work on other Arduino systems like STM32duino which has a DMA transfer call. They want it to work with or without FreeRTOS.

I am not saying this very well, hope you understand.

yield() also is not supportable with FreeRTOS in the same way as on Arduino.
 
Hi Bill, hi Frank,
sorry to ask such a silly question:
but why would I need something like a realtime operating system on Teensy for?
Maybe you could point me to a link or a publication that would explain this to me.
Sorry for asking this offtopic question, but I would be really interested in some more information on that! I did a bit of googling, but most information starts to steep for me and skips the most basic question: why do I need FreeRTOS?

Just a link or a reference would be highly appreciated!

All the best,

Frank
 
Hi Bill, hi Frank,
sorry to ask such a silly question:
but why would I need something like a realtime operating system on Teensy for?
Maybe you could point me to a link or a publication that would explain this to me.
Sorry for asking this offtopic question, but I would be really interested in some more information on that! I did a bit of googling, but most information starts to steep for me and skips the most basic question: why do I need FreeRTOS?

Just a link or a reference would be highly appreciated!

All the best,

Frank

Start with this, then this, and, this.

Search for "when to use a rtos" with google. Use of an RTOS in embedded systems is very controversial so read several pro and con articles.

Here is a 398 page book about FreeRTOS. This shows an RTOS is a tool that takes time to master.
 
Last edited:
Bill, Thanks a lot for your links and info!
I will read and think more in order to really understand when and why and if I would need FreeRTOS for my projects.
You already cleared up one of my misunderstandings: an operating system like FreeRTOS does not make it easier and less complex to perform real time processing in the Teensy, but it can make it more efficient, if you are already deeply involved in embedded programming.
Thanks again!
All the best, Frank
 
Which changes to the core are needed to improve the io performance ?
I have a better answer to Frank's question.

I have ported the new FreeRTOS V9 to three Arduino architectures. As I expected, FreeRTOS is best as a scheduler so it is not worth mods to the Arduino core to improve I/O.

If you need threads, and part of a program requires extreme performance, either use "fast interrupts" outside the scheduler or custom interrupt code using the FreeRTOS scheduler. You might want to use a faster RTOS like ChibiOS/RT.

You can get fair speed with FreeRTOS if you need a thread to run quickly in response to an interrupt. Here is a context switch test program.

Code:
// Test to determine context switch time with a semaphore
// Connect a scope to pin 13
// Measure difference in time between first pulse with no context switch
// and second pulse started in ledControl and ended in ledOffTask.
// This is the time for the semaphore and a context switch.
#include <FreeRTOS.h>

#define LED_PIN 13
// Semaphore to trigger context switch
SemaphoreHandle_t xSemaphore;
//------------------------------------------------------------------------------
// high priority thread to set pin low
static void ledOffTask(void *pvParameters) {
  for (;;) {
    xSemaphoreTake(xSemaphore, portMAX_DELAY);
    digitalWrite(LED_PIN, LOW);
  }
}
//------------------------------------------------------------------------------
// lower priority thread to toggle LED and trigger thread 1
static void ledControl(void *pvParameters) {
  for (;;) {
    // first pulse to get time with no context switch
    digitalWrite(LED_PIN, HIGH);
    digitalWrite(LED_PIN, LOW);

    // start second pulse
    digitalWrite(LED_PIN, HIGH);

    // trigger context switch for task that ends pulse
    xSemaphoreGive(xSemaphore);

    // sleep until next tick
    vTaskDelay(1);
  }
}
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);

  // create high priority thread
  xTaskCreate(ledOffTask,
    "Task1",
    configMINIMAL_STACK_SIZE,
    NULL,
    tskIDLE_PRIORITY + 2,
    NULL);

  // create lower priority thread
  xTaskCreate(ledControl,
    "Task2",
    configMINIMAL_STACK_SIZE,
    NULL,
    tskIDLE_PRIORITY + 1,
    NULL);

  // create semaphore
  vSemaphoreCreateBinary(xSemaphore);

  // start FreeRTOS
  vTaskStartScheduler();

  // should never return
  Serial.println("Die");
  while(1);
}
//------------------------------------------------------------------------------
void loop() {
  // Not used - idle loop has a very small, configMINIMAL_STACK_SIZE, stack
  // loop must never block
}
Here is the result on a Teensy 3.6 at 180 MHz.
FreeRTOS.png
The context switch time is the difference in width of the two pulses (see the test code). It's about three microseconds, not extremely fast. The advantage is that after three microseconds the thread runs with interrupts enabled and can be preempted by a higher priority interrupt.

There are several reasons that FreeRTOS is slower than other RTOSs. FreeRTOS has lots of error checking options and hooks to make code more reliable. FreeRTOS is implemented with simple standard mechanisms, no tricks. FreeRTOS is easy to port but most users just use an existing port.

The advantage is that FreeRTOS implements a standard API on a huge number of architectures, see this list. There is lots of documentation, books, and examples. There are many programmers and consultants that have FreeRTOS experience.

There are faster RTOSs that are designed to support fast I/O with a HAL. Here is the same context switch test with ChibiOS/RT.

ChibiOS.png

ChibiOS/RT takes about 0.8 microsecond, more than three times as fast as FreeRTOS.

FreeRTOS is fast enough for many users. FreeRTOS is fine if you need a round-robin scheduler for a few threads with a 20 ms time slice. The overhead is 3 microseconds every 20 ms, far less than 0.1%. You still get preemptive priority scheduling with 3 microsecond response time for higher priority tasks.

I will post a new GitHub repository for FreeRTOS V9 soon. I need to finish details for Teensy 3.0 - 3.2 and do a port for SAMD Arduino boards.
 
Last edited:
Definitely looking forward to a port of a later version, especially under MIT licensing.

I'm willing to help as I can, though my only device is a Teensy-LC on order.
 
Status
Not open for further replies.
Back
Top