distortos project - mentioned in previous news article - is still evolving. Today it is exactly 7 months since the first commit in the repository, and the total number of these commits reached a nice value of 1023. Many readers - at least those who are a bit into RTOSes for microcontrollers - may wonder "who needs another RTOS project?". Answer to this question is very complex and I could write a separate article about that, so for now a link to README file - in which I tried to explain the main reasons for this project's existence - must suffice. I think that at least the huge emphasis placed on C++ and C++11 support makes this project worthwhile, although this feature should not diminish other advantages (some of which are of course "future" (; ), important for people who don't intend to use C++ (this feature is one of the "future" ones for sure, as for now only C++11 API is available).
There are still many features missing, but these 7 months were well spent - quite a lot was done, and these things work remarkably well (;
The most important features are obviously threads (Thread, StaticThread and ThreadBase classes), which can accept any number of arguments of any type - thanks to new features of C++11 standard - not only the void* known from other RTOSes. Moreover - regular functions, member functions, functors or lambdas can be used as thread's function.
All of these features are also present in software timers (SoftwareTimer class).
Scheduler supports full preemption based on thread's priority (there are 256 priority levels), and when several threads with the same priority are present, they are scheduled according to FIFO or round-robin algorithm (selected for each thread individually).
Semaphore (Semaphore class) is probably the most basic synchronization object. It is possible to configure maximal value the semaphore can "have", so this object can also be used as binary semaphore. Semaphores can be "posted" from interrupts.
Mutex (Mutex class) is one of more advanced synchronization mechanisms. Just as in POSIX standard, it can be configured to use any of the three "modes" - normal, error-checking or recursive - and any of the three "protocols" - normal, priority inheritance or priority protocol (also known as priority ceiling). Unlike many other RTOSes, priority inheritance protocol works with no limitations: through any number of inheritance "levels" and with any number of mutexes locked by threads in any order (diagram and description of test case of this particular feature).
Classic condition variable (ConditionVariable class) is a mechanism which extends functionality of mutexes.
Queues can be used for standard communication between threads and interrupts (in any combination). There are four variants of queues:
Messages added to queues which don't support priorities (...FifoQueue) are ordered in FIFO order, while queues which do support priorities (...MessageQueue) allow adding messages with one of 256 priority levels. Queues without support for objects (...Raw...) copy the messages with memcpy() function, while queues with support for objects use all operations required in such scenario (construction, destruction, assignment operator, swap, emplace, ...).
All blocking operations are also available in non-blocking variants and in blocking versions with timeout (absolute or relative), which - thanks to C++11 std::chrono - can be easily expressed in any unit (like seconds, minutes, hours, ... - link), not only in system "ticks".
All errors are signaled with error codes - functions use neither errno variable, nor C++ exceptions.
The only supported architecture - for now - is ARMv7-M, so ARM Cortex-M3 (ARM Cortex-M4 can be used without enabling FPU) (added 20.03.2015) and ARM Cortex-M4(F), and the only "officially" supported chip is STM32F407VG (known from STM32F4Discovery board), although using any different chip with proper core would be trivial.
I saved the best part (I hope) for the end - use of all functionalities mentioned above is possible without dynamic memory allocation. All previously described objects can be constructed as global variables or on stack.
I'm sure I forgot to mention some more interesting features...
Feel encouraged to test the code, ask questions, post comments, send suggestions and cooperate (; Stay tuned!
|