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 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====*/
56 \typedef osKernelState_t
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.
61 \var osKernelState_t::osKernelInactive
63 The kernel is not ready yet. \ref osKernelInitialize needs to be executed successfully.
65 \var osKernelState_t::osKernelReady
67 The kernel is not yet running. \ref osKernelStart transfers the kernel to the running state.
69 \var osKernelState_t::osKernelRunning
71 The kernel is initialized and running.
73 \var osKernelState_t::osKernelLocked
75 The kernel was locked with \ref osKernelLock. The functions \ref osKernelUnlock or \ref osKernelRestoreLock unlocks it.
77 \var osKernelState_t::osKernelSuspended
79 The kernel was suspended using \ref osKernelSuspend. The function \ref osKernelResume returns to normal operation.
81 \var osKernelState_t::osKernelError
85 \var osKernelState_t::osKernelReserved
91 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
93 \fn osStatus_t osKernelInitialize (void)
95 The function \b osKernelInitialize initializes the RTOS Kernel. Before it is successfully executed, only the functions
96 \ref osKernelGetInfo and \ref osKernelGetState may be called.
98 Possible \ref osStatus_t return values:
99 - \em osOK in case of success.
100 - \em osError if an unspecific error occurred.
101 - \em osErrorISR if called from an \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routine".
102 - \em osErrorNoMemory if no memory could be reserved for the operation.
104 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
108 #include "RTE_Components.h"
109 #include CMSIS_device_header
110 #include "cmsis_os2.h"
112 /*----------------------------------------------------------------------------
113 * Application main thread
114 *---------------------------------------------------------------------------*/
115 void app_main (void *argument) {
123 // System Initialization
124 SystemCoreClockUpdate();
127 osKernelInitialize(); // Initialize CMSIS-RTOS
128 osThreadNew(app_main, NULL, NULL); // Create application main thread
129 osKernelStart(); // Start thread execution
135 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
137 \fn osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size)
139 The function \b osKernelGetInfo retrieves the API and kernel version of the underlying RTOS kernel and a human readable
140 identifier string for the kernel. It can be safely called before the RTOS is initialized or started (call to
141 \ref osKernelInitialize or \ref osKernelStart).
143 Possible \ref osStatus_t return values:
144 - \em osOK in case of success.
145 - \em osError if an unspecific error occurred.
147 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
156 status = osKernelGetInfo(&osv, infobuf, sizeof(infobuf));
158 printf("Kernel Information: %s\r\n", infobuf);
159 printf("Kernel Version : %d\r\n", osv.kernel);
160 printf("Kernel API Version: %d\r\n", osv.api);
166 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
168 \fn osKernelState_t osKernelGetState (void)
170 The function \b osKernelGetState returns the current state of the kernel and can be safely called before the RTOS is
171 initialized or started (call to \ref osKernelInitialize or \ref osKernelStart). In case it fails it will return \c osKernelError,
172 otherwise it returns the kernel state (refer to \ref osKernelState_t for the list of kernel states).
174 Possible \ref osKernelState_t return values:
175 - \ref osKernelError if an unspecific error occurred.
176 - the actual kernel state otherwise.
178 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
183 // System Initialization
184 SystemCoreClockUpdate();
186 if(osKernelGetState() == osKernelInactive) { // Is the kernel initialized?
187 osKernelInitialize(); // Initialize CMSIS-RTOS kernel
194 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
196 \fn osStatus_t osKernelStart (void)
198 The function \b osKernelStart starts the RTOS kernel and begins thread switching. It will not return to its calling function
199 in case of success. Before it is successfully executed, only the functions \ref osKernelGetInfo, \ref osKernelGetState, and
200 object creation functions (\b osXxxNew) may be called.
202 At least one initial thread should be created prior osKernelStart, see \ref osThreadNew.
204 Possible \ref osStatus_t return values:
205 - \em osError if an unspecific error occurred.
206 - \em osErrorISR if called from an \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routine".
208 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
213 // System Initialization
214 SystemCoreClockUpdate();
216 if(osKernelGetState() == osKernelInactive) {
217 osKernelInitialize();
219 ; // ... Start Threads
220 if (osKernelGetState() == osKernelReady) { // If kernel is ready to run...
221 osKernelStart(); // ... start thread execution
224 while(1); // only reached in case of error
229 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
231 \fn int32_t osKernelLock (void)
233 The function \b osKernelLock allows to lock all task switches. It returns the previous value of the lock state (\token{1} if
234 it was locked, \token{0} if it was unlocked), or a negative number representing an error code otherwise (refer to
237 Possible \ref osStatus_t return values:
238 - \em osError if an unspecific error occurred.
239 - \em osErrorISR if called from an \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routine".
240 - \em osErrorSafetyClass if the calling thread safety class is lower than the kernel protect safety class.
242 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
246 int32_t state = osKernelLock();
248 osKernelRestore(state);
252 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
254 \fn int32_t osKernelUnlock (void)
256 The function \b osKernelUnlock resumes from \ref osKernelLock. It returns the previous value of the lock state (\token{1} if
257 it was locked, \token{0} if it was unlocked), or a negative number representing an error code otherwise (refer to
260 Possible \ref osStatus_t return values:
261 - \em osError if an unspecific error occurred.
262 - \em osErrorISR if called from an \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routine".
264 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
268 int32_t sl = osKernelLock();
271 int32_t su = osKernelUnlock();
272 // ... uncritical code
273 osKernelRestoreLock(su);
276 osKernelRestoreLock(sl);
280 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
282 \fn int32_t osKernelRestoreLock (int32_t lock)
284 The function \b osKernelRestoreLock restores the previous lock state after \ref osKernelLock or \ref osKernelUnlock.
286 The argument \a lock specifies the lock state as obtained by \ref osKernelLock or \ref osKernelUnlock.
288 The function returns the new value of the lock state (\token{1} if it was locked, \token{0} if it was unlocked), or a
289 negative number representing an error code otherwise (refer to \ref osStatus_t).
291 Possible \ref osStatus_t return values:
292 - \em osError if an unspecific error occurred.
293 - \em osErrorISR if called from interrupt other than fault or \ref osWatchdogAlarm_Handler.
294 - \em osErrorSafetyClass if the calling thread safety class is lower than the kernel protect safety class.
298 int32_t sl = osKernelLock();
301 int32_t su = osKernelUnlock();
302 // ... uncritical code
303 osKernelRestoreLock(su);
306 osKernelRestoreLock(sl);
310 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
312 \fn uint32_t osKernelSuspend (void)
314 CMSIS-RTOS2 provides extension for tick-less operation which is useful for applications that use extensively low-power modes where the SysTick timer is also disabled.
316 To provide a time-tick in such power-saving modes a wake-up timer is used to derive timer intervals. The function \b osKernelSuspend suspends the RTOS kernel scheduler and thus enables sleep modes.
318 The return value can be used to determine the amount of system ticks until the next tick-based kernel event will occur, i.e. a delayed thread becomes ready again. It is recommended to set up the low power timer to generate a wake-up interrupt based on this return value.
320 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
324 void osRtxIdleThread (void) {
325 /* The idle thread is running
326 when no other thread is ready
331 /* HERE: include optional user
332 code to be executed when no
334 sleep = osKernelSuspend(); /* Suspend RTOS kernel scheduler */
336 if (sleep) { /* How long can we sleep? */
337 /* "sleep" is in kernel Timer Ticks
341 /* Setup wake-up e.g. watchdog */
343 __WFE(); /* Enter Power-down mode */
346 sleep = tc; /* Adjust with cycles slept */
349 osKernelResume(sleep); /* Resume thread scheduler */
355 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
357 \fn void osKernelResume (uint32_t sleep_ticks)
359 CMSIS-RTOS provides extension for tick-less operation which is useful for applications that use extensively low-power modes where the SysTick timer is also disabled.
361 To provide a time-tick in such power-saving modes a wake-up timer is used to derive timer intervals. The function \b osKernelResume enables the RTOS kernel scheduler and thus wakes up the system from sleep
364 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
368 void osRtxIdleThread (void) {
369 /* The idle thread is running
370 when no other thread is ready
375 /* HERE: include optional user
376 code to be executed when no
378 sleep = osKernelSuspend(); /* Suspend RTOS kernel scheduler */
380 if (sleep) { /* How long can we sleep? */
381 /* "sleep" is in Kernel Timer Ticks
385 /* Setup wake-up e.g. watchdog */
387 __WFE(); /* Enter Power-down mode */
390 sleep = tc; /* Adjust with cycles slept */
393 osKernelResume(sleep); /* Resume thread scheduler */
399 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
401 \fn uint32_t osKernelGetTickCount (void)
403 The function \b osKernelGetTickCount returns the current RTOS kernel tick count.
405 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
409 #include "cmsis_os2.h"
411 void Thread_1 (void *arg) { // Thread function
414 tick = osKernelGetTickCount(); // retrieve the number of system ticks
416 tick += 1000; // delay 1000 ticks periodically
422 Due to the limited value range used for the tick count it may overflow during runtime,
423 i.e. after 2<sup>32</sup> ticks which are roughly 49days @ 1ms. Typically one has not to
424 take special care of this unless a monotonic counter is needed. For such a case an additional
425 64bit tick counter can be implemented as follows. The given example needs GetTick() called at
426 least twice per tick overflow to work properly.
430 uint64_t GetTick(void) {
431 static uint32_t tick_h = 0U;
432 static uint32_t tick_l = 0U;
435 tick = osKernelGetTickCount();
441 return (((uint64_t)tick_h << 32) | tick_l);
446 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
448 \fn uint32_t osKernelGetTickFreq (void)
450 The function \b osKernelGetTickFreq returns the frequency of the current RTOS kernel tick.
452 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
455 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
457 \fn uint32_t osKernelGetSysTimerCount (void)
459 The function \b osKernelGetSysTimerCount returns the current RTOS kernel system timer as a 32-bit value.
460 The value is a rolling 32-bit counter that is composed of the kernel system interrupt timer value
461 and the counter that counts these interrupts (RTOS kernel ticks).
463 This function allows the implementation of very short timeout checks below the RTOS tick granularity.
464 Such checks might be required when checking for a busy status in a device or peripheral initialization
465 routine, see code example below.
467 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
471 #include "cmsis_os2.h"
473 void SetupDevice (void) {
476 // Calculating 100us timeout in system timer ticks
477 const uint32_t timeout = 100U * osKernelGetSysTimerFreq() / 1000000u;
479 tick = osKernelGetSysTimerCount(); // get start value of the Kernel system tick
480 Device.Setup (); // initialize a device or peripheral
481 do { // poll device busy status for 100 microseconds
482 if (!Device.Busy) break; // check if device is correctly initialized
483 } while ((osKernelGetSysTimerCount() - tick) < timeout));
485 ; // in case device still busy, signal error
487 // start interacting with device
493 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
495 \fn uint32_t osKernelGetSysTimerFreq (void)
497 The function \b osKernelGetSysTimerFreq returns the frequency of the current RTOS kernel system timer.
499 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
502 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
504 \fn osStatus_t osKernelProtect (uint32_t safety_class);
506 The function \b osKernelProtect configures kernel access protection. After its successful execution, only threads with
507 safety class equal or higher than the \a safety_class specified in the argument can execute kernel control functions.
509 - \ref osKernelUnlock
510 - \ref osKernelRestoreLock
511 - \ref osKernelSuspend
512 - \ref osKernelResume
513 - \ref osKernelProtect
515 Possible \ref osStatus_t return values:
516 - \em osOK in case of success.
517 - \em osErrorParameter if \a safety_class is invalid.
518 - \em osError if kernel is not in ready or running state.
519 - \em osErrorISR if called from an \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routine".
520 - \em osErrorSafetyClass if the calling thread safety class is lower than the kernel protect safety class.
522 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
526 #include "cmsis_os2.h"
528 void ProtectKernelControlFunctions (void) {
531 status = osKernelProtect(4U); // Enable Kernel Control for threads with safety class 4 or higher
532 // verify status value here.
537 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
539 \fn osStatus_t osKernelDestroyClass (uint32_t safety_class, uint32_t mode);
541 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.
543 If \ref osSafetyWithSameClass is set in \a mode than the RTOS objects with safety class value equal to \a safety_class will be destroyed.
545 If \ref osSafetyWithLowerClass is set in \a mode than the RTOS objects with safety class value lower than \a safety_class will be destroyed.
547 Possible \ref osStatus_t return values:
548 - \em osOK in case of success.
549 - \em osErrorParameter if \a safety_class is invalid.
550 - \em osErrorResource if no other \ref ThreadStates "READY" thread exists.
551 - \em osErrorISR if called from interrupt other than \ref osWatchdogAlarm_Handler.
552 - \em osErrorSafetyClass if the calling thread safety class is lower than the kernel protect safety class.
556 #include "cmsis_os2.h"
558 void DestroyNonCriticalClasses (void) {
561 status = osKernelDestroyClass(4U, osSafetyWithSameClass | osSafetyWithLowerClass); // Destroy objects with safety class 4 or lower
562 // verify status value here.
567 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
569 \fn void osFaultResume (void);
571 Resume normal RTOS operation when exiting exception faults.
575 void HardFault_Handler (void) {
577 "... \n\t" // Enter assembly and handle faults
579 "ldr r0,=osFaultResume \n\t" // Before exiting the handler load and
580 "bx r0 \n\t" // jump to osFaultResume