For the impatient
If you ever had to do with CMSIS RTOS API and did not enjoy it, or if you felt it like a straitjacket compared to your native RTOS, well, rest assured, your're not alone. The good news is that your experience matters and you can help improve CMSIS RTOS API. Go to GitHub Issues and comment on any of the existing issues, or open new ones.
ARM, thumbs up for the CMSIS RTOS idea!
First of all I have to confess that I was a big supporter of the general idea of a common CMSIS RTOS API, from the moment I first read about it. However, as big as my expectations were, as big was my dissapointment when the specs went out.
Some CMSIS RTOS API considerations
From my point of view, the main problems with the CMSIS RTOS API are:
- no POSIX compliance
- not C++ friendly
Please note that I did not ask for C++ APIs, the plain C APIs should be perfectly fine, I just prefered the APIs to be designed by someone who thinks in C++, not in C (and as such knows how to avoid the usual mess that unstructured C programs bring, especially in the embedded world); unfortunately ARM seems to have no C++ specialists in their design teams.
The CMSIS++ proposal
Given this situation, and seeing that ARM had no plans for a C++ redesign, by the end of 2015 I started to think of CMSIS++, as a C++ POSIX compliant proposal for a future generation of CMSIS. In March 2016 the project was publicly announced in the ARM Connected site.
Some CMSIS RTOS API issues
The initial CMSIS++ attempt was to simply rewrite the original CMSIS RTOS API in C++. However, while starting to walk on this path, I encountered many problems, and noticed many differences from the POSIX and ISO C/C++ specs. At a certain point I realised that the current design is broken beyound repair, and a reset is required, otherwise the approach will not work.
Restarting from scratch, the focus moved from CMSIS to POSIX and ISO.
During the design and development phases, I kept a log of issues that I identified and addressed in the CMSIS++ proposal.
Some were difficulties in understanding the CMSIS RTOS API, due to documentation issues, some are functional issues that make using the original API not very convenient, and some are suggestions for missing features.
The POSIX compliance issues are:
- Use POSIX error codes (#65)
- Use explicit separate calls for different waiting functions, like lock(), try_lock(), timed_lock() (#45)
- Add normal (non-recursive) mutex (#53)
- Add a mechanism to wait for a thread to terminate (#50)
- For message queues, make the message size user configurable (#70)
- For message queues, add message priorities (#72)
- Make osSemaphoreWait() return errors, not counts (#56)
- Deprecate or remove the unused thread_id parameter in osMessageQCreate()/osMailQCreate() prototypes (#61)
Other functional issues are:
- Avoid the heavy use of macros (to define objects and to refer to them) (#36)
- Do not mandate the use of a dynamic allocator (for stack, queues, etc) (#37)
- Add support for critical regions (interrupts & scheduler) (#38)
- Avoid mixing time durations (in milliseconds) with timer counts in ticks (#39)
- Add a separate RTC system clock (#40)
- Add os_main() to make the use of a main thread explicit (#41)
- Add support for a synchronised public memory allocator (#42)
- Avoid returning agregates (like osEvent) (#43)
- Extend the range for osKernelSysTick() (#44)
- Make the scheme to assign names to objects more consistent (#46)
- Add missing destructor functions to all objects (#47)
- Extend the range of priority levels (#49)
- Add a mechanism to enumerate all registered threads (#51)
- Allow to explicitly define the semaphore max count (#55)
- Add a method to wait for a memory pool block to become available (#57)
- Fix non-portable message type in osMessagePut() (#60)
- Fix osMessagePut()/osMailPut() inconsistent error when called from ISR (#62)
- Mail queues, as separate objects, are redundant (#63)
- Add typedefs for all different types used in prototypes (#66)
- For all objects, add reset functions to return the object to initial status (#67)
- For mutex, add a method to get the owner thread (#68)
- For memory pools, add more accessors to get pool status (#69)
- For message queues, add more accessors to get queue status (#71)
The documentation issues are:
- Explain that thread functions can return (#48)
- Explain the mutex behaviour (recursive vs normal) (#52)
- Clarify the specs for binary vs counting semaphores (#54)
- Fix the data type used in osMessageQDef() example (#58)
- Fix misplaced thread id parameter for message queue (#59)
CMSIS RTOS API v2
Somehow acknowledging the initial design problems, ARM announced working on CMSIS RTOS API v2. To my pleasant surprise, ARM seems to have deprecated the initial macro based object creation mechanism (probably one of the most annoying features of the RTOS API v1).
In the new proposal ARM also gave up returning aggregate objects, extended the priorities range, added explicit normal/recursive mutex objects, renamed some objects and generally kept very few features from the initial specification, so a design reset seems possible.
However, based on the CMSIS++ experience, there are still more design decisions required to bring the new RTOS v2 closer to POSIX and ISO, for example using the POSIX error codes, using the POSIX explicit separate calls for different waiting functions (like lock(), try_lock(), timed_lock()), etc.
So, if you would like to express your support for POSIX compatibility, or generally to have a better CMSIS RTOS API, please go to GitHub Issues and comment on any of the existing issues (especially those marked with Help Wanted), or open new tickets with your own suggestions.
CMSIS 5 announcement.
CMSIS++ is an open source project, maintained by Liviu Ionescu.
The main source of information for CMSIS++ is the project web.