A C++11/C++14 interface for CMSIS-RTOS API Version 2.
This source code implements some classes of the STL, based on CMSIS-RTOS API Version 2 interface. You must use a C++ compiler that supports the C++11/C++14 standard, like GNU ARM Embedded Toolchain.
Defined in header "Thread.h"
This header is part of the concurrency support library. It provides a full implementation of STL interfaces. You can directly use std::thread and std::thread::id classes, and std::this_thread namespace.
Threads are created in a join-able state, with default thread priority (osPriorityNormal) and default stack size from the Global Memory Pool. See Thread Management for more details.
Defined in header "Mutex.h"
This header is part of the concurrency support library. It provides a partial implementation of STL interfaces. You can directly use std::mutex, std::timed_mutex, std::recursive_mutex and std::recursive_timed_mutex classes. once_flag and call_once are not implemented yet.
Mutexes are created with Priority inheritance protocol (osMutexPrioInherit flag). While a thread owns this mutex it cannot be preempted by a higher priority thread to avoid starvation. See Mutex Management for more details.
Mutex management functions cannot be called from Interrupt Service Routines (ISR), unlike a binary semaphore that can be released from an ISR.
Defined in header "Semaphore.h"
This header is part of the concurrency support library. It provides a full implementation of STL interfaces. You can directly use std::counting_semaphore and std::binary_semaphore classes.
Semaphores are used to manage and protect access to shared resources.
Defined in header "Chrono.h"
This header is part of the date and time library. It provides a full implementation of STL interfaces. std::chrono::system_clock and std::chrono::high_resolution_clock are implemented using the osKernelGetTickCount() function. If you need more precision, you can use sys::chrono::high_resolution_clock that is implemented with osKernelGetSysTimerCount() function.
Globals operators new and delete are overridden for using the Global Memory Pool. For now, this part is specific to RTX5 implementation, and need to be ported for other RTOS (like FreeRTOS).
Defined in header "OSException.h"
In case of failure, methods throws a std::system_error exception. std::error_code::value contains the CMSIS error code.
This part is a group of some CMSIS specific classes, but as close as possible of the "STL spirit".
Defined in header "OS.h"
Get RTOS Kernel version. Returns a string that contains version information. In case of failure, throws a std::system_error exception.
Get RTOS Kernel tick frequency in Hz. Returns the frequency of the current RTOS kernel tick. In case of failure, throws a std::system_error exception.
Initialize the RTOS Kernel. In case of failure, throws a std::system_error exception.
If you want to use static C++ objects, the RTOS must be initialized before main(). In that case, call osKernelInitialize() at the end of SystemInit() function.
Start the RTOS Kernel scheduler. In case of success, this function will never returns. In case of failure, throws a std::system_error exception.
Suspends the RTOS kernel scheduler and thus enables sleep modes.
Enables the RTOS kernel scheduler and thus wakes up the system from sleep mode.
Get system core clock frequency in Hz. Returns the frequency of the current system core clock. In case of failure, throws a std::system_error exception.
Defined in header "EventFlag.h"
The event flags management allow you to control or wait for event flags. Each signal has up to 31 event flags.
Class sys::event.
Defined in header "Timer.h"
Timer Management, class sys::timer.
Defined in header "MessageQueue.h"
Message Queue exchange messages between threads in a FIFO-like operation.
class sys::message_queue.
Defined in header "Memory.h"
Memory Pools are fixed-size blocks of memory that are thread-safe.
class sys::memory_pool satisfies allocator completeness requirements and provides a compatible interface with std::allocator but is not CopyConstructible. In consequence, don't try to use this class with STL containers, because this ones aren't designed to works with fixed size allocators.
class sys::memory_pool_delete is a Deleter (like std::default_delete) associated to an memory pool.
Be carreful with memory pools and smart pointers. Don't delete a memory pool with living associated smart pointers.
#include <iostream>
#include "OS.h"
#include "Thread.h"
#include "Timer.h"
#include "Chrono.h"
int main()
{
cmsis::kernel::initialize(); // Or call osKernelInitialize() at the end of SystemInit() function
std::thread main_thread([]
{
std::cout << cmsis::kernel::version() << std::endl;
std::cout << "Core Clock: " << sys::core::clock_frequency() << "Hz" << std::endl;
try
{
std::chrono::system_clock::time_point tp0 = std::chrono::system_clock::now();
sys::timer ledTimer(std::chrono::seconds(1), [&]
{
std::cout << "now: " << (std::chrono::system_clock::now() - tp0).count() << std::endl;
return true;
});
ledTimer.start();
sys::chrono::high_resolution_clock::time_point tp1 = sys::chrono::high_resolution_clock::now();
for (;;)
{
std::this_thread::sleep_for(std::chrono::milliseconds(900));
std::cout << "hrc: " << (sys::chrono::high_resolution_clock::now() - tp1).count() << std::endl;
}
}
catch(std::exception& e)
{
std::cout << "ERROR: " << e.what() << std::endl;
}
});
cmsis::kernel::start();
return 0;
}