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();
34 #ifdef RTE_Compiler_EventRecorder
35 // Initialize and start Event Recorder
36 EventRecorderInitialize(EventRecordError, 1U);
40 osKernelInitialize(); // Initialize CMSIS-RTOS
41 osThreadNew(app_main, NULL, NULL); // Create application main thread
42 osKernelStart(); // Start thread execution
48 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
52 Identifies the underlying RTOS kernel and API version number. The version is represented in a combined decimal number in the
53 format: major.minor.rev: mmnnnrrrr
55 Use \ref osKernelGetInfo to retrieve the version numbers.
58 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
62 State of the kernel as retrieved by \ref osKernelGetState. In case \b osKernelGetState fails or if it is called from an ISR,
63 it will return \c osKernelError, otherwise it returns the kernel state.
66 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
68 \fn osStatus_t osKernelInitialize (void)
70 The function \b osKernelInitialize initializes the RTOS Kernel. Before it is successfully executed, only the functions
71 \ref osKernelGetInfo and \ref osKernelGetState may be called.
73 Possible \ref osStatus_t return values:
74 - \em 'osOK', in case of success
75 - \em 'osError', if the kernel is not in state \em 'osRtxKernelInactive'
77 - \em 'osError', if the thread stack size is lower than 64U+8U
79 - \em 'osError', if (osRtxConfig.isr_queue.data == NULL) || (osRtxConfig.isr_queue.max == 0U)
81 - \em 'osErrorISR', if IRQ is masked
83 - \em 'osErrorISR', if in IRQ mode.
86 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
90 #include "RTE_Components.h"
91 #include CMSIS_device_header
92 #include "cmsis_os2.h"
94 /*----------------------------------------------------------------------------
95 * Application main thread
96 *---------------------------------------------------------------------------*/
97 void app_main (void *argument) {
105 // System Initialization
106 SystemCoreClockUpdate();
109 osKernelInitialize(); // Initialize CMSIS-RTOS
110 osThreadNew(app_main, NULL, NULL); // Create application main thread
111 osKernelStart(); // Start thread execution
117 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
119 \fn osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size)
121 The function \b osKernelGetInfo retrieves the API and kernel version of the underlying RTOS kernel and a human readable
122 identifier string for the kernel. It can be safely called before the RTOS is initialized or started (call to
123 \ref osKernelInitialize or \ref osKernelStart).
124 The function shall return the first 'size' characters of of the kernel id in the output parameter id_buf.
126 Possible \ref osStatus_t return values:
127 - \em 'osOK', in case of success
128 - \em 'osErrorISR', if IRQ is masked
129 - \em 'osErrorISR', if in IRQ mode.
131 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
140 status = osKernelGetInfo(&osv, infobuf, sizeof(infobuf));
142 printf("Kernel Information: %s\r\n", infobuf);
143 printf("Kernel Version : %d\r\n", osv.kernel);
144 printf("Kernel API Version: %d\r\n", osv.api);
150 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
152 \fn osKernelState_t osKernelGetState (void)
154 The function \b osKernelGetState returns the current state of the kernel and can be safely called before the RTOS is
155 initialized or started (call to \ref osKernelInitialize or \ref osKernelStart).
157 Possible \ref osKernelState_t return values:
158 - \ref osKernelError, if an unspecific error occurred
159 - the kernel state otherwise.
161 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
166 // System Initialization
167 SystemCoreClockUpdate();
169 if(osKernelGetState() == osKernelInactive) { // Is the kernel initialized?
170 osKernelInitialize(); // Initialize CMSIS-RTOS kernel
177 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
179 \fn osStatus_t osKernelStart (void)
181 The function \b osKernelStart starts the RTOS kernel and begins thread switching. It will not return to its calling function
182 in case of success. Before it is successfully executed, only the functions \ref osKernelGetInfo, \ref osKernelGetState, and
183 object creation functions (\b osXxxNew) may be called.
185 At least one initial thread should be created prior osKernelStart, see \ref osThreadNew.
187 Possible \ref osStatus_t return values:
188 - \em 'osOk', in case of success
189 - \em 'osError', if the kernel is not in state \em 'osRtxKernelReady'
190 - \em 'osError', if no threads are in state \em 'osRtxThreadReady'
191 - \em 'osError', if timer thread or idle thread could not be started
192 - \em 'osError', if the RTOS tick could not be set up
193 - \em 'osErrorISR', if IRQ is masked
194 - \em 'osErrorISR', if in IRQ mode.
197 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
202 // System Initialization
203 SystemCoreClockUpdate();
205 if(osKernelGetState() == osKernelInactive) {
206 osKernelInitialize();
208 ; // ... Start Threads
209 if (osKernelGetState() == osKernelReady) { // If kernel is ready to run...
210 osKernelStart(); // ... start thread execution
213 while(1); // only reached in case of error
218 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
220 \fn int32_t osKernelLock (void)
222 The function \b osKernelLock allows to lock all task switches. It returns the previous value of the lock state (\token{1} if
223 it was locked, \token{0} if it was unlocked), or a negative number representing an error code otherwise (refer to
226 Possible return values:
228 1, if the kernel is locked
230 - \em 0, if the kernel is running
231 - \em 'osErrorISR', if IRQ is masked
233 - \em 'osErrorISR', if in IRQ mode
234 - \em 'osError', if an unspecified error occured.
236 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
240 int32_t state = osKernelLock();
242 osKernelRestore(state);
246 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
248 \fn int32_t osKernelUnlock (void)
250 The function \b osKernelUnlock resumes from \ref osKernelLock. It returns the previous value of the lock state (\token{1} if
251 it was locked, \token{0} if it was unlocked), or a negative number representing an error code otherwise (refer to
254 Possible return values:
255 - \em 1, if the state of the kernel is \em 'osRtxKernelLocked'
256 - \em 0, if the state of the kernel is \em 'osRtxKernelRunning'
257 - \em 'osError', if the kernel is not in state \em 'osRtxKernelLocked' and not in state \em 'osRtxKernelRunning'
258 - \em 'osErrorISR', if IRQ is masked
259 - \em 'osErrorISR', if in IRQ mode.
262 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
266 int32_t sl = osKernelLock();
269 int32_t su = osKernelUnlock();
270 // ... uncritical code
271 osKernelRestoreLock(su);
274 osKernelRestoreLock(sl);
278 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
280 \fn int32_t osKernelRestoreLock (int32_t lock)
282 The function \b osKernelRestoreLock restores the previous lock state after \ref osKernelLock or \ref osKernelUnlock.
284 The argument \a lock specifies the lock state as obtained by \ref osKernelLock or \ref osKernelUnlock.
286 The function returns the new value of the lock state (\token{1} if it was locked, \token{0} if it was unlocked), or a
287 negative number representing an error code otherwise (refer to \ref osStatus_t).
289 Possible return values:
290 - \em '1', if kernel was locked
291 - \em '0', if kernel was not locked
292 - \em 'osError', unspecified error occurred
293 - \em 'osErrorISR', if IRQ is masked
294 - \em 'osErrorISR', if in IRQ mode.
297 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
301 int32_t sl = osKernelLock();
304 int32_t su = osKernelUnlock();
305 // ... uncritical code
306 osKernelRestoreLock(su);
309 osKernelRestoreLock(sl);
313 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
315 \fn uint32_t osKernelSuspend (void)
317 CMSIS-RTOS provides extension for tick-less operation which is useful for applications that use extensively low-power modes
318 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
319 timer intervals. The function \b osKernelSuspend suspends the RTX kernel scheduler and thus enables sleep modes.
321 The return value can be used to determine the amount of system ticks until the next tick-based kernel event will occure, i.e.
322 a delayed thread becomed ready again. It is recommended to set up the low power timer to generate a wake-up interrupt based
323 on this return value.
325 Possible return values:
326 - amount of system ticks, in case of success
327 - \em 'osErrorISR', if IRQ is masked
328 - \em 'osErrorISR', if in IRQ mode.
330 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
334 void osRtxIdleThread (void) {
335 /* The idle thread is running
336 when no other thread is ready
341 /* HERE: include optional user
342 code to be executed when no
344 sleep = osKernelSuspend(); /* Suspend RTX thread scheduler */
346 if (sleep) { /* How long can we sleep? */
347 /* "sleep" is in RTX Timer Ticks
351 /* Setup wake-up e.g. watchdog */
353 __WFE(); /* Enter Power-down mode */
356 sleep = tc; /* Adjust with cycles slept */
359 osKernelResume(sleep); /* Resume thread scheduler */
365 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
367 \fn void osKernelResume (uint32_t sleep_ticks)
369 CMSIS-RTOS provides extension for tick-less operation which is useful for applications that use extensively low-power modes
370 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
371 timer intervals. The function \b osKernelResume enables the RTX kernel scheduler and thus wakes up the system from sleep
374 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
378 void osRtxIdleThread (void) {
379 /* The idle thread is running
380 when no other thread is ready
385 /* HERE: include optional user
386 code to be executed when no
388 sleep = osKernelSuspend(); /* Suspend RTX thread scheduler */
390 if (sleep) { /* How long can we sleep? */
391 /* "sleep" is in RTX Timer Ticks
395 /* Setup wake-up e.g. watchdog */
397 __WFE(); /* Enter Power-down mode */
400 sleep = tc; /* Adjust with cycles slept */
403 osKernelResume(sleep); /* Resume thread scheduler */
409 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
411 \fn uint32_t osKernelGetTickCount (void)
413 The function \b osKernelGetTickCount returns the current RTOS kernel tick count.
415 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
419 #include "cmsis_os2.h"
421 void Thread_1 (void *arg) { // Thread function
424 tick = osKernelGetTickCount(); // retrieve the number of system ticks
426 tick += 1000; // delay 1000 ticks periodically
432 Due to the limited value range used for the tick count it may overflow during runtime,
433 i.e. after 2<sup>32</sup> ticks which are roughly 49days @ 1ms. Typically one has not to
434 take special care of this unless a monotonic counter is needed. For such a case an additional
435 64bit tick counter can be implemented as follows. The given example needs GetTick() called at
436 least twice per tick overflow to work properly.
440 uint64_t GetTick(void) {
441 static uint32_t tick_h = 0U;
442 static uint32_t tick_l = 0U;
445 tick = osKernelGetTickCount();
451 return (((uint64_t)tick_h << 32) | tick_l);
456 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
458 \fn uint32_t osKernelGetTickFreq (void)
460 The function \b osKernelGetTickFreq returns the frequency of the current RTOS kernel tick.
462 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
465 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
467 \fn uint32_t osKernelGetSysTimerCount (void)
469 The function \b osKernelGetSysTimerCount returns the current RTOS kernel system timer as a 32-bit value.
471 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
474 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
476 \fn uint32_t osKernelGetSysTimerFreq (void)
478 The function \b osKernelGetSysTimerFreq returns the frequency of the current RTOS kernel system timer.
480 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
484 // these struct members must stay outside the group to avoid double entries in documentation
486 \var osKernelState_t::osKernelInactive
488 The kernel is not ready yet. \ref osKernelInitialize needs to be executed successfully.
490 \var osKernelState_t::osKernelReady
492 The kernel is not yet running. \ref osKernelStart transfers the kernel to the running state.
494 \var osKernelState_t::osKernelRunning
496 The kernel is initialized and running.
498 \var osKernelState_t::osKernelLocked
500 The kernel was locked with \ref osKernelLock. The functions \ref osKernelUnlock or \ref osKernelRestoreLock unlocks it.
502 \var osKernelState_t::osKernelSuspended
504 The kernel was suspended using \ref osKernelSuspend. The function \ref osKernelResume returns to normal operation.
506 \var osKernelState_t::osKernelError
510 \var osKernelState_t::osKernelReserved