What could FreeRTOS do next? Share your Ideas

Dear FreeRTOS Community,

The FreeRTOS team wants to hear your thoughts and ideas about new features you would like to see on our roadmap. Whether you’re a seasoned user or just starting out with FreeRTOS, we want to know what you need and want from our project.

Our roadmap is currently focused on delivering features like Functional Safety (IEC 61508), IPv6 Multicast, MQTTv5, and SMP improvements, along with our ongoing commitment to Long-Term Support (LTS) releases. We want to learn what other features are important to our community. Please share your suggestions in the comments below. These inputs will greatly help us in planning our future development roadmap.

Best Regards,
The FreeRTOS Team :wave:

1 Like

Memory management is always important, I think we had different mechanisms in the Kernel because people have different requirements that cannot be met by a single implementation.

I would be curious to see what you did though, I will take a look at your implementation.

Do you know the features of the 4 heaps we have? Like the one that does not allow freeing so that you can use it in safety certified environments that do not allow dynamic allocation at all?

1 Like

I have heard requests for Rust bindings for FreeRTOS, anybody here have an interest in that?

I’d like to see a “Tickless mode”. Ie. not just tickless idle, but an entirely tickless mode.

It would allow scheduling to be done to microsecond precision (no need for developers to use spinloops), as well as getting rid of the CPU hungry tick interrupt.

Implementation-wise it could be done by exposing xNextTaskUnblockTime (from tasks.c) to the port, which could use a hardware timer to call the ‘tick’ interrupt at only the exact times that will be necessary for task switches.

Looks like the code change would be fairly small too.

3 Likes

xNextTaskUnblockTime isn’t the time mark for the next scheduler point needed, as the Round Robin Scheduling may need earlier scheduling. It works for Tickless idle, as, by definition, at that point only the Idle task is ready, so the unblock time would be the next time the scheduler is needed.

Making the round robin period configurable, and then adding a way for the kernel to inform the port what the next “tick” the scheduler would be needed could move towards that ability.

Note, many processors don’t have a portable way to get an interrupt at an arbitary and changeable point in the future (and it needs to be changable, as the current task might block for a period shorter than the current next unblock time, so the next needed interrupt needs to be made shorter. Yes, a lot of processors have a way to do this, but will require choosing a processor specific hardware timer for this action, and that choice might well need to be application specific as to which timer the application doesn’t need for other choices.

By still measuring things in “ticks”, it allows processors/applications that can’t or don’t want to supply such a time still use the existing method, with perhaps a small optimization of not calling the FreeRTOS tick handler every tick, but just increment the system time and return, allowing a somewhat higher tick rate, or for systems that can do what you want, to define the “tick” to be very short, and delays are all specified in much bigger numbers. (and the tick type likely needing to be possible expanded to 64 bits).

The first step to being able to do that is to remove the built in assumption that Round Robin is based on every tick, so the tick can be made shorter and not clog the system.

In my mind, ideally Round Robin allocation should be configurable per task, or at least per priority level. It would also be great if it was based on actual CPU time given and not just that it was running when the tick interrupt occured. If you are using the performance counters, then that could be used to determine how much time it ACTUALLY got, and take into account time lost due to higher priority tasks interrupting it.

1 Like

I have frequently lobbied for an asynchronous “I/O model” that supports something similar to Windows’ I/O completion ports (there is also something similar on linux called urings). See for example here: Device Driver Model - suggestions - #6 by RAc

Very briefly, it is an architecture that allows several outstanding blocking waits to be associated with a pool of worker threads. Each worker thread can process any of the computations once unblocked. It is a fantastic tool to build very efficient multithreaded servers with a throttled max number of worker threads (usually the number of CPUs in a multi core system) without the disadvantages of the threads coupled with computations. Given that almost all blockings/suspensions in FreeRTOS reduce to queue waits, it would even be rather straightforward to implement. Would be one of my retirement projects if not tackled before ;-).

2 Likes

@RAc, does QueueSets not handle that capability. The Tasks in the pool wait on the QueueSet, and get notified which Queue (or Semaphore, since they are queues) has an action to perform.

No, the concepts are related (thanks for the pointer), but not identical. One subtle difference is that one can dynamically add objects to participate in the IOCP, another one that there is “fair scheduling,” meaning the position of an object in the list is not relevant for its scheduling (I am not too familiar with queue sets, but I believe that the OS also traverses the queue set list in a deterministic order like in WaitForMultipleObjects() which leads to a priorization). There are other differences too. I once wrote them uo for msdn, but the article is currently lost, let me try to locate it. Thanks for the input, though!

1 Like

This technology already exists with embOS-Ultra.

Please have a look here.

1 Like

Debugging and tuning are an issue to me.
I want a profiling tool as part of the operating system to avoid crashes due to bad (or insufficient) memory allocation. FreeRTOS, while it has the hooks, does not have the tools. Nor is it very good at telling me what’s going on.
so the wish list is:

  1. better profiling tools (timeline, task switching,etc)
  2. better memory management that I don’t have to do myself. I’d like to see one of the memory managers with a redirect to the base of memory. Normally, it uses standard memory, but with a size and location pointer, it can go elsewhere. I’d also like this to work with multiple managers, with the ability to pick which memory manager does “new”
  3. proper integration into C++ with new, etc. Not that FreeRTOS should be written in C++, but it should support it better.
  4. Alloc failed hook should give parameters, or have a pointer to how much was requested, and how short the allocation was.
  5. I’d like to see a documentation section on memory allocation, as to where a task gets memory, where “new” and PVMALLOC actually take memory, as well as some tools to let the programmer know what the statistics are. I’m talking simple pictures and the like. When there’s an error, most of the solutions are “oh, insufficient stack size, just increase it”.
  6. the operating system knows a lot of things, it should be able to tell me without me begging.
  7. a lot of your structures are deliberately hidden. That means that I can’t take a task block and decode it when writing my own tools. A solution would be to publish alternate definitions that I can cast the data (task blocks, etc), to, so I can write some of my own debugging tools.

A lot of these go down to “ease of use”.

2 Likes

For all architectures with separate stack for ISRs - ISR stack checking!
Needed for safe use of FreeRTOS!
For ARM MSP check for example:
https://github.com/DRNadler/FreeRTOS_helpers/blob/master/port_DRN.c

1 Like

Supported C++ wrappers for FreeRTOS API!
Too many of us are rolling are own limited versions…
C++ is widely used for embedded! Please!

Rust may be cool, but C++ is bread-and-butter

3 Likes

C++ wrappers

Every object in FreeRTOS requires a state, from a statically allocated task to semaphores and queues. Why do I need to code such states as global variables?

If your entities needs to hold a state through they entire life, then they are excellent candidates for a class.

Example:

class myLedTask : public osTask
{
private:
   // my private variables (state variables) here

public:
   myLedTask( /* task stuff ,*/ uint8_t led_number )
      : Task( /* task stuff here */ )
   {
      // initialize the led (hardware level)
   }

   // no destructor (I don't like dynamically allocated tasks/objects)

   void run()
   {
      // initialize some stuff (logical level)

      while( 1 )
      {
         // your task code here

         // Awesome!
      }
   }
};

void main()
{
   myLedTask led( /* task stuff ,*/ 1 );


   otherTask other( /* task stuff ,*/ led.get_handler() );
   // you can pass another task's handler to a task so that both
   // now are related (because of a semaphore or queue or so)
   // Get rid of global variables!

   os.add_task( led );
   os.add_task( other );

   // ...

   os.start();
}

With objects you can have kind of templates for your tasks (nothing related to C++ templates) so you can reuse them safely and easily.

Besides that, C++ has tons of non-OOP features that can help developing with this OS.

1 Like

@Xaveier,
You ask, why does FreeRTOS objects need to be globals, they don’t. They can be allocated on the heap.

One warning, your example code did:

void main()
{
   myLedTask led( /* task stuff ,*/ 1 );

This is VERY dangerous, as FreeRTOS (on many ports) reuses the stack for main as the ISR stack, so your “led” object will get overwritten by ISRs.

I find it generally works best to allocate my main object in “static” memory (objects allocated at startup outside of any function, or in a function with the static keyword so it is created from fixed memory the first time the function is called, as that avoid use of dynamic heap memory and all the out-of-memory error handling.

These do NOT need to be “global”, as they can be static and have access restricted to the file they are declared in, or to who has had an address of the object passed to them in a pointer/reference.

I have a C++ wrapper class that will use the FreeRTOS “static” allocation for objects whenever possible

1 Like

I’ve use wrappers for C++, possibly yours. I"ve stopped using them because the constructors were used in establishing the code. Not all programs follow that "set everything up with constructors (or allow for establishing tasks, etc before running the program, see ST micro setups). My programs establish everything programmatically and do not establish anything before the program runs. Indeed, I use main.c to initialize hardware, a bridge program to initialize known services (I2C, SPI, SERIAL and some displays), then go to a main setup task. Constructors are not used, and the same software is controlled by an include file which has a lot of conditional definitions. With that logic, constructors are not useful as everything is built during run time.

Curious:
is this documented anywhere in detail? Might be useful for others.
and WHY.

anyone have an answer to why tasks with the task as a member of a C++ class don’t seem to work well? Handles and such are ok, but the task function itself was a problem.

The problem with creating a class based task after the scheduler is started using a base class is that as soon as the base class is constructed, the task is created and ready to run, but the class that defines the code for it hasn’t been run yet, so the task “C” stub can’t call the virtual function defining the task. My classes currently work around this by making the new task lower in priority then the creating task (if possible) and fix the priority whe the task gets a chance to run. This works ok for an single processor or AMP setup, but not for SMP, so I am reworking it have tasks created after the scheduler to require a call to start the task, and the stub blocks if it was created with the scheduler running