1/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 2// ==== Thread Flags Management ==== 3/** 4\addtogroup CMSIS_RTOS_ThreadFlagsMgmt Thread Flags 5\ingroup CMSIS_RTOS 6\brief Synchronize threads using flags. 7\details 8Thread Flags are a more specialized version of the Event Flags. See \ref CMSIS_RTOS_EventFlags. 9While Event Flags can be used to globally signal a number of threads, thread flags are only sent to a single specific thread. 10Every thread instance can receive thread flags without any additional allocation of a thread flags object. 11 12\note Thread flag management functions cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines", except 13for \ref osThreadFlagsSet. 14 15<b>Usage Example</b> 16 17The following (incomplete) code excerpt sketches the usage principals for <b>Thread Flags</b>. 18 19The behavior is the following: 20- app_main starts executing 21- statement A sets thread flags to 0x02 (flags = 0x02 – after set) 22- app_main enters delay 23- execution switches to threadX 24- statement B waits for flag 0x01 and blocks since flag is not set 25- execution switches to app_main 26- statement C sets thread flags to 0x07 27- threadX wakes-up and clears flag 0x01, thread flags = 0x06, return value set to 0x07 (before clear), note: all this happens during statement C 28- statement C returns with flags = 0x06 29- app_main enters delay 30- execution switches to threadX 31- statement B returns with flagsX = 0x07 32 33\code 34#include "cmsis_os2.h" 35 36osThreadId_t tid; 37uint32_t flagsX; 38uint32_t flags; 39 40void threadX (void *argument) { 41 42 osDelay(1U); 43 for (;;) { 44 flagsX = osThreadFlagsWait(0x0001U, osFlagsWaitAny, osWaitForever); /* B */ 45 } 46} 47 48void app_main (void *argument) { 49 50 tid = osThreadNew(threadX, NULL, NULL); 51 52 flags = osThreadFlagsSet(tid, 0x0002U); /* A */ 53 osDelay(2U); 54 flags = osThreadFlagsSet(tid, 0x0005U); /* C */ 55 osDelay(2U); 56 57 for(;;); 58} 59\endcode 60 61@{ 62*/ 63 64/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 65/** \fn uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags ) 66The function \b osThreadFlagsSet sets the thread flags for a thread specified by parameter \em thread_id. The thread returns 67the flags stored in the thread control block, or an error code if highest bit is set (refer to \ref flags_error_codes). 68Refer to \b Usage \b Examples below to understand how the return value is computed. 69 70The target thread waiting for a flag to be set will resume from \ref ThreadStates "BLOCKED" state. 71 72Possible \ref flags_error_codes return values: 73 - \em osFlagsErrorUnknown: unspecified error. 74 - \em osFlagsErrorParameter: parameter \em thread_id is not a valid thread or \em flags has highest bit set. 75 - \em osFlagsErrorResource: the thread is in invalid state. 76 - \em osFlagsErrorSafetyClass: the calling thread safety class is lower than the safety class of the specified thread. 77 78\note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 79 80\b Code \b Example 81\code 82/*---------------------------------------------------------------------------- 83 * Function 'signal_func' called from multiple threads 84 *---------------------------------------------------------------------------*/ 85void signal_func (osThreadId_t tid) { 86 osThreadFlagsSet(tid_clock, 0x0100U); /* set signal to clock thread */ 87 osDelay(500U); /* delay 500ms */ 88 osThreadFlagsSet(tid_clock, 0x0100U); /* set signal to clock thread */ 89 osDelay(500U); /* delay 500ms */ 90 osThreadFlagsSet(tid, 0x0001U); /* set signal to thread 'thread' */ 91 osDelay(500U); /* delay 500ms */ 92} 93\endcode 94 95\b Usage \b Examples 96 97The following diagram assumes that in the control block of Thread1 the flag 1 is already set. Thread2 now sets flag 2 and 98Thread1 returns the updated value immediately: 99 100\msc 101 a [label="", textcolor="indigo", linecolor="indigo", arclinecolor="red"], 102 b [label="", textcolor="blue", linecolor="blue", arclinecolor="blue"]; 103 104 a note a [label="Thread1", textbgcolour="#FFCCCF"], 105 b note b [label="Thread2", textbgcolour="#E0E0FF"]; 106 107 a box a [label = "Flags == 1"]; 108 a<-b [label = "osThreadFlagsSet(2)"]; 109 a>>b [label = "return(3)"]; 110 a->a [label = "while(1)"]; 111\endmsc 112 113Depending on thread scheduling, the flag status can be modified before returning: 114 115\msc 116 a [label="", textcolor="indigo", linecolor="indigo", arclinecolor="red"], 117 b [label="", textcolor="blue", linecolor="blue", arclinecolor="blue"]; 118 119 a note a [label="Thread1", textbgcolour="#FFCCCF"], 120 b note b [label="Thread2", textbgcolour="#E0E0FF"]; 121 122 b box b [label = "Flags == 0"]; 123 b->b [label = "osThreadFlagsWait(1)"]; 124 b box b [label = "thread state = blocked"]; 125 a->b [label = "osThreadFlagsSet(1)"]; 126 b box b [label = "Flags == 1"]; 127 b box b [label = "thread state = ready"]; 128 b box b [label = "Flags == 0*"]; 129 --- [label = "If Thread2 priority > Thread1 priority, it gets scheduled immediately"]; 130 b->b [label = "return(1)"]; 131 b->b [label = "osThreadFlagsWait(1)"]; 132 b box b [label = "thread state = blocked"]; 133 --- [label = "endif"]; 134 b->a [label = "return(0)"]; 135\endmsc 136\note * In this case \ref osThreadFlagsWait auto-clears the flag. 137*/ 138 139/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 140/** \fn uint32_t osThreadFlagsClear (uint32_t flags) 141\details 142The function \b osThreadFlagsClear clears the specified flags for the currently running thread. It returns the 143flags before clearing, or an error code if highest bit is set (refer to \ref flags_error_codes). 144 145Possible \ref flags_error_codes return values: 146 - \em osFlagsErrorUnknown: unspecified error, i.e. not called from a running threads context. 147 - \em osFlagsErrorParameter: parameter \em flags has highest bit set. 148 - \em osFlagsErrorISR: the function \b osThreadFlagsClear cannot be called from interrupt service routines. 149 150\note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 151*/ 152 153/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 154/** \fn uint32_t osThreadFlagsGet (void) 155\details 156The function \b osThreadFlagsGet returns the flags currently set for the currently running thread. 157If called without a active and currently running thread \b osThreadFlagsGet return zero. 158 159\note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 160*/ 161 162/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 163/** \fn uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) 164The function \b osThreadFlagsWait suspends the execution of the currently \ref ThreadStates "RUNNING" thread until any or all of the thread 165flags specified with the parameter \a flags are set. When these thread flags are already set, the function returns instantly. 166Otherwise the thread is put into the state \ref ThreadStates "BLOCKED". 167 168The parameter \em options specifies the wait condition: 169|Option | | 170|--------------------|-------------------------------------------------------| 171|\b osFlagsWaitAny | Wait for any flag (default). | 172|\b osFlagsWaitAll | Wait for all flags. | 173|\b osFlagsNoClear | Do not clear flags which have been specified to wait for. | 174 175If \c osFlagsNoClear is set in the options \ref osThreadFlagsClear can be used to clear flags manually. 176Otherwise \b osThreadFlagsWait automatically clears the flags waited for. 177 178The parameter \ref CMSIS_RTOS_TimeOutValue "timeout" represents a number of timer ticks and is an upper bound. The 179exact time delay depends on the actual time elapsed since the last timer tick. 180 181The function returns the flags before clearing, or an error code if highest bit is set (refer to \ref flags_error_codes). 182 183Possible \ref flags_error_codes return values: 184 - \em osFlagsErrorUnknown: unspecified error, i.e. not called from a running threads context. 185 - \em osFlagsErrorTimeout: awaited flags have not been set in the given time. 186 - \em osFlagsErrorResource: awaited flags have not been set when no \a timeout was specified. 187 - \em osFlagsErrorParameter: Parameter \em flags has highest bit set. 188 189\note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 190 191<b>Code Example</b> 192\code 193#include "cmsis_os2.h" 194 195void Thread (void* arg) { 196 ; 197 osThreadFlagsWait(0x00000001U, osFlagsWaitAny, osWaitForever); // Wait forever until thread flag 1 is set. 198 ; 199 osThreadFlagsWait(0x00000003U, osFlagsWaitAny, osWaitForever); // Wait forever until either thread flag 0 or 1 is set. 200 ; 201 osThreadFlagsWait(0x00000003U, osFlagsWaitAll, 10U); // Wait for 10 timer ticks until thread flags 0 and 1 are set. Timeout afterwards. 202 ; 203 osThreadFlagsWait(0x00000003U, osFlagsWaitAll | osFlagsNoClear, osWaitForever); // Same as the above, but the flags will not be cleared. 204} 205\endcode 206*/ 207/// @} 208