]> begriffs open source - cmsis/blob - CMSIS/DoxyGen/RTOS2/src/cmsis_os2_Thread.txt
RTOS2 Documentation Update
[cmsis] / CMSIS / DoxyGen / RTOS2 / src / cmsis_os2_Thread.txt
1 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2 //  ==== Thread Management ====
3 /** 
4 \addtogroup CMSIS_RTOS_ThreadMgmt Thread Management
5 \ingroup CMSIS_RTOS CMSIS_RTOSv2
6 \brief Define, create, and control thread functions.
7 \details 
8 The Thread Management function group allows defining, creating, and controlling thread functions in the system. The function
9 \b main is a special thread function that is started at system initialization and has the initial priority
10 \a osPriorityNormal.
11
12
13 \anchor ThreadStates
14 Threads can be in the following states:
15
16  - \b RUNNING: The thread that is currently running is in the \b RUNNING state. Only one thread at a time can be in this state.
17
18  - \b READY: Threads which are ready to run are in the \b READY state. Once the \b RUNNING thread has terminated, or is \b BLOCKED, the next \b READY thread with the highest priority becomes the \b RUNNING thread.
19  
20  - \b BLOCKED: Threads that are blocked either delayed, waiting for an event to occur or suspended are in the \b BLOCKED state.
21  
22  - \b TERMINATED: When \ref osThreadTerminate is called, and threads that joined are in \b TERMINATED state. When all joined threads have terminated, resources are released an the threads are in state \b INACTIVE. 
23  
24  - \b INACTIVE: Threads that are not created or have been terminated with all resources released are in the \b INACTIVE state.
25  
26 \image html "ThreadStatus.png" "Thread State and State Transitions"
27
28
29 A CMSIS-RTOS assumes that threads are scheduled as shown in the figure <b>Thread State and State Transitions</b>. The thread
30 states change as follows:
31  - A thread is created using the function \ref osThreadNew. This puts the thread into the \b READY or \b RUNNING state
32    (depending on the thread priority).
33  - CMSIS-RTOS is pre-emptive. The active thread with the highest priority becomes the \b RUNNING thread provided it does not
34    wait for any event. The initial priority of a thread is defined with the \ref osThreadAttr_t but may be changed during
35    execution using the function \ref osThreadSetPriority.
36  - The \b RUNNING thread transfers into the \b BLOCKED state when it is delayed, waiting for an event or suspended.
37  - Active threads can be terminated any time using the function \ref osThreadTerminate. Threads can terminate also by just
38    returning from the thread function. Threads that are terminated are in the \b INACTIVE state and typically do not consume
39    any dynamic memory resources. 
40
41 Thread Examples
42 ===============
43 The following examples show various scenarios to create threads:
44  
45 <b>Example 1 - Create a simple thread</b> 
46
47 Create a thread out of the function thread1 using all default values for thread attributes and memory from the \ref GlobalMemoryPool.
48  
49 \code{.c}
50 __NO_RETURN void thread1 (void *argument) {
51   // ...
52   for (;;) {}
53 }
54  
55 int main (void) {
56   osKernelInitialize();
57   ;
58   osThreadNew(thread1, NULL, NULL);    // Create thread with default settings
59   ;
60   osKernelStart(); 
61 }
62 \endcode
63
64 <b>Example 2 - Create thread with stack non-default stack size</b>
65  
66 Similar to the simple thread all attributes are default. The stack is dynamically allocated from the \ref GlobalMemoryPool
67  
68 \ref osThreadAttr_t.stack_size is used to pass the stack size in Bytes to osThreadNew.
69
70 \code{.c}
71 __NO_RETURN void thread1 (void *argument) {
72   // ...
73   for (;;) {}
74 }
75  
76 const osThreadAttr_t thread1_attr = {
77   .stack_size = 1024;    // Create the thread stack with a size of 1024 bytes
78 }
79  
80 int main (void) {
81   ;  
82   osThreadNew(thread1, NULL, &thread1_attr);    // Create thread with custom sized stack memory
83   ;
84 }
85 \endcode
86
87 <b>Example 3 - Create thread with statically allocated stack</b>
88  
89 Similar to the simple thread all attributes are default. The stack is statically allocated using the uint64_t array thread1_stk_1. This allocates 64*8 Bytes (=512 Bytes) with an alignment of 8 Bytes (mandatory for Cortex-M stack memory). 
90  
91 \ref osThreadAttr_t.stack_mem holds a pointer to the stacks lowest address. 
92  
93 \ref osThreadAttr_t.stack_size is used to pass the stack size in Bytes to osThreadNew.
94
95 \code{.c}
96 __NO_RETURN void thread1 (void *argument) {
97   // ...
98   for (;;) {}
99 }
100  
101 static uint64_t thread1_stk_1[64];
102  
103 const osThreadAttr_t thread1_attr = {
104   .stack_mem  = &thread1_stk_1[0];
105   .stack_size = sizeof(thread1_stk_1);
106 }
107  
108 int main (void) {
109   ;  
110   osThreadNew(thread1, NULL, &thread1_attr);    // Create thread with statically allocated stack memory
111   ;
112 }
113 \endcode
114
115 <b>Example 4 - Thread with statically allocated task control block</b>
116  
117 Typically this method is chosen together with a statically allocated stack as shown in Example 2. 
118 os_<i>object</i>Size macros supply the size of OS objects. 
119 RTX5 has the following internal definitions to determine the size of OS objects:
120 \code{.c}
121 #define os_ThreadCbSize         sizeof(os_thread_t)
122 #define os_TimerCbSize          sizeof(os_timer_t)
123 #define os_EventFlagsCbSize     sizeof(os_event_flags_t)
124 #define os_MutexCbSize          sizeof(os_mutex_t)
125 #define os_SemaphoreCbSize      sizeof(os_semaphore_t)
126 #define os_MemoryPoolCbSize     sizeof(os_memory_pool_t)
127 #define os_MessageQueueCbSize   sizeof(os_message_queue_t)
128 \endcode 
129  
130 Include "rtx_os.h" to access these macros.
131  
132 \code{.c} 
133 #include "rtx_os.h"     //required for os_ThreadCbSize macro definition
134  
135 __NO_RETURN void thread1 (void *argument) {
136   // ...
137   for (;;) {}
138 }
139  
140 static os_thread_t thread1_tcb;
141  
142 const osThreadAttr_t thread1_attr = {
143   .cb_mem  = &thread1_tcb;
144   .cb_size = os_ThreadCbSize;
145 }
146  
147 int main (void) {
148   ;
149   osThreadNew(thread1, NULL, &thread1_attr);    // Create thread with custom tcb memory
150   ;
151 }
152 \endcode
153
154 <b>Example 5 - Create thread with a different priority</b> 
155  
156 The default priority of RTX is \ref osPriorityNormal. Often you want to run a task with a higher or lower priority. Using the \ref osThreadAttr_t control structure you can set any inital priority required.
157
158 \code
159 __NO_RETURN void thread1 (void *argument) {
160   // ...
161   for (;;) {}
162 }
163  
164 const osThreadAttr_t thread1_attr = {
165   .priority = osPriorityHigh  //Set initial thread priority to high   
166
167  
168 int main (void) {
169   ;
170   osThreadNew(thread1, NULL, &thread1_attr);   
171   ;
172 }
173 \endcode
174
175 <b>Example 6 - Joinable threads</b>
176  
177 In this example a master thread creates four threads with the \ref osThreadJoinable attribute. These will do some work and return using the osThreadExit call after finished. \ref osThreadJoin is used to synchronize the thread termination. 
178
179
180 \code{.c} 
181 __NO_RETURN void worker (void *argument) {     
182     ; // work a lot on data[] 
183         osDelay(1000);       
184         osThreadExit();
185 }
186  
187 __NO_RETURN void thread1 (void *argument) {
188   osThreadAttr_t worker_attr = {0};
189   osThreadId_t worker_ids[4];
190   uint8_t data[4][10];
191  
192   worker_attr.attr_bits = osThreadJoinable; 
193   
194   worker_ids[0] = osThreadNew(worker, &data[0][0], &worker_attr);    
195   worker_ids[1] = osThreadNew(worker, &data[1][0], &worker_attr);    
196   worker_ids[2] = osThreadNew(worker, &data[2][0], &worker_attr);    
197   worker_ids[3] = osThreadNew(worker, &data[3][0], &worker_attr);    
198         
199   osThreadJoin(worker_ids[0]);
200   osThreadJoin(worker_ids[1]);
201   osThreadJoin(worker_ids[2]);
202   osThreadJoin(worker_ids[3]);
203                 
204   osThreadExit(); 
205 }
206 \endcode
207
208
209
210
211
212
213    
214 @{
215 */
216 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
217 /**
218 \enum osThreadState_t
219 \details
220
221 */
222 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
223 /**
224 \enum osPriority_t
225 \details
226
227 The \b osPriority_t value specifies the priority for a thread. The default thread priority should be \a osPriorityNormal.
228 If a Thread is active that has a higher priority than the currently executing thread, then a thread switch occurs immediately
229 to execute the new task.
230
231 To prevent from a priority inversion, a CMSIS-RTOS compliant OS may optionally implement a <b>priority inheritance</b> method.
232 A priority inversion occurs when a high priority thread is waiting for a resource or event that is controlled by a thread
233 with a lower priority. 
234
235 \note 
236 Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
237
238 */
239 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
240 /**
241 \typedef void *(*os_thread_func_t) (void *argument)
242 \details
243
244
245 */
246 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
247 /**
248 \typedef osThreadId_t
249
250 */
251 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
252 /**
253 \struct osThreadAttr_t
254
255 */
256 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
257 /**
258 \def osThreadJoinable
259 \details
260
261 */
262 /**
263 \def osThreadDetached
264 \details
265
266 */
267 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
268 /**
269 \fn osThreadId_t osThreadNew (os_thread_func_t func, void *argument, const osThreadAttr_t *attr)
270 \details
271
272 Start a thread function by adding it to the Active Threads list and set it to state \b READY. Arguments for the thread function are passed
273 using the parameter pointer \em *argument. When the priority of the created thread function is higher than the current \b RUNNING thread, 
274 the created thread function starts instantly and becomes the new \b RUNNING thread. Thread attributes are defined with the parameter pointer \em attr.
275 Attributes include settings for thread priority, stack size, or memory allocation.
276
277 \note
278 Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
279
280
281 */
282 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
283 /**
284 \fn const char *osThreadGetName (osThreadId_t thread_id)
285 \details
286
287 */
288
289 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
290 /**
291 \fn osThreadId_t osThreadGetId (void)
292 \details
293
294 Get the thread ID of the current running thread.
295
296 \note
297 Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
298
299 \b Example:
300 \code{.c}
301 void ThreadGetId_example (void)  {
302   osThreadId id;                                           // id for the currently running thread
303    
304   id = osThreadGetId ();
305   if (id == NULL) {
306     // Failed to get the id; not in a thread
307   }
308 }
309 \endcode
310 */
311 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
312 /**
313 \fn osThreadState_t osThreadGetState (osThreadId_t thread_id)
314 \details
315
316 Return the state of the thread identified by parameter \em thread_id.
317 See \ref osThreadState_t for possible states.
318
319 */
320 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
321 /**
322 \fn osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority)
323 \details
324
325 Change the priority of an active thread.
326
327 \ref osStatus_t return values:
328     - \em osOK: the priority of the specified thread has been changed successfully.
329     - \em osErrorParameter: the value of the parameter \em thread_id or parameter \em priority is incorrect.
330     - \em osErrorResource: parameter \em thread_id refers to a thread that is not an active thread.
331     - \em osErrorISR: the function \b osThreadSetPriority cannot be called from interrupt service routines.
332
333 \note
334 Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
335
336 \b Example:
337 \code{.c}
338 #include "cmsis_os2.h"
339  
340 void Thread_1 (void const *arg)  {                         // Thread function
341   osThreadId_t id;                                         // id for the currently running thread
342   osStatus   status;                                       // status of the executed function
343    
344   :  
345   id = osThreadGetId ();                                   // Obtain ID of current running thread
346    
347   if (id != NULL) {
348     status = osThreadSetPriority (id, osPriorityBelowNormal);
349     if (status == osOK)  {
350       // Thread priority changed to BelowNormal
351     }
352     else {
353       // Failed to set the priority
354     }
355   }
356   else  {
357     // Failed to get the id
358   }
359   :  
360 }
361 \endcode
362 */
363 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
364 /**
365 \fn osPriority_t osThreadGetPriority (osThreadId_t thread_id)
366 \details
367
368 Get the priority of an active thread. In case of failure, the value \b osPriorityError is returned.
369
370 \note
371 Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
372
373 \b Example:
374 \code{.c}
375 #include "cmsis_os2.h"
376  
377 void Thread_1 (void const *arg)  {                         // Thread function
378   osThreadId_t id;                                         // id for the currently running thread
379   osPriority_t priority;                                   // thread priority
380    
381   id = osThreadGetId ();                                   // Obtain ID of current running thread
382    
383   if (id != NULL)  {
384     priority = osThreadGetPriority (id);
385   }
386   else  {
387     // Failed to get the id
388   }
389 }
390 \endcode
391 */
392 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
393 /**
394 \fn osStatus_t osThreadYield (void)
395 \details
396
397 Pass control to the next thread that is in state \b READY. If there is no other thread in state \b READY, 
398 then the current thread continues execution and no thread switching occurs.
399
400 \note
401 Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
402
403 \b Example:
404 \code{.c}
405 #include "cmsis_os2.h"
406  
407 void Thread_1 (void const *arg)  {                         // Thread function
408   osStatus_t   status;                                     // status of the executed function
409   :
410   while (1)  {
411     status = osThreadYield();                              // 
412     if (status != osOK)  {
413       // thread switch not occurred, not in a thread function
414     }
415   }
416 }
417 \endcode
418 */
419 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
420 /**
421 \fn osStatus_t osThreadSuspend (osThreadId_t thread_id)
422 \details
423 Suspends execution of the thread identified by parameter \em thread_id. Thread is put into the state \em Blocked (\ref osThreadBlocked).
424 The thread is not executed until restarted with the function \ref osThreadResume.
425
426 */
427 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
428 /**
429 \fn osStatus_t osThreadResume (osThreadId_t thread_id)
430 \details
431 Forces a thread in BLOCKED state, specified with \em thread_id, to resume operation. 
432 Functions that will put a thread into BLOCKED state are:
433 \ref osEventFlagsWait and \ref osThreadFlagsWait,
434 \ref osDelay and \ref osDelayUntil,
435 \ref osMutexAcquire and \ref osSemaphoreAcquire,
436 \ref osMessageQueueGet,
437 \ref osThreadJoin,
438 \ref osThreadSuspend.
439
440 */
441 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
442 /**
443 \fn osStatus_t osThreadDetach (osThreadId_t thread_id)
444 \details
445 Changes the attribute of a thread specified in \em thread_id to \ref osThreadDetached. Detached threads are not joinable with \ref osThreadJoin. 
446 When a detached thread is terminated all resources are returned to the system. The behaviour of \ref osThreadDetach on an already detached thread is undefined.
447
448 \todo : describe
449
450 \note
451 Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
452 */
453 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
454 /**
455 \fn osStatus_t osThreadJoin (osThreadId_t thread_id)
456 \details
457 Waits for the thread specified by \em thread_id to terminate. 
458 If that thread has already terminated, then \ref osThreadJoin returns immediately.  
459 The thread referred to by thread_id must joinable. By default threads are created with the attribute \ref osThreadJoinable. The thread may not have been detached by \ref osThreadDetach.
460
461 \note
462 Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
463
464 \todo See Example 5
465
466 */
467 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
468 /**
469 \fn __NO_RETURN void osThreadExit (void)
470 \details
471
472 osThreadExit terminates the calling thread. This allows the thread to be synchronized with osThreadJoin. 
473
474 \note
475 Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
476 */
477 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
478 /**
479 \fn osStatus_t osThreadTerminate (osThreadId_t thread_id)
480 \details
481 Remove the thread function from the active thread list. If the thread is currently /b RUNNING the execution stops and the thread
482 terminates.
483
484 \note
485 Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
486
487 \code
488 #include "cmsis_os2.h"
489  
490 void *Thread_1 (void c*arg);                           // function prototype for Thread_1
491
492 void ThreadTerminate_example (void) {
493   osStatus_t status;
494   osThreadId_t id;
495  
496   id = osThreadNew (Thread_1, NULL, NULL);             // create the thread
497   :  
498   status = osThreadTerminate (id);                     // stop the thread
499   if (status == osOK) {
500     // Thread was terminated successfully
501   }
502   else {
503     // Failed to terminate a thread
504   }
505 }
506 \endcode
507 */
508 /// @}
509
510
511 // these struct members must stay outside the group to avoid double entries in documentation
512 /**
513 \var osThreadAttr_t::attr_bits
514 \details
515 The following predefined bit masks can be assigned to set options for a thread object.
516
517 Bit Mask                |   Description
518 :-----------------------|:-----------------------------------------
519 osThreadJoinable        | Thread is created in a join-able state (default).
520 osThreadDettached       | Thread is created in a detached state.
521
522 \var osThreadAttr_t::cb_mem
523 \details
524 Pointer to a memory location for the thread object. This can optionally be used for custom memory management systems. 
525 Specify \token{NULL} to use the kernel memory management.
526
527 \var osThreadAttr_t::cb_size
528 \details
529 The size of the memory block passed with \ref cb_mem. Must be the size of a thread control block object or larger.
530
531 \var osThreadAttr_t::name
532 \details
533 String with a human readable name of the thread object.
534
535 \var osThreadAttr_t::priority
536 \details
537 Specifies the initial thread priority with a value from #osPriority_t.
538
539 \var osThreadAttr_t::reserved
540 \details
541 Reserved for future use. Must be \token{0}.
542
543 \var osThreadAttr_t::stack_mem
544 \details
545 Pointer to a memory location for the thread stack. This can optionally be used for custom memory management systems. 
546 Specify \token{NULL} to use the kernel memory management.
547
548 \var osThreadAttr_t::stack_size
549 \details
550 The size of the stack specified by \ref stack_mem in Bytes.
551
552 */