1 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2 // ==== Kernel Control ====
4 \addtogroup CMSIS_RTOS_KernelCtrl Kernel Information and Control
6 \brief Provides version/system information and starts/controls the RTOS Kernel.
8 The kernel Information and Control function group allows to:
9 - obtain information about the system and the underlying kernel.
10 - obtain version information about the CMSIS-RTOS API.
11 - initialize of the RTOS kernel for creating objects.
12 - start the RTOS kernel and thread switching.
13 - check the execution status of the RTOS kernel.
15 \note The kernel information and control functions cannot be called from
16 \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
17 \note The kernel initialization for RTX5 is documented in \ref SystemStartup.
21 /*----------------------------------------------------------------------------
22 * Application main thread
23 *---------------------------------------------------------------------------*/
24 void app_main (void *argument) {
32 // System Initialization
33 SystemCoreClockUpdate();
36 osKernelInitialize(); // Initialize CMSIS-RTOS
37 osThreadNew(app_main, NULL, NULL); // Create application main thread
38 osKernelStart(); // Start thread execution
44 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
48 Identifies the underlying RTOS kernel and API version number. The version is represented in a combined decimal number in the
49 format: major.minor.rev: mmnnnrrrr
51 Use \ref osKernelGetInfo to retrieve the version numbers.
54 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
58 State of the kernel as retrieved by \ref osKernelGetState. In case \b osKernelGetState fails or if it is called from an ISR,
59 it will return \c osKernelError, otherwise it returns the kernel state.
62 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
64 \fn osStatus_t osKernelInitialize (void)
66 The function \b osKernelInitialize initializes the RTOS Kernel. Before it is successfully executed, only the functions
67 \ref osKernelGetInfo and \ref osKernelGetState may be called.
69 Possible \ref osStatus_t return values:
70 - \em osOK in case of success.
71 - \em osError if an unspecific error occurred.
72 - \em osErrorISR if called from an \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routine".
73 - \em osErrorNoMemory if no memory could be reserved for the operation.
75 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
79 #include "RTE_Components.h"
80 #include CMSIS_device_header
81 #include "cmsis_os2.h"
83 /*----------------------------------------------------------------------------
84 * Application main thread
85 *---------------------------------------------------------------------------*/
86 void app_main (void *argument) {
94 // System Initialization
95 SystemCoreClockUpdate();
98 osKernelInitialize(); // Initialize CMSIS-RTOS
99 osThreadNew(app_main, NULL, NULL); // Create application main thread
100 osKernelStart(); // Start thread execution
106 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
108 \fn osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size)
110 The function \b osKernelGetInfo retrieves the API and kernel version of the underlying RTOS kernel and a human readable
111 identifier string for the kernel. It can be safely called before the RTOS is initialized or started (call to
112 \ref osKernelInitialize or \ref osKernelStart).
114 Possible \ref osStatus_t return values:
115 - \em osOK in case of success.
116 - \em osError if an unspecific error occurred.
118 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
127 status = osKernelGetInfo(&osv, infobuf, sizeof(infobuf));
129 printf("Kernel Information: %s\r\n", infobuf);
130 printf("Kernel Version : %d\r\n", osv.kernel);
131 printf("Kernel API Version: %d\r\n", osv.api);
137 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
139 \fn osKernelState_t osKernelGetState (void)
141 The function \b osKernelGetState returns the current state of the kernel and can be safely called before the RTOS is
142 initialized or started (call to \ref osKernelInitialize or \ref osKernelStart). In case it fails it will return \c osKernelError,
143 otherwise it returns the kernel state (refer to \ref osKernelState_t for the list of kernel states).
145 Possible \ref osKernelState_t return values:
146 - \ref osKernelError if an unspecific error occurred.
147 - the actual kernel state otherwise.
149 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
154 // System Initialization
155 SystemCoreClockUpdate();
157 if(osKernelGetState() == osKernelInactive) { // Is the kernel initialized?
158 osKernelInitialize(); // Initialize CMSIS-RTOS kernel
165 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
167 \fn osStatus_t osKernelStart (void)
169 The function \b osKernelStart starts the RTOS kernel and begins thread switching. It will not return to its calling function
170 in case of success. Before it is successfully executed, only the functions \ref osKernelGetInfo, \ref osKernelGetState, and
171 object creation functions (\b osXxxNew) may be called.
173 At least one initial thread should be created prior osKernelStart, see \ref osThreadNew.
175 Possible \ref osStatus_t return values:
176 - \em osError if an unspecific error occurred.
177 - \em osErrorISR if called from an \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routine".
179 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
184 // System Initialization
185 SystemCoreClockUpdate();
187 if(osKernelGetState() == osKernelInactive) {
188 osKernelInitialize();
190 ; // ... Start Threads
191 if (osKernelGetState() == osKernelReady) { // If kernel is ready to run...
192 osKernelStart(); // ... start thread execution
195 while(1); // only reached in case of error
200 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
202 \fn int32_t osKernelLock (void)
204 The function \b osKernelLock allows to lock all task switches. It returns the previous value of the lock state (\token{1} if
205 it was locked, \token{0} if it was unlocked), or a negative number representing an error code otherwise (refer to
208 Possible \ref osStatus_t return values:
209 - \em osError if an unspecific error occurred.
210 - \em osErrorISR if called from an \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routine".
211 - \em osErrorSafetyClass if the calling thread safety class is lower than the kernel protect safety class.
213 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
217 int32_t state = osKernelLock();
219 osKernelRestore(state);
223 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
225 \fn int32_t osKernelUnlock (void)
227 The function \b osKernelUnlock resumes from \ref osKernelLock. It returns the previous value of the lock state (\token{1} if
228 it was locked, \token{0} if it was unlocked), or a negative number representing an error code otherwise (refer to
231 Possible \ref osStatus_t return values:
232 - \em osError if an unspecific error occurred.
233 - \em osErrorISR if called from an \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routine".
235 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
239 int32_t sl = osKernelLock();
242 int32_t su = osKernelUnlock();
243 // ... uncritical code
244 osKernelRestoreLock(su);
247 osKernelRestoreLock(sl);
251 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
253 \fn int32_t osKernelRestoreLock (int32_t lock)
255 The function \b osKernelRestoreLock restores the previous lock state after \ref osKernelLock or \ref osKernelUnlock.
257 The argument \a lock specifies the lock state as obtained by \ref osKernelLock or \ref osKernelUnlock.
259 The function returns the new value of the lock state (\token{1} if it was locked, \token{0} if it was unlocked), or a
260 negative number representing an error code otherwise (refer to \ref osStatus_t).
262 Possible \ref osStatus_t return values:
263 - \em osError if an unspecific error occurred.
264 - \em osErrorISR if called from interrupt other than fault or \ref osWatchdogAlarm_Handler.
265 - \em osErrorSafetyClass if the calling thread safety class is lower than the kernel protect safety class.
269 int32_t sl = osKernelLock();
272 int32_t su = osKernelUnlock();
273 // ... uncritical code
274 osKernelRestoreLock(su);
277 osKernelRestoreLock(sl);
281 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
283 \fn uint32_t osKernelSuspend (void)
285 CMSIS-RTOS provides extension for tick-less operation which is useful for applications that use extensively low-power modes
286 where the SysTick timer is also disabled. To provide a time-tick in such power-saving modes a wake-up timer is used to derive
287 timer intervals. The function \b osKernelSuspend suspends the RTX kernel scheduler and thus enables sleep modes.
289 The return value can be used to determine the amount of system ticks until the next tick-based kernel event will occur, i.e.
290 a delayed thread becomes ready again. It is recommended to set up the low power timer to generate a wake-up interrupt based
291 on this return value.
293 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
297 void osRtxIdleThread (void) {
298 /* The idle thread is running
299 when no other thread is ready
304 /* HERE: include optional user
305 code to be executed when no
307 sleep = osKernelSuspend(); /* Suspend RTX thread scheduler */
309 if (sleep) { /* How long can we sleep? */
310 /* "sleep" is in RTX Timer Ticks
314 /* Setup wake-up e.g. watchdog */
316 __WFE(); /* Enter Power-down mode */
319 sleep = tc; /* Adjust with cycles slept */
322 osKernelResume(sleep); /* Resume thread scheduler */
328 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
330 \fn void osKernelResume (uint32_t sleep_ticks)
332 CMSIS-RTOS provides extension for tick-less operation which is useful for applications that use extensively low-power modes
333 where the SysTick timer is also disabled. To provide a time-tick in such power-saving modes a wake-up timer is used to derive
334 timer intervals. The function \b osKernelResume enables the RTX kernel scheduler and thus wakes up the system from sleep
337 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
341 void osRtxIdleThread (void) {
342 /* The idle thread is running
343 when no other thread is ready
348 /* HERE: include optional user
349 code to be executed when no
351 sleep = osKernelSuspend(); /* Suspend RTX thread scheduler */
353 if (sleep) { /* How long can we sleep? */
354 /* "sleep" is in RTX Timer Ticks
358 /* Setup wake-up e.g. watchdog */
360 __WFE(); /* Enter Power-down mode */
363 sleep = tc; /* Adjust with cycles slept */
366 osKernelResume(sleep); /* Resume thread scheduler */
372 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
374 \fn uint32_t osKernelGetTickCount (void)
376 The function \b osKernelGetTickCount returns the current RTOS kernel tick count.
378 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
382 #include "cmsis_os2.h"
384 void Thread_1 (void *arg) { // Thread function
387 tick = osKernelGetTickCount(); // retrieve the number of system ticks
389 tick += 1000; // delay 1000 ticks periodically
395 Due to the limited value range used for the tick count it may overflow during runtime,
396 i.e. after 2<sup>32</sup> ticks which are roughly 49days @ 1ms. Typically one has not to
397 take special care of this unless a monotonic counter is needed. For such a case an additional
398 64bit tick counter can be implemented as follows. The given example needs GetTick() called at
399 least twice per tick overflow to work properly.
403 uint64_t GetTick(void) {
404 static uint32_t tick_h = 0U;
405 static uint32_t tick_l = 0U;
408 tick = osKernelGetTickCount();
414 return (((uint64_t)tick_h << 32) | tick_l);
419 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
421 \fn uint32_t osKernelGetTickFreq (void)
423 The function \b osKernelGetTickFreq returns the frequency of the current RTOS kernel tick.
425 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
428 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
430 \fn uint32_t osKernelGetSysTimerCount (void)
432 The function \b osKernelGetSysTimerCount returns the current RTOS kernel system timer as a 32-bit value.
433 The value is a rolling 32-bit counter that is composed of the kernel system interrupt timer value
434 and the counter that counts these interrupts (RTOS kernel ticks).
436 This function allows the implementation of very short timeout checks below the RTOS tick granularity.
437 Such checks might be required when checking for a busy status in a device or peripheral initialization
438 routine, see code example below.
440 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
444 #include "cmsis_os2.h"
446 void SetupDevice (void) {
449 // Calculating 100us timeout in system timer ticks
450 const uint32_t timeout = 100U * osKernelGetSysTimerFreq() / 1000000u;
452 tick = osKernelGetSysTimerCount(); // get start value of the Kernel system tick
453 Device.Setup (); // initialize a device or peripheral
454 do { // poll device busy status for 100 microseconds
455 if (!Device.Busy) break; // check if device is correctly initialized
456 } while ((osKernelGetSysTimerCount() - tick) < timeout));
458 ; // in case device still busy, signal error
460 // start interacting with device
466 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
468 \fn uint32_t osKernelGetSysTimerFreq (void)
470 The function \b osKernelGetSysTimerFreq returns the frequency of the current RTOS kernel system timer.
472 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
475 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
477 \fn osStatus_t osKernelProtect (uint32_t safety_class);
479 The function \b osKernelProtect configures kernel access protection. After its successful execution, only threads with
480 safety class equal or higher than the \a safety_class specified in the argument can execute kernel control functions.
482 - \ref osKernelUnlock
483 - \ref osKernelRestoreLock
484 - \ref osKernelSuspend
485 - \ref osKernelResume
486 - \ref osKernelProtect
488 Possible \ref osStatus_t return values:
489 - \em osOK in case of success.
490 - \em osErrorParameter if \a safety_class is invalid.
491 - \em osError if kernel is not in ready or running state.
492 - \em osErrorISR if called from an \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routine".
493 - \em osErrorSafetyClass if the calling thread safety class is lower than the kernel protect safety class.
495 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
499 #include "cmsis_os2.h"
501 void ProtectKernelControlFunctions (void) {
504 status = osKernelProtect(4U); // Enable Kernel Control for threads with safety class 4 or higher
505 // verify status value here.
510 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
512 \fn osStatus_t osKernelDestroyClass (uint32_t safety_class, uint32_t mode);
514 The function \b osKernelDestroyClass destroys RTOS objects based on safety class assignment. \a safety_class provides the reference safety class value, while \a mode is considered as a bitmap that additionally specifies the safety classes to be destroyed.
516 If \ref osSafetyWithSameClass is set in \a mode than the RTOS objects with safety class value equal to \a safety_class will be destroyed.
518 If \ref osSafetyWithLowerClass is set in \a mode than the RTOS objects with safety class value lower than \a safety_class will be destroyed.
520 Possible \ref osStatus_t return values:
521 - \em osOK in case of success.
522 - \em osErrorParameter if \a safety_class is invalid.
523 - \em osErrorResource if no other \ref ThreadStates "READY" thread exists.
524 - \em osErrorISR if called from interrupt other than \ref osWatchdogAlarm_Handler.
525 - \em osErrorSafetyClass if the calling thread safety class is lower than the kernel protect safety class.
529 #include "cmsis_os2.h"
531 void DestroyNonCriticalClasses (void) {
534 status = osKernelDestroyClass(4U, osSafetyWithSameClass | osSafetyWithLowerClass); // Destroy objects with safety class 4 or lower
535 // verify status value here.
540 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
542 \fn void osFaultResume (void);
544 Resume normal RTOS operation when exiting exception faults.
548 void HardFault_Handler (void) {
550 "... \n\t" // Enter assembly and handle faults
552 "ldr r0,=osFaultResume \n\t" // Before exiting the handler load and
553 "bx r0 \n\t" // jump to osFaultResume
561 // these struct members must stay outside the group to avoid double entries in documentation
563 \var osKernelState_t::osKernelInactive
565 The kernel is not ready yet. \ref osKernelInitialize needs to be executed successfully.
567 \var osKernelState_t::osKernelReady
569 The kernel is not yet running. \ref osKernelStart transfers the kernel to the running state.
571 \var osKernelState_t::osKernelRunning
573 The kernel is initialized and running.
575 \var osKernelState_t::osKernelLocked
577 The kernel was locked with \ref osKernelLock. The functions \ref osKernelUnlock or \ref osKernelRestoreLock unlocks it.
579 \var osKernelState_t::osKernelSuspended
581 The kernel was suspended using \ref osKernelSuspend. The function \ref osKernelResume returns to normal operation.
583 \var osKernelState_t::osKernelError
587 \var osKernelState_t::osKernelReserved