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