Blocking on Multiple RTOS Objects

stackmaster wrote on Friday, June 21, 2019:

Regarding xQueueSelectFromSet, it is written:

NULL is returned if a call to xQueueSelectFromSet() times out. Otherwise xQueueSelectFromSet() returns the handle of the queue set member that is ready for reading, allowing the calling task to immediately call xQueueReceive() or xSemaphoreTake() (on a queue handle or semaphore handle respectively) with the guarantee that the operation will succeed

In the world of synchronization, there exists analogues to xQueueSelectFromSet on other OS’s. On Windows, it is WaitForMultipleObjects. On Linux , it is epoll. On FreeBSD/etc. , it is kqueue.

There has been quite a bit of discussion regarding the theoretically-correct model for mutliple-object synchronization, and what is more pratically correct. IMHO, of all of the synchronization frameworks, the Windows people found the “sweet spot”. In the context of this discussion, they made it so that if WaitForMultipleObjects returns true, the side-effect(s) of having successfully waited against a waitable object occurs, automatically, before WaitForMultipleObjects returns.

I would like to know how receptive the community would be toward tweaking xQueueSelectFromSet so that the semantics changed to be more inline with WaitForMultipleObjects.

I was hoping not to get into a lengthy discussion regarding the merits of why the auto-side effect model is better before hearing what others thought.

Regards, SM

rtel wrote on Friday, June 21, 2019:

I’m open to the idea, but for backward compatibility reasons I suggest
it be a different function rather than changing the semantics of the
existing implementation.

Also, this implementation is not that efficient, predominantly because
it was created when code size was a big concerns so it is built on top
of existing code without adding a lot of new code. My preference is to
use a model where all communication is sent through a single queue with
part of the data that is transmitted informing the receiver of the
nature (what the data is, where it came from, etc.) of the information -
in the same way that were there more than one queue the queue on which
data was received would inform the receiver of the nature of the
information.

stackmaster wrote on Saturday, June 22, 2019:

Richard,

After thinking about your model, one concludes that, indeed, a “wait for multiple sychronization primitives” function must be different from xQueueSelectFromSet.

I guess I should reveal, upfront, what I have in mind, to avoid design-creep.

I would like a “full complement” of synchronization primitives. Of course, FreeRTOS already has a surprisingly rich model for synchronization. Here, I am talking more about the waiting functions. These are the enhancments that I would make:

  1. Create a new function xWaitForOne that waits against a single synchronization object. This function would take a TickType_t to specify time-out.
  2. Create a new function xWaitForAny that waits against a multiple synchronization objects. This function would be able to wait for up to a #define specified number objects simultaneously. Microsoft calls their #define for this maximum MAXIMUM_WAIT_OBJECTS. This function would take a TickType_t to specify time-out.
  3. Make timer, event, semaphore, mutex, all waitable using xWaitForOne and xWaitForAny , using handles to such objects as arguments.
  4. My prefernce would have been to modify FreeRTOS’s existing timer primitive to make it possible to insert its handle into xWaitForOne and xWaitForAny, but I am not sure whether that is desirable or possible. There is also the issue of FreeRTOS’s timer’s callback function, but that pointer argument could be set to NULL under the new model.
  5. Coincidentally, in this thread, Richard Damon mentions that he has a C++ wrapper for FreeRTOS’s thread framework. When one clicks to see his code on github, it is clearly evident that he is heading in the same direction, as least for primitives.
  6. For my personal use, “full complement” would mean adding shared-memory, but I realize that this is probably asking too much.

stackmaster wrote on Monday, June 24, 2019:

I did not respond to your preference for the model that you described above. I did see your UDP example.

The xWaitForAny model seems to be fundamental, no? Don’t want to appear to be a Big OS bigot, but the ability to stash handles of Semaphore/etc. into some kind of array, and wait on just that (no data tagging), seems to be very useful.

heinbali01 wrote on Tuesday, June 25, 2019:

Stack Master, while working with FreeRTOS for 13+ years, I never felt any need for a unified call that waits for many objects.

The UDP example is indeed very useful. Mind you that the UDP library is now extended with many more protocols, like TCP, and it is now called FreeRTOS+TCP.
The principles are still the same: IP-task listens to a queue, and the messages (IPStackEvent_t) are simple and fixed-size. They are treated in a first-in first-out order.

    /* Message type that is sent to the IP-task. */
    struct
    {
        eIPEvent_t eEventType;
        void *pvData;
    } IPStackEvent_t;

The task that handles the network interface (EMAC), works with two interrupts (RX/TX), and it is called “the EMAC deferred interrupt handler task”. The ISR’s do a minimum: read and clear a status of the peripheral. The high-priority task will be woken up (vTaskNotifyGiveFromISR), and take care of receiving and sending Ethernet data.

Recently, Richard wrote a good an interesting text about semaphores and task-notify here. Don’t miss that.

When I have a complex task that works with many different objects ( queues, GPIO-status, TCP sockets, audio controllers, etc ), I will have it block in a simple call to ulTaskNotifyTake(). All other tasks and drivers know the task handle, and they can ask for it’s immediate attention by calling either xTaskNotifyGive() or vTaskNotifyGiveFromISR().

rtel wrote on Tuesday, June 25, 2019:

Perhaps the wrong link in that post?

stackmaster wrote on Tuesday, June 25, 2019:

Hein, Thanks for that link. Per Richard (Barry)'s reply, I noticed that the semaphore aspect was missing from the link. I think what the OP wanted in that discussion was perhaps a condition-variable. I’ve never used them myself, but I have seen others talking about them.

Regarding xWaitForAny, what about on “Big OS”? Haven’t you ever saw the need to wait on multiple objects in those Big OS’s?

heinbali01 wrote on Tuesday, June 25, 2019:

I noticed that the semaphore aspect was missing from the link.

Oops, sorry, I sent the wrong URL, should be when can we not use task notificatin as binary semaphore

Regarding xWaitForAny, what about on “Big OS”?

Wasn’t FreeRTOS an RTOS?

Haven’t you ever seen the need to wait on multiple objects in those Big OS’s?

Yes of course. When I write an application on Linux or Windows, I will use primitives like select() and semaphores much in the same way. There are all sorts of ways to treat devices (cq sockets) in asynchronous ways. I find select() and poll() very powerful on big OS’s.

stackmaster wrote on Tuesday, June 25, 2019:

As you know, many coders have wrapped epoll(), WaitForMultipleObjects() etc. in C or C++ such that they never see these functions in our day-to-day coding. This is true for mutiple Big OS’s in my case. My C++ application compiles to 1.8 MB on Linux/x86-32, and I use event loops in my source code very often, but I never use epoll() or kqueue() explicitly.

For several years, I watched FreeRTOS from the sideline’s thinking:
That’s a nice OS. Too bad my application will not fit into a $10US computer.
But today that is no longer true. There are many sub-$10US computers that can hold 1.8MB executables, and while some of them run Linux, many of them run FreeRTOS. Last week, I decided to look at FreeRTOS in more detail, and it occurred to me that, with some functions added, for my own situation, there is very little distinction between it and Big OS’s. If my app needs 43 threads running simultaneosly on an MCU with 8MB of RAM, no problem, whereas several years ago, it would have been a problem, because there was not enough RAM.

Because the memory is now available, and multi-threading has always been available, and most synchronization primitives are available; the lure of being able to do a simple re-compile against FreeRTOS without changing any of my “regular” C++ is code is very hard to ignore. My guess is that the same is true for other people who are thinking about porting large applications to “small” MCU’s running FreeRTOS.

richarddamon wrote on Tuesday, June 25, 2019:

While there is much similarity betseen an RTOS (especially a micro kernal like FreeRTOS) and a ‘Big OS’, there are also significant fundamental differences. A programmer who ignores these tends to write bad, if not broken code. One big difference is that with a ‘Big OS’, the OS has control of the machine, and parcels out access to the user programs, and those only have as much access as the OS gives them, and one of the key features is the OS is in control and is trying to protect one program from another. With an RTOS like FreeRTOS this is reversed. The program is in complete control over the machine, it owns it and controls it. The program gives the kernal usage of a few parts of it to get the services it needs. There is no fundamental concept of protecting the machine from the program.

One spot this distinction shows up is in the identities of the fundamental program units to each other. In FreeRTOS we have Tasks, that interact with each other through global variables and various syncronization primatives. For the ‘Big OS’, this is pretty much like the basic thread. But the Big OS adds to that Processes which are mostly isolated from each other, and these Processes are often grouped into Sessions, and these Sessions are well isolated from each other. People confusing these two sometimes ask how to kill a Task and clean up its resources, thinking of Processes, which FreeRTOS doesn’t have.

A second big spot where we see a difference is in I/O, in the Big OS, all I/O is provided by the OS and all communication needs to be done through well defined channels, it needs to be this way to protect differnet Processes and Sessions from each other. The OS needs to be in control. With FreeRTOS, it provides NO I/O, all I/O is provided by the user program, perhaps through standard library proceedures, but it is outside the kernel. This means there doesn’t need to be as uniform of an I/O interface, and the I/O drivers can be more customizable to the program needs.

If your larger application has built into it the concept that it is a unique Process from parts of the system, and that there are other parts running that are well isolated from it, then it may well NOT be suitable for conversion to something like FreeRTOS.

stackmaster wrote on Tuesday, June 25, 2019:

Valid points.

First, I imagined my main 1.8MB application running on FreeRTOS, useful in its own right in isolation on a 32-bit sub-$10US MCU. Then I imagined several companion applications, each on the order of 50KB, running alongside the main application. Bcause My Code Is Perfect And Never Ever Ever Crashes ® , I was planning to approach the “no-processes” issue by simply lumping all the applications together into one image.

However, certainly I am not the first person to think about adding a mechanism for processes and dynamic loading. For an MCU with 8MB of flash and 4MB RAM, the idea of dynamic loading, both in the terms of reading into RAM on command a new process, as well as run-time binding of symbols, is very attractive. But that is certainly not necessary to get the benefit of multiple “programs” running simultaneously.

This is what lead me to my original post. FreeRTOS already provides so much of what my apps use on Big OS, I asked what else would be needed to provide a pain-free port, and it was xWaitForAny and xWaitForOne. If I could get C++'s RTTI, exception handling, and static initialization, (shared memory would be nice, but easily faked); I would be able to make a no-change port of an application that currently runs happily on a 16-core Xeon onto sub-$10 MCU’s.

This is the allure: to be able to compile the same C++ code base for a $5000 machine vs $5 machine with essentially no changes to source or configuration changes other than editing a 8 or 9 .INI files to inform the applications that they are now running in only 4MB of RAM. Or, if I use FreeRTOS to determine total available RAM at start-up, then the only porting issues, aside from the above, is use of certain hardware-acceleration primitives (AES) that are different on the MCU’s and would have been necessary anyway.

tlafleur wrote on Tuesday, June 25, 2019:

This should get added to the FreeRTOS users guide…

~~ _/) _/) _/) ``` _/) ~~

Tom Lafleur

On Jun 25, 2019, at 6:57 AM, Richard Damon richarddamon@users.sourceforge.net wrote:

While there is much similarity betseen an RTOS (especially a micro kernal like FreeRTOS) and a ‘Big OS’, there are also significant fundamental differences. A programmer who ignores these tends to write bad, if not broken code. One big difference is that with a ‘Big OS’, the OS has control of the machine, and parcels out access to the user programs, and those only have as much access as the OS gives them, and one of the key features is the OS is in control and is trying to protect one program from another. With an RTOS like FreeRTOS this is reversed. The program is in complete control over the machine, it owns it and controls it. The program gives the kernal usage of a few parts of it to get the services it needs. There is no fundamental concept of protecting the machine from the program.

One spot this distinction shows up is in the identities of the fundamental program units to each other. In FreeRTOS we have Tasks, that interact with each other through global variables and various syncronization primatives. For the ‘Big OS’, this is pretty much like the basic thread. But the Big OS adds to that Processes which are mostly isolated from each other, and these Processes are often grouped into Sessions, and these Sessions are well isolated from each other. People confusing these two sometimes ask how to kill a Task and clean up its resources, thinking of Processes, which FreeRTOS doesn’t have.

A second big spot where we see a difference is in I/O, in the Big OS, all I/O is provided by the OS and all communication needs to be done through well defined channels, it needs to be this way to protect differnet Processes and Sessions from each other. The OS needs to be in control. With FreeRTOS, it provides NO I/O, all I/O is provided by the user program, perhaps through standard library proceedures, but it is outside the kernel. This means there doesn’t need to be as uniform of an I/O interface, and the I/O drivers can be more customizable to the program needs.

If your larger application has built into it the concept that it is a unique Process from parts of the system, and that there are other parts running that are well isolated from it, then it may well NOT be suitable for conversion to something like FreeRTOS.

Blocking on Multiple RTOS Objects

Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/freertos/discussion/382005/

To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

richarddamon wrote on Wednesday, June 26, 2019:

The big issue is it sounds like you somewhere are assuming the process model (even if not needing it for crash protection). FreeRTOS by its nature doesn’t really support the concept of independant processes, as fundamentally the whole application is built into a single process. I say this because I do get C++'s RTTI, exception handling and static initalization in my FreeRTOS apps. Now static initialization all occurs by the spec before the start of the application main (which is before FreeRTOS starts) and not at the begining of some Task (as a task is not a process). Tasks also need to keep track of the resources they use and release those that need to be before terminating, as they aren’t Processes (so you don’t get the automatic cleanup of a process). In FreeRTOS you terminate the ‘Process’ by rebooting or turning off the system.

Shared memory doesn’t need to be ‘faked’ as ALL memory is shared, unless you specifically make you task a restricted task (and then you just need to map the shared memory into one of the accessable segments). This is in part because FreeRTOS only supports MPUs not MMU (or more accurately, treats processors with MMUs as if they just had an MPU).

stackmaster wrote on Wednesday, June 26, 2019:

Oh no, not assuming anything at all. I do understand all of that.

I was approaching my problem from a practical perspective. I was thinking about what steps would minimize a porting effort from Big OS to FreeRTOS onto these devices. Without xWaitForAny , my code would have to change. With a few more functions, my code would not have to change.

I mentioned the process issue while thinking about other programmers. If one takes an 8MB/4BM Flash/RAM MCU, that is clearly permits a different operating model than 32KB/4KB MCU. While it would be inappropriate to insist on adding a process model to FreeRTOS, one cannot blame some programmers for making the observation that 8MB/4MB is enough to provide sophisticated “Big Os” features. Naturally, any features added would have to be done in such a way so as not to interfere with extant FreeRTOS model.

Dynamic-linking, which I am not proposing, but someone else wanted, would suddenly make sense. One can imagine that “system” DLL’s have been partititioned into an orthogonal baiss set, so that synchro primitives might be in one DLL, security in another, strings in another, network I/O in another, whatever.

Then, even though no MMU features would be active, because, as I said, We All Write Perfect Code ®, one would have a situation where it would be possible to publish compiled software to run on sub-$10US devices. And that would permit the ultimate laziness:

I would compile my 10 or so Big OS apps for my MCU of choice with 8MB/4MB. Then I would drag and drop apps to and from my Windows 7 machine to my MCU, mixing and matching ad-hoc, over the Internet, without rebuilding the OS. And I would induce the MCU to run which ever app I specify. I would also receive published binary from third parties, servers of various sorts, like an SSH-like server, for example.

richarddamon wrote on Wednesday, June 26, 2019:

First big comment, With FreeRTOS there is no ‘rebuilding the OS’, there is just loading your program, and that is where there seems to be the fundamental disconnect in the model. With a ‘Big OS’ system, the OS owns the system and pulls in programs and various processes. This is the nature of that sort of machine.

With FreeRTOS, you load your program into the machine that uses FreeRTOS as a library as part of the program. FreeRTOS doesn’t run your program, your program runs FreeRTOS (your application starts first, and sets up FreeRTOS and lets FreeRTOS control aspects of the application)

Your vision seems to be to have some sort of Master Control Program that builds up an app from pieces, that MCP is NOT FreeRTOS, but could perhaps be a FreeRTOS based app that is able to assemble/download an app from some source. I am not sure how you envision this ‘combining’ of your multiple apps into a single unified app, that share a run time library with FreeRTOS without a compiling step (or at least a linking step).

stackmaster wrote on Wednesday, June 26, 2019:

No disconnect. I am aware of the current FreeRTOS model. You are speaking about what is. I am speaking about what could be.

First, there are two distinct topics here.

One is xWaitForAny/xWaitForOne, which, if existed, would go a long way to getting me, personally, what I want, with no other change at all.

The other is that, for MCU’s with a sufficient amount of Flash/RAM, it is possible for FreeRTOS to more to have Big OS features.

One could start with the smallest notion of what constitutes an OS, and start adding features to this smallest notion. One might ask if the OS is multitasking. One might ask if there is hardware-enforced memory protection. One might ask if there is demand-paging. One might asks there is a distinction between user-mode/kernel-mode, and if so, whether user-mode code can gain acess to i/O registers. One might ask if it provides real-time support, etc;

As one adds features to the hypothetical OS, the size of the code will grow, naturally. No one tool fits all situations, and so, OS’s will sometimes have a particular purpose, and certain features will be excluded, and some included. FreeRTOS has obviously been a fanstastic OS over the years and has served its purpose well for its chosen feature-set.

If, it is predicated that FreeRTOS is only to be run on low foot-print MCU’s, and that any change that causes it to grow in size and or complexity is not permitted, then, well, there would be nothing to discuss, because the predication would mean that no non-sanctioned feature would be allowed, no matter how much flash/RAM is available.

But if one discovers, by coincidence, that FreeRTOS currently runs on MCU’s that have near-Big-OS Flash/RAM, it is natural to ask what would happpen if FreeRTOS were modified to become a Big-Little-OS on these devices. By “modified”, I do not mean to say that it is changed fundamentally. I mean modified in the same spirit of a la carte pick-and-choose that currently exists.

Another way to look at it is to imagine starting a new project to write preemptive multitasking OS from scratch, specifically targeted at sub-$10 MCU’s that have at least 4MB of Flash and 4BM of RAM. One will go through the usual (arduous) decision-making process of deciding what features should be included, size/performance trade-offs, abstraction barriers for hardware, etc. When one is finished, one will have a hypothetical OS.

IMO, FreeRTOS (Richard), has done such a good job of being a “Little OS”, that this little OS is not so far from a Big OS in features for system-level “user-mode” coding. So if one were to write a new hypothetical “Mid-Size” OS that is not big, but capable of running Big Programs under a model that Big OS’s have done for decades; would one rewrite the hypothetical OS from scratch? Of course not. When you have something that is already 95%+ of where you want to be, you don’t start from scratch. You use what’s there, or at least try.

The question then becomes:

How wide is the gap between what exists and what you want?

FreeRTOS is 95%+ (at least) of what I would want if I needed a “Little OS” that was capable of runing my Big Apps on sub-$10 devices in a manner that is currently done on Big OS’s. No, my apps would not run on an 64K/4K machine, but I’m OK with that.

There are quite a few people who would be quite intrigued by being able to plop a distinct, compiled binary onto a running FreeRTOS MCU and have it execute in a manner that is currently done on Big OS’s. It would be a sweet spot between less capable RTOS’s and Linux/Windows Embedded. I see opportunity here.

richarddamon wrote on Wednesday, June 26, 2019:

I thin you miss the key property of a micro kernal, which is what FreeRTOS is. FreeRTOS is focused on being a small basic very portable tool for building applications. Many of the features you are asking about don’t belong in the micro kernal.

Let us compare this to your Big OS type system, most of these have a kernal with in them, but they are bigger than the kernal. Let us take a Linux system, and suppose we have a machine with JUST the kernal (and a few minimal drivers) installed. It boots, loads itself, and then effectively dies, as the kernal itself isn’t very usable. The kernal needs to start up a shell of some sort for the user to interact with. In the same way, FreeRTOS needs an application to run to do anything useful, but it doesn’t come with one built in, because there is no one most likely model for what it should be. Much oof what you talk about desiring for FreeRTOS to grow with is the domain of such a shell, not the kernal. I suspect that if you tried to build such a shell around FreeRTOS, you would find that there are many different ways to structure it, each with different abilities and limitations, and that no one structure is clearly best for the broad range of uses. Also, to really use the shell concept, you want the concept of a Process, so when you finish one task the system cleans itself up, but that level of tracking isn’t built into FreeRTOS as it is too expensive and not needed for most of its applications. It could be added in the shell/executive though.

stackmaster wrote on Wednesday, June 26, 2019:

Again, you are speaking about what is, and I am speaking about what could be. :slight_smile:

You are 100% right that FreeRTOS is currently structured a certain way because of original intent. Yet, if I had more time, I would make specific, deliberate modifications to that structure to realize something that a lot of engineers would find useful. That would be possible because FreeRTOS (Richard) has done an excellent job of keeping features orthogonal. By contrast, if AIX could run 8MB/4MB MCU, I would not be interested, because, despite being a “Big OS” with purportedly every tool under the Sun, AIX is functionally deficient in the area of sychronization, and there is no hope of enhancing it the way the Linux and FreeBSD have done to their OS’s.

FreeRTOS, with modifications, has the potential to fill a “hole” in the OS market that no OS that I know of has currently filled.

Barebones QNX/Windows Embedded are too big. There are a bunch of “weird” OS’s like TinyOS that reveal their weirdness (insufficiency for generalized purposes) almost immediately upon reading documentation. uCOS appears to have done a reasonable job heading toward a “regular set” of synchro primitives, but like FreeRTOS, it stops short of being able to wait, simultaneously, on multiple types of objects which, again, is what I want, and what I believe is an essential ingredient in the regular model for systems programming. The Linux and Illumos (Solaris) people eventually provided a primitive in this spirit, (eventfd), for multiple-object waiting which is sorta/kinda/mostly correct, but these OS’s, again, are too big. The FreeBSD people swear by kqueue, but not only does it not allow named waitable timers, to my knowledge, there is no wizardry that can be done to circumvent this “deficiency”. If there is, I’d certainly like to know about it.

So one goes back to FreeRTOS, and though, say xTimerCreate does not use its pcTimerName argument in the same way that CreateWaitableTimer uses its lpTimerName argument, the argument is still there, and being present at all is a great convenience if one is to move in a direction of fully-generalized sychronization primitives.

Taking all this into consideration, one might conclude that FreeRTOS, a tiny OS, has a more correct sychronization-primitive model than AIX, an obviously much bigger OS. This is the appeal: If there be such a thing as a regular set of syncrhonization primitives, FreeRTOS is closer to that model than AIX, IMO.

This presumes, of course, that one has good intuition about what constitutes a “fully-generalized” set of synchronization primitives, and that there is concensus on what that set is. I’m claiming that Microsoft figured out what that set was, and “closure” of that set in FreeRTOS would be realized by creating xWaitForOne and xWaitForAny. Primitives beyond this basic set (fast “user-mode” spinlocks) then fall in the nice-to-have category, IMO.

These primitives are best implemented in the kernel, as you know.

The process-model, dynamica loading, etc. features…those are answers to a questions that a question that an OS theorist might ask:

What features might be added to FreeRTOS to make it a full-generalized OS without significantly increasing its size or complexity? What is a fully-generalized OS, anyway?

richarddamon wrote on Thursday, June 27, 2019:

You say it is what it could be, I would say it is more what you want it to be, but for me, most of these are things I hope never become part of the kernel.

I would not want to see any of these features added that add essential cost for system that don’t need/want it.

I will say to begin with that I have NEVER found a need for a FreeRTOS task to wait on multiple things at once, NEVER. I will admit that some people have seen a need for something like that, which is why QueueSets were created, even if they are less powerful than you WaitForAny operation, but it seems sufficient for them, and it was able to be implemented at no cost to the basic Queue operation (a key feature). My first impession is this might be hard to do for your general WaitForAny call, and still keep the current bounded execution time for a queue read/write irrespective on how many/who is waiting for the queue.

The one case where I have used a WaitForAny was in a multiprocess environments as part of inter-process communications. When Process A sends a request to Process B, it might use one of several different message forms, and Process B will typically have a single thread listening for all those messages and when it gets one, often forwards it to an appropriate worker thread. Thus this message pump needs a WaitForAny. Process A couldn’t directly address the needed thread, because that is a detail abstracted out by the process boundry.

With Tasks, we don’t have that process boundry, so the Task that is acting like Process A, doesn’t need to address a dispatch thread in Process B, but can (and should) directly address the task that is responsible for that operation, which likely will be waiting for a single queue, or possibly a QueueSet if it handles multiple different sorts of things. What use of WaitForAny that isn’t brought about by the limitations of a Multi-Process envronment do you have?

Adding the equivalent of processes to FreeRTOS would be heavy weight, and inappropriate. Some of your features might work as part of FreeRTOS/Plus. Just as I am glad that a network stack is not build into FreeRTOS as that is weight I rarely need, but is available by adding the appropriate additional package that builds on top of FreeRTOS, so perhaps some of your additions could be worked into an addon package like that.

For example, your comment about timers using the name so that you could look up a timer by name. I see no need for something like that, as I generally know the timer I want to use, as it has a given purpose. The need to look up a timer by name mostly comes, in my opinion, from wanting to share the timer between processes (where you can’t just access the handle as a global). If you really wanted to be able to look up a timer by name, just add a wrapper layer that keeps a dictionary of timers with their names, and lets you look up a timer register through it. That would add no overhead to applciations/timers that don’t need it.

stackmaster wrote on Thursday, June 27, 2019:

The one case where I have used a WaitForAny was in a multiprocess environments as part of inter-process communications. When Process A sends a request to Process B, it might use one of several different message forms, and Process B will typically have a single thread listening for all those messages and when it gets one, often forwards it to an appropriate worker thread. Thus this message pump needs a WaitForAny. Process A couldn’t directly address the needed thread, because that is a detail abstracted out by the process boundry.

What do you mean by that? [I want to make sure that we are on the same page before responding to other comments in your reply.]