FreeRTOS Reference Manual V10.0.0
FreeRTOS Reference Manual V10.0.0
Reference Manual
The FreeRTOS™
Reference Manual
© Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
http://www.FreeRTOS.org
http://www.FreeRTOS.org/plus
http://www.FreeRTOS.org/labs
Contents
Contents ................................................................................................................................... 5
v
2.10 pcTaskGetName() ..................................................................................................... 91
2.11 xTaskGetTickCount() ................................................................................................ 92
2.12 xTaskGetTickCountFromISR() .................................................................................. 94
2.13 vTaskList()................................................................................................................. 96
2.14 xTaskNotify() ............................................................................................................. 99
2.15 xTaskNotifyAndQuery() ........................................................................................... 102
2.16 xTaskNotifyAndQueryFromISR() ............................................................................. 106
2.17 xTaskNotifyFromISR() ............................................................................................. 110
2.18 xTaskNotifyGive() .................................................................................................... 115
2.19 vTaskNotifyGiveFromISR() ...................................................................................... 118
2.20 xTaskNotifyStateClear() .......................................................................................... 121
2.21 ulTaskNotifyTake() .................................................................................................. 123
2.22 xTaskNotifyWait() .................................................................................................... 126
2.23 uxTaskPriorityGet() ................................................................................................. 129
2.24 vTaskPrioritySet() .................................................................................................... 131
2.25 vTaskResume() ....................................................................................................... 133
2.26 xTaskResumeAll() ................................................................................................... 135
2.27 xTaskResumeFromISR() ......................................................................................... 138
2.28 vTaskSetApplicationTaskTag() ................................................................................ 141
2.29 vTaskSetThreadLocalStoragePointer() .................................................................... 143
2.30 vTaskSetTimeOutState() ......................................................................................... 145
2.31 vTaskStartScheduler() ............................................................................................. 147
2.32 vTaskStepTick() ...................................................................................................... 149
2.33 vTaskSuspend() ...................................................................................................... 151
2.34 vTaskSuspendAll() .................................................................................................. 153
2.35 taskYIELD() ............................................................................................................. 155
vi
3.17 xQueueReceiveFromISR() ...................................................................................... 189
3.18 xQueueRemoveFromSet() ...................................................................................... 192
3.19 xQueueReset()........................................................................................................ 194
3.20 xQueueSelectFromSet().......................................................................................... 195
3.21 xQueueSelectFromSetFromISR() ........................................................................... 197
3.22 xQueueSend(), xQueueSendToFront(), xQueueSendToBack()............................... 199
3.23 xQueueSendFromISR(), xQueueSendToBackFromISR(),
xQueueSendToFrontFromISR() .............................................................................. 202
3.24 uxQueueSpacesAvailable() ..................................................................................... 206
vii
5.8 xTimerReset() ......................................................................................................... 283
5.9 xTimerResetFromISR() ........................................................................................... 286
5.10 vTimerSetTimerID() ................................................................................................. 288
5.11 xTimerStart() ........................................................................................................... 290
5.12 xTimerStartFromISR() ............................................................................................. 292
5.13 xTimerStop() ........................................................................................................... 294
5.14 xTimerStopFromISR() ............................................................................................. 296
viii
9.4 xMessageBufferIsEmpty() ....................................................................................... 378
9.5 xMessageBufferIsFull() ........................................................................................... 379
9.6 xMessageBufferReceive() ....................................................................................... 380
9.7 xMessageBufferReceiveFromISR() ......................................................................... 383
9.8 xMessageBufferReset() .......................................................................................... 386
9.9 xMessageBufferSend() ........................................................................................... 387
9.10 xMessageBufferSendFromISR() ............................................................................. 390
9.11 xMessageBufferSpacesAvailable() .......................................................................... 393
List of Figures
ix
List of Code Listings
x
Listing 40 uxTaskGetNumberOfTasks() function prototype ..................................................... 73
Listing 41 vTaskGetRunTimeStats() function prototype .......................................................... 74
Listing 42 Example macro definitions, taken from the LM3Sxxx Eclipse Demo ....................... 76
Listing 43 Example macro definitions, taken from the LPC17xx Eclipse Demo ....................... 77
Listing 44 Example use of vTaskGetRunTimeStats() .............................................................. 77
Listing 45 xTaskGetSchedulerState() function prototype......................................................... 78
Listing 46 Example use of uxTaskGetStackHighWaterMark() ................................................. 80
Listing 47 eTaskGetState() function prototype ........................................................................ 81
Listing 48 uxTaskGetSystemState() function prototype ........................................................... 83
Listing 49 Example use of uxTaskGetSystemState() .............................................................. 85
Listing 50 The TaskStatus_t definition .................................................................................... 86
Listing 51 vTaskGetTaskInfo() function prototype ................................................................... 87
Listing 52 Example use of vTaskGetTaskInfo() ....................................................................... 88
Listing 53 pvTaskGetThreadLocalStoragePointer() function prototype.................................... 89
Listing 54 Example use of pvTaskGetThreadLocalStoragePointer() ....................................... 90
Listing 55 pcTaskGetName() function prototype ..................................................................... 91
Listing 56 xTaskGetTickCount() function prototype ................................................................. 92
Listing 57 Example use of xTaskGetTickCount()..................................................................... 93
Listing 58 xTaskGetTickCountFromISR() function prototype ................................................... 94
Listing 59 Example use of xTaskGetTickCountFromISR() ...................................................... 95
Listing 60 vTaskList() function prototype ................................................................................. 96
Listing 61 Example use of vTaskList()..................................................................................... 98
Listing 62 xTaskNotify() function prototype ............................................................................. 99
Listing 63 Example use of xTaskNotify() ............................................................................... 101
Listing 64 xTaskNotifyAndQuery() function prototype ........................................................... 102
Listing 65 Example use of xTaskNotifyAndQuery() ............................................................... 105
Listing 66 xTaskNotifyAndQueryFromISR() function prototype ............................................. 106
Listing 67 Example use of xTaskNotifyAndQueryFromISR() ................................................. 109
Listing 68 xTaskNotifyFromISR() function prototype ............................................................. 110
Listing 69 Example use of xTaskNotifyFromISR() ................................................................. 114
Listing 70 xTaskNotifyGive() function prototype .................................................................... 115
Listing 71 Example use of xTaskNotifyGive() ........................................................................ 117
Listing 72 vTaskNotifyGiveFromISR() function prototype ...................................................... 118
Listing 73 Example use of vTaskNotifyGiveFromISR() .......................................................... 120
Listing 74 xTaskNotifyStateClear() function prototype ........................................................... 121
Listing 75 Example use of xTaskNotifyStateClear() .............................................................. 122
Listing 76 ulTaskNotifyTake() function prototype................................................................... 123
Listing 77 Example use of ulTaskNotifyTake() ...................................................................... 125
Listing 78 xTaskNotifyWait() function prototype .................................................................... 126
Listing 79 Example use of xTaskNotifyWait() ........................................................................ 128
Listing 80 uxTaskPriorityGet() function prototype .................................................................. 129
Listing 81 Example use of uxTaskPriorityGet() ..................................................................... 130
Listing 82 vTaskPrioritySet() function prototype .................................................................... 131
xi
Listing 83 Example use of vTaskPrioritySet() ........................................................................ 132
Listing 84 vTaskResume() function prototype ....................................................................... 133
Listing 85 Example use of vTaskResume() ........................................................................... 134
Listing 86 xTaskResumeAll() function prototype.................................................................... 135
Listing 87 Example use of xTaskResumeAll() ....................................................................... 137
Listing 88 xTaskResumeFromISR() function prototype ......................................................... 138
Listing 89 Example use of xTaskResumeFromISR() ............................................................. 140
Listing 90 vTaskSetApplicationTaskTag() function prototype ................................................ 141
Listing 91 Example use of vTaskSetApplicationTaskTag() .................................................... 142
Listing 92 vTaskSetThreadLocalStoragePointer() function prototype .................................... 143
Listing 93 Example use of vTaskSetThreadLocalStoragePointer() ........................................ 144
Listing 94 vTaskSetTimeOutState() function prototype.......................................................... 145
Listing 95 Example use of vTaskSetTimeOutState() and xTaskCheckForTimeOut() ............. 146
Listing 96 vTaskStartScheduler() function prototype ............................................................. 147
Listing 97 Example use of vTaskStartScheduler() ................................................................. 148
Listing 98 Example use of vTaskStepTick() ........................................................................... 150
Listing 99 vTaskSuspend() function prototype ....................................................................... 151
Listing 100 Example use of vTaskSuspend() ........................................................................ 152
Listing 101 vTaskSuspendAll() function prototype ................................................................. 153
Listing 102 Example use of vTaskSuspendAll()..................................................................... 154
Listing 103 taskYIELD() macro prototype .............................................................................. 155
Listing 104 Example use of taskYIELD() ............................................................................... 156
Listing 105 vQueueAddToRegistry() function prototype ........................................................ 158
Listing 106 Example use of vQueueAddToRegistry() ............................................................ 159
Listing 107 xQueueAddToSet() function prototype ................................................................ 160
Listing 108 xQueueCreate() function prototype ..................................................................... 162
Listing 109 Example use of xQueueCreate() ......................................................................... 163
Listing 110 xQueueCreateSet() function prototype ................................................................ 164
Listing 111 Example use of xQueueCreateSet() and other queue set API functions ............. 167
Listing 112 xQueueCreateStatic() function prototype ............................................................ 168
Listing 113 Example use of xQueueCreateStatic() ................................................................ 169
Listing 114 vQueueDelete() function prototype...................................................................... 170
Listing 115 Example use of vQueueDelete() ......................................................................... 171
Listing 116 pcQueueGetName() function prototype ............................................................... 172
Listing 117 xQueueIsQueueEmptyFromISR() function prototype .......................................... 173
Listing 118 xQueueIsQueueFullFromISR() function prototype............................................... 174
Listing 119 uxQueueMessagesWaiting() function prototype .................................................. 175
Listing 120 Example use of uxQueueMessagesWaiting()...................................................... 175
Listing 121 uxQueueMessagesWaitingFromISR() function prototype .................................... 176
Listing 122 Example use of uxQueueMessagesWaitingFromISR()........................................ 177
Listing 123 xQueueOverwrite() function prototype ................................................................. 178
Listing 124 Example use of xQueueOverwrite() .................................................................... 179
Listing 125 xQueueOverwriteFromISR() function prototype................................................... 180
xii
Listing 126 Example use of xQueueOverwriteFromISR() ...................................................... 181
Listing 127 xQueuePeek() function prototype ....................................................................... 182
Listing 128 Example use of xQueuePeek() ........................................................................... 184
Listing 129 xQueuePeekFromISR() function prototype ......................................................... 185
Listing 130 xQueueReceive() function prototype ................................................................... 186
Listing 131 Example use of xQueueReceive() ...................................................................... 188
Listing 132 xQueueReceiveFromISR() function prototype ..................................................... 189
Listing 133 Example use of xQueueReceiveFromISR() ........................................................ 191
Listing 134 xQueueRemoveFromSet() function prototype ..................................................... 192
Listing 135 Example use of xQueueRemoveFromSet() ........................................................ 193
Listing 136 xQueueReset() function prototype ...................................................................... 194
Listing 137 xQueueSelectFromSet() function prototype ........................................................ 195
Listing 138 xQueueSelectFromSetFromISR() function prototype .......................................... 197
Listing 139 Example use of xQueueSelectFromSetFromISR() .............................................. 198
Listing 140 xQueueSend(), xQueueSendToFront() and xQueueSendToBack() function
prototypes ...................................................................................................... 199
Listing 141 Example use of xQueueSendToBack() ............................................................... 201
Listing 142 xQueueSendFromISR(), xQueueSendToBackFromISR() and
xQueueSendToFrontFromISR() function prototypes ...................................... 202
Listing 143 Example use of xQueueSendToBackFromISR() ................................................. 205
Listing 144 uxQueueSpacesAvailable() function prototype ................................................... 206
Listing 145 Example use of uxQueueSpacesAvailable() ....................................................... 206
Listing 146 vSemaphoreCreateBinary() macro prototype ...................................................... 209
Listing 147 Example use of vSemaphoreCreateBinary() ....................................................... 211
Listing 148 xSemaphoreCreateBinary() function prototype ................................................... 212
Listing 149 Example use of xSemaphoreCreateBinary() ....................................................... 214
Listing 150 xSemaphoreCreateBinaryStatic() function prototype .......................................... 215
Listing 151 Example use of xSemaphoreCreateBinaryStatic() .............................................. 217
Listing 152 xSemaphoreCreateCounting() function prototype ............................................... 218
Listing 153 Example use of xSemaphoreCreateCounting() ................................................... 220
Listing 154 xSemaphoreCreateCountingStatic() function prototype ...................................... 221
Listing 155 Example use of xSemaphoreCreateCountingStatic() .......................................... 223
Listing 156 xSemaphoreCreateMutex() function prototype .................................................... 224
Listing 157 Example use of xSemaphoreCreateMutex() ....................................................... 225
Listing 158 xSemaphoreCreateMutexStatic() function prototype ........................................... 226
Listing 159 Example use of xSemaphoreCreateMutexStatic() .............................................. 227
Listing 160 xSemaphoreCreateRecursiveMutex() function prototype .................................... 228
Listing 161 Example use of xSemaphoreCreateRecursiveMutex() ........................................ 230
Listing 162 xSemaphoreCreateRecursiveMutexStatic() function prototype ........................... 231
Listing 163 Example use of xSemaphoreCreateRecursiveMutexStatic() ............................... 232
Listing 164 vSemaphoreDelete() function prototype .............................................................. 233
Listing 165 uxSemaphoreGetCount() function prototype ....................................................... 234
Listing 166 xSemaphoreGetMutexHolder() function prototype .............................................. 235
Listing 167 xSemaphoreGive() function prototype................................................................. 236
xiii
Listing 168 Example use of xSemaphoreGive()..................................................................... 237
Listing 169 xSemaphoreGiveFromISR() function prototype ................................................... 238
Listing 170 Example use of xSemaphoreGiveFromISR() ...................................................... 240
Listing 171 xSemaphoreGiveRecursive() function prototype ................................................. 241
Listing 172 Example use of xSemaphoreGiveRecursive() ..................................................... 243
Listing 173 xSemaphoreTake() function prototype ................................................................ 244
Listing 174 Example use of xSemaphoreTake() .................................................................... 246
Listing 175 xSemaphoreTakeFromISR() function prototype .................................................. 247
Listing 176 xSemaphoreTakeRecursive() function prototype................................................. 249
Listing 177 Example use of xSemaphoreTakeRecursive() .................................................... 251
Listing 178 xTimerChangePeriod() function prototype ........................................................... 254
Listing 179 Example use of xTimerChangePeriod() .............................................................. 256
Listing 180 xTimerChangePeriodFromISR() function prototype ............................................. 257
Listing 181 Example use of xTimerChangePeriodFromISR() ................................................ 258
Listing 182 xTimerCreate() function prototype ....................................................................... 259
Listing 183 The timer callback function prototype .................................................................. 260
Listing 184 Definition of the callback function used in the calls to xTimerCreate() in
Listing 185 ..................................................................................................... 261
Listing 185 Example use of xTimerCreate() .......................................................................... 262
Listing 186 xTimerCreateStatic() function prototype .............................................................. 263
Listing 187 The timer callback function prototype .................................................................. 264
Listing 188 Definition of the callback function used in the calls to xTimerCreate() in
Listing 185 ..................................................................................................... 265
Listing 189 Example use of xTimerCreateStatic().................................................................. 266
Listing 190 xTimerDelete() macro prototype .......................................................................... 267
Listing 191 xTimerGetExpiryTime() function prototype .......................................................... 269
Listing 192 Example use of xTimerGetExpiryTime() .............................................................. 270
Listing 193 pcTimerGetName() function prototype ................................................................ 271
Listing 194 xTimerGetPeriod() function prototype ................................................................. 272
Listing 195 Example use of xTimerGetPeriod() ..................................................................... 272
Listing 196 xTimerGetTimerDaemonTaskHandle() function prototype .................................. 273
Listing 197 pvTimerGetTimerID() function prototype ............................................................. 274
Listing 198 Example use of pvTimerGetTimerID() ................................................................. 275
Listing 199 xTimerIsTimerActive() function prototype ............................................................ 276
Listing 200 Example use of xTimerIsTimerActive() ................................................................ 277
Listing 201 xTimerPendFunctionCall() function prototype ..................................................... 278
Listing 202 The prototype of a function that can be pended using a call to
xTimerPendFunctionCall().............................................................................. 278
Listing 203 xTimerPendFunctionCallFromISR() function prototype ....................................... 280
Listing 204 The prototype of a function that can be pended using a call to
xTimerPendFunctionCallFromISR() ............................................................... 280
Listing 205 Example use of xTimerPendFunctionCallFromISR() ........................................... 282
Listing 206 xTimerReset() function prototype ........................................................................ 283
Listing 207 Example use of xTimerReset() ............................................................................ 285
xiv
Listing 208 xTimerResetFromISR() function prototype .......................................................... 286
Listing 209 Example use of xTimerResetFromISR() ............................................................. 287
Listing 210 vTimerSetTimerID() function prototype ............................................................... 288
Listing 211 Example use of vTimerSetTimerID() ................................................................... 289
Listing 212 xTimerStart() function prototype.......................................................................... 290
Listing 213 xTimerStartFromISR() macro prototype .............................................................. 292
Listing 214 Example use of xTimerStartFromISR() ............................................................... 293
Listing 215 xTimerStop() function prototype .......................................................................... 294
Listing 216 xTimerStopFromISR() function prototype ............................................................ 296
Listing 217 Example use of xTimerStopFromISR() ............................................................... 297
Listing 218 xEventGroupClearBits() function prototype ......................................................... 299
Listing 219 Example use of xEventGroupClearBits() ............................................................. 300
Listing 220 xEventGroupClearBitsFromISR() function prototype ........................................... 301
Listing 221 Example use of xEventGroupClearBitsFromISR()............................................... 303
Listing 222 xEventGroupCreate() function prototype ............................................................. 304
Listing 223 Example use of xEventGroupCreate() ................................................................ 305
Listing 224 xEventGroupCreateStatic() function prototype .................................................... 306
Listing 225 Example use of xEventGroupCreateStatic()........................................................ 307
Listing 226 vEventGroupDelete() function prototype ............................................................. 308
Listing 227 xEventGroupGetBits() function prototype ............................................................ 309
Listing 228 xEventGroupGetBitsFromISR() function prototype.............................................. 310
Listing 229 xEventGroupSetBits() function prototype ............................................................ 311
Listing 230 Example use of xEventGroupSetBits() ................................................................ 312
Listing 231 xEventGroupSetBitsFromISR() function prototype .............................................. 313
Listing 232 Example use of xEventGroupSetBitsFromISR() .................................................. 315
Listing 233 xEventGroupSync() function prototype ............................................................... 316
Listing 234 Example use of xEventGroupSync() ................................................................... 319
Listing 235 xEventGroupWaitBits() function prototype .......................................................... 320
Listing 236 Example use of xEventGroupWaitBits() .............................................................. 322
Listing 237 Declaring an array that will be used as the FreeRTOS heap ............................... 329
Listing 238 An example configASSERT() definition ............................................................... 330
Listing 239 The stack overflow hook function prototype ........................................................ 330
Listing 240 An example of saving and restoring the processors privilege state ..................... 335
Listing 241 The daemon task startup hook function name and prototype. ............................. 342
Listing 242 The idle task hook function name and prototype. ................................................ 342
Listing 243 The malloc() failed hook function name and prototype. ....................................... 343
Listing 244 The tick hook function name and prototype......................................................... 346
Listing 245 size_t xStreamBufferBytesAvailable() function prototype .................................... 349
Listing 246 xStreamBufferCreate() function prototype ........................................................... 350
Listing 247 Example use of xStreamBufferCreate() .............................................................. 351
Listing 248 xStreamBufferCreateStatic() function prototype .................................................. 352
Listing 249 Example use of xStreamBufferCreateStatic()...................................................... 353
Listing 250 vStreamBufferDelete() function prototype ........................................................... 354
xv
Listing 251 xStreamBufferIsEmpty() function prototype ......................................................... 355
Listing 252 xStreamBufferIsFull() function prototype ............................................................. 356
Listing 253 xStreamBufferReceive() function prototype ......................................................... 357
Listing 254 Example use of xStreamBufferReceive() ............................................................ 359
Listing 255 xStreamBufferReceiveFromISR() function prototype ........................................... 360
Listing 256 Example use of xStreamBufferReceiveFromISR() .............................................. 362
Listing 257 xStreamBufferReset() function prototype ............................................................ 363
Listing 258 xStreamBufferSend() function prototype ............................................................. 364
Listing 259 Example use of xStreamBufferSend() ................................................................. 366
Listing 260 xStreamBufferSendFromISR() function prototype ............................................... 367
Listing 261 Example use of xStreamBufferSendFromISR() ................................................... 369
Listing 262 xStreamBufferSetTriggerLevel() function prototype ............................................. 370
Listing 263 xStreamBufferSpacesAvailable() function prototype ........................................... 371
Listing 266 xMessageBufferCreate() function prototype ........................................................ 373
Listing 267 Example use of xMessageBufferCreate() ............................................................ 374
Listing 268 xMessageBufferCreateStatic() function prototype ............................................... 375
Listing 269 Example use of xMessageBufferCreateStatic() ................................................... 376
Listing 270 vMessageBufferDelete() function prototype ........................................................ 377
Listing 271 xMessageBufferIsEmpty() function prototype ...................................................... 378
Listing 272 xMessageBufferIsFull() function prototype .......................................................... 379
Listing 273 xMessageBufferReceive() function prototype ...................................................... 380
Listing 274 Example use of xMessageBufferReceive().......................................................... 382
Listing 275 xMessageBufferReceiveFromISR() function prototype ........................................ 383
Listing 276 Example use of xMessageBufferReceiveFromISR() ........................................... 385
Listing 277 xMessageBufferReset() function prototype ......................................................... 386
Listing 278 xMessageBufferSend() function prototype .......................................................... 387
Listing 279 Example use of xMessageBufferSend() .............................................................. 389
Listing 280 xMessageBufferSendFromISR() function prototype ............................................ 390
Listing 281 Example use of xMessageBufferSendFromISR() ................................................ 392
Listing 282 xMessageBufferSpacesAvailable () function prototype........................................ 393
List of Tables
xvi
List of Notation
xvii
Chapter 1
xviii
1.1 Scope
This document provides a technical reference to both the primary FreeRTOS API1, and the
FreeRTOS kernel configuration options. It is assumed the reader is already familiar with the
concepts of writing multi tasking applications, and the primitives provided by real time kernels.
Readers that are not familiar with these fundamental concepts are recommended to read the
book “Mastering the FreeRTOS Real Time Kernel – A Practical Guide” for a much more
descriptive, hands on, and tutorial style text. The book can be obtained from
http://www.FreeRTOS.org/Documentation.
Within this document, the API functions have been split into five groups – task and scheduler
related functions, queue related functions, semaphore related functions, software timer related
functions and event group related functions. Each group is documented in its own chapter,
and within each chapter, the API functions are listed in alphabetical order. Note however that
the name of each API function is prefixed with one or more letters that specify the function’s
return type, and the alphabetical ordering of API functions within each chapter ignores the
function return type prefix. APPENDIX 1: describes the prefixes in more detail.
As an example, consider the API function that is used to create a FreeRTOS task. Its name is
xTaskCreate(). The ‘x’ prefix specifies that xTaskCreate() returns a non-standard type. The
secondary ‘Task’ prefix specifies that the function is a task related function, and, as such, will
be documented in the chapter that contains task and scheduler related functions. The ‘x’ is
not considered in the alphabetical ordering, so xTaskCreate() will appear in the task and
scheduler chapter ordered as if its name was just TaskCreate().
1. API functions that do not end in “FromISR” must not be used in an interrupt service
routine (ISR). Some FreeRTOS ports make a further restriction that even API functions
that do end in “FromISR” cannot be used in an interrupt service routine that has a
1The ‘alternative’ API is not included as its use is no longer recommended. The co-routine API is also
omitted as co-routines are only useful to a small subset of applications.
19
(hardware) priority above the priority set by the
configMAX_SYSCALL_INTERRUPT_PRIORITY (or
configMAX_API_CALL_INTERRUPT_PRIORITY, depending on the port) kernel
configuration constant, which is described in section 7.1 of this document. The second
restriction is to ensure that the timing, determinism and latency of interrupts that have a
priority above that set by configMAX_SYSCALL_INTERRUPT_PRIORITY are not
affected by FreeRTOS.
2. API functions that can potentially cause a context switch must not be called while the
scheduler is suspended.
3. API functions that can potentially cause a context switch must not be called from within
a critical section.
20
21
Chapter 2
22
2.1 portSWITCH_TO_USER_MODE()
#include “FreeRTOS.h”
#include “task.h”
Summary
This function is intended for advanced users only and is only relevant to FreeRTOS MPU ports
(FreeRTOS ports that make use of a Memory Protection Unit).
MPU restricted tasks are created using xTaskCreateRestricted(). The parameters supplied to
xTaskCreateRestricted() specify whether the task being created should be a User (un-
privileged) mode task, or a Supervisor (privileged) mode task. A Supervisor mode task can
call portSWITCH_TO_USER_MODE() to convert itself from a Supervisor mode task into a
User mode task.
Parameters
None.
Return Values
None.
Notes
23
2.2 vTaskAllocateMPURegions()
#include “FreeRTOS.h”
#include “task.h”
Summary
Define a set of Memory Protection Unit (MPU) regions for use by an MPU restricted task.
This function is intended for advanced users only and is only relevant to FreeRTOS MPU ports
(FreeRTOS ports that make use of a Memory Protection Unit).
MPU controlled memory regions can be assigned to an MPU restricted task when the task is
created using the xTaskCreateRestricted() function. They can then be redefined (or
reassigned) at run time using the vTaskAllocateMPURegions() function.
Parameters
xTaskToModify The handle of the restricted task being modified (the task that is being given
access to the memory regions defined by the xRegions parameter).
A task can modify its own memory region access definitions by passing
NULL in place of a valid task handle.
24
Notes
MPU memory regions are defined using the MemoryRegion_t structure shown in Listing 3.
The pvBaseAddress and ulLengthInBytes members are self explanatory as the start of the
memory region and the length of the memory region respectively. These must comply with the
size and alignment restrictions imposed by the MPU. In particular, the size and alignment of
each region must both be equal to the same power of two value.
ulParameters defines how the task is permitted to access the memory region being defined,
and can take the bitwise OR of the following values:
portMPU_REGION_READ_WRITE
portMPU_REGION_PRIVILEGED_READ_ONLY
portMPU_REGION_READ_ONLY
portMPU_REGION_PRIVILEGED_READ_WRITE
portMPU_REGION_CACHEABLE_BUFFERABLE
portMPU_REGION_EXECUTE_NEVER
25
Example
/* Define an array that the task will both read from and write to. Make sure the
size and alignment are appropriate for an MPU region (note this uses GCC syntax). */
static unsigned char ucOneKByte[ 1024 ] __attribute__((align( 1024 )));
/* Now the task can continue its function, but from this point on can only access
its stack and the ucOneKByte array (unless any other statically defined or shared
regions have been declared elsewhere). */
}
26
2.3 xTaskAbortDelay()
#include “FreeRTOS.h”
#include “task.h”
Summary
Calling an API function that includes a timeout parameter can result in the calling task entering
the Blocked state. A task that is in the Blocked state is either waiting for a timeout period to
elapse, or waiting with a timeout for an event to occur, after which the task will automatically
leave the Blocked state and enter the Ready state. There are many examples of this
behavior, two of which are:
If a task calls vTaskDelay() it will enter the Blocked state until the timeout specified by
the function’s parameter has elapsed, at which time the task will automatically leave
the Blocked state and enter the Ready state.
If a task calls ulTaskNotifyTake() when its notification value is zero it will enter the
Blocked state until either it receives a notification or the timeout specified by one of the
function’s parameters has elapsed, at which time the task will automatically leave the
Blocked state and enter the Ready state.
xTaskAbortDelay() will move a task from the Blocked state to the Ready state even if the event
the task is waiting for has not occurred, and the timeout specified when the task entered the
Blocked state has not elapsed.
While a task is in the Blocked state it is not available to the scheduler, and will not consume
any processing time.
Parameters
xTask The handle of the task that will be moved out of the Blocked state.
To obtain a task’s handle create the task using xTaskCreate() and make use of
the pxCreatedTask parameter, or create the task using xTaskCreateStatic() and
27
store the returned value, or use the task’s name in a call to xTaskGetHandle().
Returned If the task referenced by xTask was removed from the Blocked state then
value pdPASS is returned. If the task referenced by xTask was not removed from the
Blocked state because it was not in the Blocked state then pdFAIL is returned.
Notes
Example
28
2.4 xTaskCallApplicationTaskHook()
#include “FreeRTOS.h”
#include “task.h”
Summary
The vTaskSetApplicationTaskTag() function can be used to assign a ‘tag’ value to a task. The
meaning and use of the tag value is defined by the application writer. The kernel itself will not
normally access the tag value.
As a special case, the tag value can be used to associate a ‘task hook’ (or callback) function to
a task. When this is done, the hook function is called using xTaskCallApplicationTaskHook().
Task hook functions can be used for any purpose. The example shown in this section
demonstrates a task hook being used to output debug trace information.
Listing 8 The prototype to which all task hook functions must conform
Parameters
xTask The handle of the task whose associated hook function is being called.
To obtain a task’s handle create the task using xTaskCreate() and make use
of the pxCreatedTask parameter, or create the task using xTaskCreateStatic()
and store the returned value, or use the task’s name in a call to
29
xTaskGetHandle().
A task can call its own hook function by passing NULL in place of a valid task
handle.
pvParameters The value used as the parameter to the task hook function itself.
This parameter has the type ‘pointer to void’ to allow the task hook function
parameter to effectively, and indirectly by means of casting, receive a
parameter of any type. For example, integer types can be passed into a hook
function by casting the integer to a void pointer at the point the hook function
is called, then by casting the void pointer parameter back to an integer within
the hook function itself.
30
Example
/* This example does not make use of the hook return value so just returns
0 in every case. */
return 0;
}
for( ;; )
{
/* The rest of the task code goes here. */
}
}
31
2.5 xTaskCheckForTimeOut()
#include “FreeRTOS.h”
#include “task.h”
Summary
A task can enter the Blocked state to wait for an event. Typically, the task will not wait in the
Blocked state indefinitely, but instead a timeout period will be specified. The task will be
removed from the Blocked state if the timeout period expires before the event the task is
waiting for occurs.
If a task enters and exits the Blocked state more than once while it is waiting for the event to
occur then the timeout used each time the task enters the Blocked state must be adjusted to
ensure the total of all the time spent in the Blocked state does not exceed the originally
specified timeout period. xTaskCheckForTimeOut() performs the adjustment, taking into
account occasional occurrences such as tick count overflows, which would otherwise make a
manual adjustment prone to error.
Parameters
pxTicksToWait Used to pass out an adjusted block time, which is the block time that remains
after taking into account the time already spent in the Blocked state.
32
Returned If pdTRUE is returned then no block time remains, and a timeout has
value occurred.
If pdFALSE is returned then some block time remains, so a timeout has not
occurred.
Example
/* Driver library function used to receive uxWantedBytes from an Rx buffer that is filled
by a UART interrupt. If there are not enough bytes in the Rx buffer then the task enters
the Blocked state until it is notified that more data has been placed into the buffer. If
there is still not enough data then the task re-enters the Blocked state, and
xTaskCheckForTimeOut() is used to re-calculate the Block time to ensure the total amount
of time spent in the Blocked state does not exceed MAX_TIME_TO_WAIT. This continues until
either the buffer contains at least uxWantedBytes bytes, or the total amount of time spent
in the Blocked state reaches MAX_TIME_TO_WAIT – at which point the task reads however many
bytes are available up to a maximum of uxWantedBytes. */
size_t xUART_Receive( uint8_t *pucBuffer, size_t uxWantedBytes )
{
size_t uxReceived = 0;
TickType_t xTicksToWait = MAX_TIME_TO_WAIT;
TimeOut_t xTimeOut;
/* Initialize xTimeOut. This records the time at which this function was entered. */
vTaskSetTimeOutState( &xTimeOut );
/* Loop until the buffer contains the wanted number of bytes, or a timeout occurs. */
while( UART_bytes_in_rx_buffer( pxUARTInstance ) < uxWantedBytes )
{
/* The buffer didn’t contain enough data so this task is going to enter the Blocked
state. Adjusting xTicksToWait to account for any time that has been spent in the
Blocked state within this function so far to ensure the total amount of time spent
in the Blocked state does not exceed MAX_TIME_TO_WAIT. */
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) != pdFALSE )
{
/* Timed out before the wanted number of bytes were available, exit the loop. */
break;
}
/* Attempt to read uxWantedBytes from the receive buffer into pucBuffer. The actual
number of bytes read (which might be less than uxWantedBytes) is returned. */
uxReceived = UART_read_from_receive_buffer( pxUARTInstance, pucBuffer, uxWantedBytes );
return uxReceived;
}
33
2.6 xTaskCreate()
#include “FreeRTOS.h”
#include “task.h”
Summary
Each task requires RAM that is used to hold the task state (the task control block, or TCB),
and used by the task as its stack. If a task is created using xTaskCreate() then the required
RAM is automatically allocated from the FreeRTOS heap. If a task is created using
xTaskCreateStatic() then the RAM is provided by the application writer, which results in two
additional function parameters, but allows the RAM to be statically allocated at compile time.
Newly created tasks are initially placed in the Ready state, but will immediately become the
Running state task if there are no higher priority tasks that are able to run.
Tasks can be created both before and after the scheduler has been started.
Parameters
pvTaskCode Tasks are simply C functions that never exit and, as such, are normally
implemented as an infinite loop. The pvTaskCode parameter is simply a
pointer to the function (in effect, just the function name) that implements the
task.
pcName A descriptive name for the task. This is mainly used to facilitate debugging,
but can also be used in a call to xTaskGetHandle() to obtain a task handle.
34
silently truncated.
usStackDepth Each task has its own unique stack that is allocated by the kernel to the task
when the task is created. The usStackDepth value tells the kernel how large
to make the stack.
The value specifies the number of words the stack can hold, not the number
of bytes. For example, on an architecture with a 4 byte stack width, if
usStackDepth is passed in as 100, then 400 bytes of stack space will be
allocated (100 * 4 bytes). The stack depth multiplied by the stack width must
not exceed the maximum value that can be contained in a variable of type
size_t.
The size of the stack used by the idle task is defined by the application-
defined constant configMINIMAL_STACK_SIZE. The value assigned to this
constant in the demo application provided for the chosen microcontroller
architecture is the minimum recommended for any task on that architecture.
If your task uses a lot of stack space, then you must assign a larger value.
pvParameters Task functions accept a parameter of type ‘pointer to void’ ( void* ). The
value assigned to pvParameters will be the value passed into the task.
This parameter has the type ‘pointer to void’ to allow the task parameter to
effectively, and indirectly by means of casting, receive a parameter of any
type. For example, integer types can be passed into a task function by
casting the integer to a void pointer at the point the task is created, then by
casting the void pointer parameter back to an integer in the task function
definition itself.
uxPriority Defines the priority at which the task will execute. Priorities can be assigned
from 0, which is the lowest priority, to (configMAX_PRIORITIES – 1), which
is the highest priority.
35
wasting RAM.
pxCreatedTask pxCreatedTask can be used to pass out a handle to the task being created.
This handle can then be used to reference the task in API calls that, for
example, change the task priority or delete the task.
If your application has no use for the task handle, then pxCreatedTask can
be set to NULL.
Return Values
36
If heap_3.c is included in the project
then the total heap size is defined by
the linker configuration.
Notes
37
Example
/* Define a structure called xStruct and a variable of type xStruct. These are just used to
demonstrate a parameter being passed into a task function. */
typedef struct A_STRUCT
{
char cStructMember1;
char cStructMember2;
} xStruct;
/* Define the task that will be created. Note the name of the function that implements the task
is used as the first parameter in the call to xTaskCreate() below. */
void vTaskCode( void * pvParameters )
{
xStruct *pxParameters;
/* Define a function that creates a task. This could be called either before or after the
scheduler has been started. */
void vAnotherFunction( void )
{
TaskHandle_t xHandle;
38
2.7 xTaskCreateStatic()
#include “FreeRTOS.h”
#include “task.h”
Summary
Each task requires RAM that is used to hold the task state (the task control block, or TCB),
and used by the task as its stack. If a task is created using xTaskCreate() then the required
RAM is automatically allocated from the FreeRTOS heap. If a task is created using
xTaskCreateStatic() then the RAM is provided by the application writer, which results in two
additional function parameters, but allows the RAM to be statically allocated at compile time.
Newly created tasks are initially placed in the Ready state, but will immediately become the
Running state task if there are no higher priority tasks that are able to run.
Tasks can be created both before and after the scheduler has been started.
Parameters
pvTaskCode Tasks are simply C functions that never exit and, as such, are normally
implemented as an infinite loop. The pvTaskCode parameter is simply a
pointer to the function (in effect, just the function name) that implements the
task.
pcName A descriptive name for the task. This is mainly used to facilitate debugging,
but can also be used in a call to xTaskGetHandle() to obtain a task handle.
39
Supplying a string longer than this maximum will result in the string being
silently truncated.
pvParameters Task functions accept a parameter of type ‘pointer to void’ ( void* ). The
value assigned to pvParameters will be the value passed into the task.
This parameter has the type ‘pointer to void’ to allow the task parameter to
effectively, and indirectly by means of casting, receive a parameter of any
type. For example, integer types can be passed into a task function by
casting the integer to a void pointer at the point the task is created, then by
casting the void pointer parameter back to an integer in the task function
definition itself.
uxPriority Defines the priority at which the task will execute. Priorities can be assigned
from 0, which is the lowest priority, to (configMAX_PRIORITIES – 1), which
is the highest priority.
40
pxTaskBuffer Must point to a variable of type StaticTask_t. The variable will be used to
hold the created task's data structures (TCB), so it must be persistent (not
declared within the stack frame created by a function, or in any other
memory that can legitimately be overwritten as the application executes).
Return Values
NULL The task could not be created because puxStackBuffer or pxTaskBuffer was
NULL.
Any other If a non-NULL value is returned then the task was created and the returned
value value is the handle of the created task.
Notes
41
Example
/* Dimensions the buffer that the task being created will use as its stack. NOTE: This is the
number of words the stack will hold, not the number of bytes. For example, if each stack item
is 32-bits, and this is set to 100, then 400 bytes (100 * 32-bits) will be allocated. */
#define STACK_SIZE 200
/* Structure that will hold the TCB of the task being created. */
StaticTask_t xTaskBuffer;
/* Buffer that the task being created will use as its stack. Note this is an array of
StackType_t variables. The size of StackType_t is dependent on the RTOS port. */
StackType_t xStack[ STACK_SIZE ];
for( ;; )
{
/* Task code goes here. */
}
}
/* puxStackBuffer and pxTaskBuffer were not NULL, so the task will have been created, and
xHandle will be the task's handle. Use the handle to suspend the task. */
vTaskSuspend( xHandle );
}
42
2.8 xTaskCreateRestricted()
#include “FreeRTOS.h”
#include “task.h”
Summary
This function is intended for advanced users only and is only relevant to FreeRTOS MPU ports
(FreeRTOS ports that make use of a Memory Protection Unit).
Newly created tasks are initially placed in the Ready state, but will immediately become the
Running state task if there are no higher priority tasks that are able to run.
Tasks can be created both before and after the scheduler has been started.
Parameters
pxTaskDefinition Pointer to a structure that defines the task. The structure is described under
the notes heading in this section of the reference manual.
pxCreatedTask pxCreatedTask can be used to pass out a handle to the task being created.
This handle can then be used to reference the task in API calls that, for
example, change the task priority or delete the task.
If your application has no use for the task handle, then pxCreatedTask can
be set to NULL.
Return Values
Any other value Indicates that the task could not be created as specified, probably because
there is insufficient FreeRTOS heap memory available to allocate the task
data structures.
43
If heap_1.c, heap_2.c or heap_4.c are included in the project then the total
amount of heap available is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and failure to allocate memory can be trapped using
the vApplicationMallocFailedHook() callback (or ‘hook’) function, and the
amount of free heap memory remaining can be queried using the
xPortGetFreeHeapSize() API function.
If heap_3.c is included in the project then the total heap size is defined by
the linker configuration.
Notes
xTaskCreateRestricted() makes use of the two data structures shown in Listing 17.
pvTaskCode These structure members are equivalent to the xTaskCreate() API function
to
parameters that have the same names.
uxPriority
44
structure member is used to control this option. To create a task in User
mode, uxPriority is set to equal the priority at which the task is to be
created. To create a task in Supervisor mode, uxPriority is set to equal the
priority at which the task is to be created and to have its most significant bit
set. The macro portPRIVILEGE_BIT is provided for this purpose.
For example, to create a User mode task at priority three, set uxPriority to
equal 3. To create a Supervisor mode task at priority three, set uxPriority
to equal ( 3 | portPRIVILEGE_BIT ).
puxStackBuffer The xTaskCreate() API function will automatically allocate a stack for use
by the task being created. The restrictions imposed by using an MPU
means that the xTaskCreateRestricted() function cannot do the same, and
instead, the stack used by the task being created must be statically
allocated and passed into the xTaskCreateRestricted() function using the
puxStackBuffer parameter.
45
defines a single MPU memory region for use by the task being created.
The Cortex-M3 FreeRTOS-MPU port defines
portNUM_CONFIGURABLE_REGIONS to be 3. Three regions can be
defined when the task is created. The regions can be redefined at run time
using the vTaskAllocateMPURegions() function.
portMPU_REGION_READ_WRITE
portMPU_REGION_PRIVILEGED_READ_ONLY
portMPU_REGION_READ_ONLY
portMPU_REGION_PRIVILEGED_READ_WRITE
portMPU_REGION_CACHEABLE_BUFFERABLE
portMPU_REGION_EXECUTE_NEVER
46
Example
/* Declare the stack that will be used by the protected task being created. The stack alignment
must match its size, and be a power of 2. So, if 128 words are reserved for the stack then it
must be aligned on a ( 128 * 4 ) byte boundary. This example uses GCC syntax. */
static portSTACK_TYPE xTaskStack[ 128 ] __attribute__((aligned(128*4)));
/* Declare an array that will be accessed by the protected task being created. The task should
only be able to read from the array, and not write to it. */
char cReadOnlyArray[ 512 ] __attribute__((aligned(512)));
/* Fill in a TaskParameters_t structure to define the task - this is the structure passed to the
xTaskCreateRestricted() function. */
static const TaskParameters_t xTaskDefinition =
{
vTaskFunction, /* pvTaskCode */
"A task", /* pcName */
128, /* usStackDepth - defined in words, not bytes. */
NULL, /* pvParameters */
1, /* uxPriority - priority 1, start in User mode. */
xTaskStack, /* puxStackBuffer - the array to use as the task stack. */
/* xRegions - In this case only one of the three user definable regions is actually used.
The parameters are used to set the region to read only. */
{
/* Base address Length Parameters */
{ cReadOnlyArray, 512, portMPU_REGION_READ_ONLY },
{ 0, 0, 0 },
{ 0, 0, 0 },
}
};
47
2.9 vTaskDelay()
#include “FreeRTOS.h”
#include “task.h”
Summary
Places the task that calls vTaskDelay() into the Blocked state for a fixed number of tick
interrupts.
Specifying a delay period of zero ticks will not result in the calling task being placed into the
Blocked state, but will result in the calling task yielding to any Ready state tasks that share its
priority. Calling vTaskDelay( 0 ) is equivalent to calling taskYIELD().
Parameters
xTicksToDelay The number of tick interrupts that the calling task will remain in the Blocked
state before being transitioned back into the Ready state. For example, if a
task called vTaskDelay( 100 ) when the tick count was 10,000, then it would
immediately enter the Blocked state and remain in the Blocked state until the
tick count reached 10,100.
Any time that remains between vTaskDelay() being called, and the next tick
interrupt occurring, counts as one complete tick period. Therefore, the
highest time resolution that can be achieved when specifying a delay period
is, in the worst case, equal to one complete tick interrupt period.
Return Values
None.
48
Notes
Example
…
/* Enter the Blocked state for 20 tick interrupts – the actual time spent
in the Blocked state is dependent on the tick frequency. */
vTaskDelay( 20 );
/* 20 ticks will have passed since the first call to vTaskDelay() was
executed. */
49
2.10 vTaskDelayUntil()
#include “FreeRTOS.h”
#include “task.h”
Summary
Places the task that calls vTaskDelayUntil() into the Blocked state until an absolute time is
reached.
vTaskDelay() results in the calling task entering into the Blocked state, and then remaining in
the Blocked state, for the specified number of ticks from the time vTaskDelay() was called.
The time at which the task that called vTaskDelay() exits the Blocked state is relative to when
vTaskDelay() was called.
vTaskDelayUntil() results in the calling task entering into the Blocked state, and then
remaining in the Blocked state, until an absolute time has been reached. The task that called
vTaskDelayUntil() exits the Blocked state exactly at the specified time, not at a time that is
relative to when vTaskDelayUntil() was called.
Parameters
50
normally be modified by the application code, other than when the
variable is first initialized. The example in this section demonstrates
how the initialization is performed.
Return Values
None.
Notes
51
Example
52
2.11 vTaskDelete()
#include “FreeRTOS.h”
#include “task.h”
Summary
Deletes an instance of a task that was previously created using a call to xTaskCreate() or
xTaskCreateStatic().
Do not attempt to use a task handle to reference a task that has been deleted.
When a task is deleted, it is the responsibility of the idle task to free the memory that had been
used to hold the deleted task’s stack and data structures (task control block). Therefore, if an
application makes use of the vTaskDelete() API function, it is vital that the application also
ensures the idle task is not starved of processing time (the idle task must be allocated time in
the Running state).
Only memory that is allocated to a task by the kernel itself is automatically freed when a task is
deleted. Memory, or any other resource, that the application (rather than the kernel) allocates
to a task must be explicitly freed by the application when the task is deleted.
Parameters
pxTask The handle of the task being deleted (the subject task).
To obtain a task’s handle create the task using xTaskCreate() and make use of the
pxCreatedTask parameter, or create the task using xTaskCreateStatic() and store
the returned value, or use the task’s name in a call to xTaskGetHandle().
A task can delete itself by passing NULL in place of a valid task handle.
Return Values
None.
53
Example
/* Delete the task that called this function by passing NULL in as the
vTaskDelete() parameter. The same task (this task) could also be deleted by
passing in a valid handle to itself. */
vTaskDelete( NULL );
}
54
2.12 taskDISABLE_INTERRUPTS()
#include “FreeRTOS.h”
#include “task.h”
Summary
If the FreeRTOS port being used does not make use of the
configMAX_SYSCALL_INTERRUPT_PRIORITY (or
configMAX_API_CALL_INTERRUPT_PRIORITY, depending on the port) kernel configuration
constant, then calling taskDISABLE_INTERRUPTS() will leave interrupts globally disabled.
Some FreeRTOS API functions use critical sections that will re-enable interrupts if the critical
section nesting count is zero – even if interrupts were disabled by a call to
taskDISABLE_INTERRUPTS() before the API function was called. It is not recommended to
call FreeRTOS API functions when interrupts have already been disabled.
Parameters
None.
55
Return Values
None.
56
2.13 taskENABLE_INTERRUPTS()
#include “FreeRTOS.h”
#include “task.h”
Summary
Some FreeRTOS API functions use critical sections that will re-enable interrupts if the critical
section nesting count is zero – even if interrupts were disabled by a call to
taskDISABLE_INTERRUPTS() before the API function was called. It is not recommended to
call FreeRTOS API functions when interrupts have already been disabled.
Parameters
None.
Return Values
None.
57
2.14 taskENTER_CRITICAL()
#include “FreeRTOS.h”
#include “task.h”
Summary
If the FreeRTOS port being used does not make use of the
configMAX_SYSCALL_INTERRUPT_PRIORITY kernel configuration constant, then calling
taskENTER_CRITICAL() will leave interrupts globally disabled.
Preemptive context switches only occur inside an interrupt, so will not occur when interrupts
are disabled. Therefore, the task that called taskENTER_CRITICAL() is guaranteed to remain
in the Running state until the critical section is exited, unless the task explicitly attempts to
block or yield (which it should not do from inside a critical section).
58
Calls to taskENTER_CRITICAL() and taskEXIT_CRITICAL() are designed to nest. Therefore,
a critical section will only be exited when one call to taskEXIT_CRITICAL() has been executed
for every preceding call to taskENTER_CRITICAL().
Critical sections must be kept very short, otherwise they will adversely affect interrupt
response times. Every call to taskENTER_CRITICAL() must be closely paired with a call to
taskEXIT_CRITICAL().
FreeRTOS API functions must not be called from within a critical section.
Parameters
None.
Return Values
None.
59
Example
/* Perform the action that is being protected by the critical section here. */
/* Exit the critical section. In this example, this function is itself called
from a critical section, so this call to taskEXIT_CRITICAL() will decrement the
nesting count by one, but not result in interrupts becoming enabled. */
taskEXIT_CRITICAL();
}
/* The operation that required the critical section is complete so exit the
critical section. After this call to taskEXIT_CRITICAL(), the nesting depth
will be zero, so interrupts will have been re-enabled. */
taskEXIT_CRITICAL();
}
}
60
2.15 taskENTER_CRITICAL_FROM_ISR()
#include “FreeRTOS.h”
#include “task.h”
Summary
If the FreeRTOS port being used supports interrupt nesting then calling
taskENTER_CRITICAL_FROM_ISR() will disable interrupts at and below the interrupt priority
set by the configMAX_SYSCALL_INTERRUPT_PRIORITY (or
configMAX_API_CALL_INTERRUPT_PRIORITY) kernel configuration constant, and leave all
other interrupt priorities enabled. If the FreeRTOS port being used does not support interrupt
nesting then taskENTER_CRITICAL_FROM_ISR() and taskEXIT_CRITICAL_FROM_ISR() will
have no effect.
Critical sections must be kept very short, otherwise they will adversely affect the response
times of higher priority interrupts that would otherwise nest. Every call to
taskENTER_CRITICAL_FROM_ISR() must be closely paired with a call to
taskEXIT_CRITICAL_FROM_ISR().
FreeRTOS API functions must not be called from within a critical section.
61
Parameters
None.
Return Values
Example
/* Enter the critical section. In this example, this function is itself called from
within a critical section, so entering this critical section will result in a nesting
depth of 2. Save the value returned by taskENTER_CRITICAL_FROM_ISR() into a local
stack variable so it can be passed into taskEXIT_CRITICAL_FROM_ISR(). */
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
/* Perform the action that is being protected by the critical section here. */
/* Exit the critical section. In this example, this function is itself called from a
critical section, so interrupts will have already been disabled before a value was
stored in uxSavedInterruptStatus, and therefore passing uxSavedInterruptStatus into
taskEXIT_CRITICAL_FROM_ISR() will not result in interrupts being re-enabled. */
taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
}
/* The operation that required the critical section is complete so exit the
critical section. Assuming interrupts were enabled on entry to this ISR, the value
saved in uxSavedInterruptStatus will result in interrupts being re-enabled.*/
taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
}
62
2.16 taskEXIT_CRITICAL()
#include “FreeRTOS.h”
#include “task.h”
Summary
If the FreeRTOS port being used does not make use of the
configMAX_SYSCALL_INTERRUPT_PRIORITY kernel configuration constant, then calling
taskENTER_CRITICAL() will leave interrupts globally disabled.
Preemptive context switches only occur inside an interrupt, so will not occur when interrupts
are disabled. Therefore, the task that called taskENTER_CRITICAL() is guaranteed to remain
in the Running state until the critical section is exited, unless the task explicitly attempts to
block or yield (which it should not do from inside a critical section).
63
Critical sections must be kept very short otherwise they will adversely affect interrupt response
times. Every call to taskENTER_CRITICAL() must be closely paired with a call to
taskEXIT_CRITICAL().
FreeRTOS API functions must not be called from within a critical section.
Parameters
None.
Return Values
None.
Example
64
2.1 taskEXIT_CRITICAL_FROM_ISR()
#include “FreeRTOS.h”
#include “task.h”
Summary
If the FreeRTOS port being used supports interrupt nesting then calling
taskENTER_CRITICAL_FROM_ISR() will disable interrupts at and below the interrupt priority
set by the configMAX_SYSCALL_INTERRUPT_PRIORITY (or
configMAX_API_CALL_INTERRUPT_PRIORITY) kernel configuration constant, and leave all
other interrupt priorities enabled. If the FreeRTOS port being used does not support interrupt
nesting then taskENTER_CRITICAL_FROM_ISR() and taskEXIT_CRITICAL_FROM_ISR() will
have no effect.
Critical sections must be kept very short, otherwise they will adversely affect the response
times of higher priority interrupts that would otherwise nest. Every call to
taskENTER_CRITICAL_FROM_ISR() must be closely paired with a call to
taskEXIT_CRITICAL_FROM_ISR().
FreeRTOS API functions must not be called from within a critical section.
65
Parameters
Return Values
None.
Example
66
2.2 xTaskGetApplicationTaskTag()
#include “FreeRTOS.h”
#include “task.h”
Summary
Returns the ‘tag’ value associated with a task. The meaning and use of the tag value is
defined by the application writer. The kernel itself will not normally access the tag value.
Parameters
xTask The handle of the task being queried. This is the subject task.
A task can obtain its own tag value by either using its own task handle, or by using
NULL in place of a valid task handle.
Return Values
Notes
The tag value can be used to hold a function pointer. When this is done the function assigned
to the tag value can be called using the xTaskCallApplicationTaskHook() API function. This
technique is in effect assigning a callback function to the task. It is common for such a
callback to be used in combination with the traceTASK_SWITCHED_IN() macro to implement
an execution trace feature.
67
Example
for( ;; )
{
/* Rest of task code goes here. */
}
}
/* Create a task from the vATask() function, storing the handle to the created
task in the xTask variable. */
/* What tag value is assigned to the task? The returned tag value is
stored in an integer, so cast to an integer to prevent compiler warnings. */
lReturnedTaskHandle = ( long ) xTaskGetApplicationTaskTag( xHandle );
}
}
68
2.3 xTaskGetCurrentTaskHandle()
#include “FreeRTOS.h”
#include “task.h”
Summary
Returns the handle of the task that is in the Running state – which will be the handle of the
task that called xTaskGetCurrentTaskHandle().
Parameters
None.
Return Values
Notes
69
2.4 xTaskGetIdleTaskHandle()
#include “FreeRTOS.h”
#include “task.h”
Summary
Returns the task handle associated with the Idle task. The Idle task is created automatically
when the scheduler is started.
Parameters
None.
Return Values
Notes
70
2.1 xTaskGetHandle()
#include “FreeRTOS.h”
#include “task.h”
Summary
Parameters
pcNameToQuery The name of the task being queried. The name is specified as a standard
NULL terminated C string.
Return Values
If a task has the exact same name as specified by the pcNameToQuery parameter then the
handle of the task will be returned. If no tasks have the name specified by the
pcNameToQuery parameter then NULL is returned.
Notes
The behavior of xTaskGetHandle() is undefined in there is more than one task that has the
same name.
71
Example
/* Find the handle of the task that has the name MyTask, storing the returned handle locally
so it can be re-used later. */
xHandle = xTaskGetHandle( pcNameToLookup );
for( ;; )
{
/* The rest of the task code goes here. */
}
}
72
2.2 uxTaskGetNumberOfTasks()
#include “FreeRTOS.h”
#include “task.h”
Summary
Returns the total number of tasks that exist at the time uxTaskGetNumberOfTasks() is called.
Parameters
None.
Return Values
The value returned is the total number of tasks that are under the control of the FreeRTOS
kernel at the time uxTaskGetNumberOfTasks() is called. This is the number of Suspended
state tasks, plus the number of Blocked state tasks, plus the number of Ready state tasks,
plus the idle task, plus the Running state task.
73
2.3 vTaskGetRunTimeStats()
#include “FreeRTOS.h”
#include “task.h”
Summary
FreeRTOS can be configured to collect task run time statistics. Task run time statistics
provide information on the amount of processing time each task has received. Figures are
provided as both an absolute time and a percentage of the total application run time. The
vTaskGetRunTimeStats() API function formats the collected run time statistics into a human
readable table. Columns are generated for the task name, the absolute time allocated to that
task, and the percentage of the total application run time allocated to that task. A row is
generated for each task in the system, including the Idle task. An example output is shown in
Figure 1.
Parameters
pcWriteBuffer A pointer to a character buffer into which the formatted and human readable
table is written. The buffer must be large enough to hold the entire table, as
no boundary checking is performed.
74
Return Values
None.
Notes
75
portGET_RUN_TIME_COUNTER_VALUE(), or One of these two macros must be
provided to return the current time
portALT_GET_RUN_TIME_COUNTER_VALUE(Time)
base value – which is the total time
that the application has been
running in the chosen time base
units. If the first macro is used it
must be defined to evaluate to the
current time base value. If the
second macro is used it must be
defined to set its ‘Time’ parameter to
the current time base value.
Example
/* The LM3Sxxxx Eclipse demo application already includes a 20KHz timer interrupt.
The interrupt handler was updated to simply increment a variable called
ulHighFrequencyTimerTicks each time it executed.
portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() then sets this variable to 0 and
portGET_RUN_TIME_COUNTER_VALUE() returns its value. To implement this the following
few lines are added to FreeRTOSConfig.h. */
Listing 42 Example macro definitions, taken from the LM3Sxxx Eclipse Demo
76
/* The LPC17xx demo application does not include the high frequency interrupt test,
so portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() is used to configure the timer 0
peripheral to generate the time base. portGET_RUN_TIME_COUNTER_VALUE() simply returns
the current timer 0 counter value. This was implemented using the following functions
and macros. */
/* Defined in main.c. */
void vConfigureTimerForRunTimeStats( void )
{
const unsigned long TCR_COUNT_RESET = 2,
CTCR_CTM_TIMER = 0x00,
TCR_COUNT_ENABLE = 0x01;
/* Reset Timer 0 */
T0TCR = TCR_COUNT_RESET;
/* Defined in FreeRTOSConfig.h. */
extern void vConfigureTimerForRunTimeStats( void );
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() T0TC
Listing 43 Example macro definitions, taken from the LPC17xx Eclipse Demo
77
2.4 xTaskGetSchedulerState()
#include “FreeRTOS.h”
#include “task.h”
Summary
Returns a value that indicates the state the scheduler is in at the time
xTaskGetSchedulerState() is called.
Parameters
None.
Return Values
Notes
78
2.5 uxTaskGetStackHighWaterMark()
#include “FreeRTOS.h”
#include “task.h”
Summary
Each task maintains its own stack, the total size of which is specified when the task is created.
uxTaskGetStackHighWaterMark() is used to query how close a task has come to overflowing
the stack space allocated to it. This value is called the stack 'high water mark'.
Parameters
xTask The handle of the task whose stack high water mark is being queried (the subject
task).
To obtain a task’s handle create the task using xTaskCreate() and make use of the
pxCreatedTask parameter, or create the task using xTaskCreateStatic() and store the
returned value, or use the task’s name in a call to xTaskGetHandle().
A task can query its own stack high water mark by passing NULL in place of a valid
task handle.
Return Values
The amount of stack used by a task grows and shrinks as the task executes and interrupts are
processed. uxTaskGetStackHighWaterMark() returns the minimum amount of remaining stack
space that has been available since the task started executing. This is the amount of stack
that remained unused when stack usage was at its greatest (or deepest) value. The closer the
high water mark is to zero, the closer the task has come to overflowing its stack.
Notes
79
INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for
uxTaskGetStackHighWaterMark() to be available.
Example
/* Inspect the high water mark of the calling task when the task starts to
execute. */
uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
for( ;; )
{
/* Call any function. */
vTaskDelay( 1000 );
80
2.6 eTaskGetState()
#include “FreeRTOS.h”
#include “task.h”
Summary
Returns as an enumerated type the state in which a task existed at the time eTaskGetState()
was executed.
Parameters
To obtain a task’s handle create the task using xTaskCreate() and make use of the
pxCreatedTask parameter, or create the task using xTaskCreateStatic() and store
the returned value, or use the task’s name in a call to xTaskGetHandle().
Return Values
Table 1 lists the value that eTaskGetState() will return for each possible state that the task
referenced by the pxTask parameter can exist in.
Ready eReady
Blocked eBlocked
Suspended eSuspended
81
Notes
82
2.7 uxTaskGetSystemState()
#include “FreeRTOS.h”
#include “task.h”
Summary
uxTaskGetSystemState() populates a TaskStatus_t structure for each task in the system. The
TaskStatus_t structure contains, among other things, the task’s handle, name, priority, state,
and total amount of run time consumed.
Parameters
83
Return Values
Notes
This function is intended for debugging use only as its use results in the scheduler remaining
suspended for an extended period.
To obtain information on a single task, rather than all the tasks in the system, use
vTaskGetTaskInfo() instead of uxTaskGetSystemState().
84
Example
/* This example demonstrates how a human readable table of run time stats
information is generated from raw data provided by uxTaskGetSystemState().
The human readable table is written to pcWriteBuffer. (see the vTaskList()
API function which actually does just this). */
void vTaskGetRunTimeStats( signed char *pcWriteBuffer )
{
TaskStatus_t *pxTaskStatusArray;
volatile UBaseType_t uxArraySize, x;
unsigned long ulTotalRunTime, ulStatsAsPercentage;
85
typedef struct xTASK_STATUS
{
/* The handle of the task to which the rest of the information in the structure
relates. */
TaskHandle_t xHandle;
/* A pointer to the task's name. This value will be invalid if the task was deleted
since the structure was populated! */
const signed char *pcTaskName;
/* The state in which the task existed when the structure was populated. */
eTaskState eCurrentState;
/* The priority at which the task was running (may be inherited) when the structure
was populated. */
UBaseType_t uxCurrentPriority;
/* The priority to which the task will return if the task's current priority has been
inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid
if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */
UBaseType_t uxBasePriority;
/* The total run time allocated to the task so far, as defined by the run time stats
clock. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in
FreeRTOSConfig.h. */
unsigned long ulRunTimeCounter;
/* The minimum amount of stack space that has remained for the task since the task was
created. The closer this value is to zero the closer the task has come to overflowing
its stack. */
unsigned short usStackHighWaterMark;
} TaskStatus_t;
86
2.8 vTaskGetTaskInfo()
#include “FreeRTOS.h”
#include “task.h”
Summary
Parameters
pxTaskStatus Must point to a variable of type TaskStatus_t, which will be filled with
information about the task being queried.
xGetFreeStackSpace The TaskStatus_t structure contains a member to report the stack high
water mark of the task being queried. The stack high water mark is the
minimum amount of stack space that has ever existed for the task, so
the closer the number is to zero, the closer the task has come to
overflowing its stack. Calculating the stack high water mark takes a
relatively long time, and can make the system temporarily
unresponsive – so the xGetFreeStackSpace parameter is provided to
allow the high water mark checking to be skipped. The high
87
watermark value will only be written to the TaskStatus_t structure if
xGetFreeStackSpace is not set to pdFALSE.
Notes
This function is intended for debugging use only as its use can potentially result in the
scheduler remaining suspended for an extended period.
To obtain a TaskStatus_t structure for all the tasks in the system use uxTaskGetSystemState()
in place of vTaskGetTaskInfo().
Example
88
2.9 pvTaskGetThreadLocalStoragePointer()
#include “FreeRTOS.h”
#include “task.h”
Summary
Thread local storage (or TLS) allows the application writer to store values inside a task's
control block, making the value specific to (local to) the task itself, and allowing each task to
have its own unique value.
Each task has its own array of pointers that can be used as thread local storage. The number
of indexes in the array is set by the configNUM_THREAD_LOCAL_STORAGE_POINTERS
compile time configuration constant in FreeRTOSConfig.h.
Parameters
xTaskToQuery The handle of the task from which the thread local data is being read.
A task can read its own thread local data by using NULL as the parameter
value..
xIndex The index into the thread local storage array from which data is being read.
Return Values
The value read from the task’s thread local storage array at index xIndex.
89
Example
uint32_t ulVariable;
/* Read the value stored in index 5 of the calling task's thread local storage
array into ulVariable. */
ulVariable = ( uint32_t ) pvTaskGetThreadLocalStoragePointer( NULL, 5 );
90
2.10 pcTaskGetName()
#include “FreeRTOS.h”
#include “task.h”
Summary
Queries the human readable text name of a task. A text name is assigned to a task using the
pcName parameter of the xTaskCreate() or xTaskCreateStatic() API function call used to
create the task.
Parameters
xTaskToQuery The handle of the task being queried (the subject task).
To obtain a task’s handle create the task using xTaskCreate() and make use
of the pxCreatedTask parameter, or create the task using
xTaskCreateStatic() and store the returned value, or use the task’s name in a
call to xTaskGetHandle().
A task may query its own name by passing NULL in place of a valid task
handle.
Return Values
Task names are standard NULL terminated C strings. The value returned is a pointer to the
subject task’s name.
91
2.11 xTaskGetTickCount()
#include “FreeRTOS.h”
#include “task.h”
Summary
The tick count is the total number of tick interrupts that have occurred since the scheduler was
started. xTaskGetTickCount() returns the current tick count value.
Parameters
None.
Return Values
xTaskGetTickCount() always returns the tick count value at the time that xTaskGetTickCount()
was called.
Notes
The actual time one tick period represents depends on the value assigned to
configTICK_RATE_HZ within FreeRTOSConfig.h. The pdMS_TO_TICKS() macro can be
used to convert a time in milliseconds to a time in ‘ticks’.
The tick count will eventually overflow and return to zero. This will not affect the internal
operation of the kernel – for example, tasks will always block for the specified period even if
the tick count overflows while the task is in the Blocked state. Overflows must however be
considered by host applications if the application makes direct use of the tick count value.
The frequency at which the tick count overflows depends on both the tick frequency and the
data type used to hold the count value. If configUSE_16_BIT_TICKS is set to 1, then the tick
count will be held in a 16-bit variable. If configUSE_16_BIT_TICKS is set to 0, then the tick
count will be held in a 32-bit variable.
92
Example
93
2.12 xTaskGetTickCountFromISR()
#include “FreeRTOS.h”
#include “task.h”
Summary
The tick count is the total number of tick interrupts that have occurred since the scheduler was
started.
Parameters
None.
Return Values
Notes
The actual time one tick period represents depends on the value assigned to
configTICK_RATE_HZ within FreeRTOSConfig.h. The pdMS_TO_TICKS() macro can be
used to convert a time in milliseconds to a time in ‘ticks’.
The tick count will eventually overflow and return to zero. This will not affect the internal
operation of the kernel – for example, tasks will always block for the specified period even if
the tick count overflows while the task is in the Blocked state. Overflows must however be
considered by host applications if the application makes direct use of the tick count value.
The frequency at which the tick count overflows depends on both the tick frequency and the
data type used to hold the count value. If configUSE_16_BIT_TICKS is set to 1, then the tick
count will be held in a 16-bit variable. If configUSE_16_BIT_TICKS is set to 0, then the tick
count will be held in a 32-bit variable.
94
Example
/* How many ticks occurred between this and the previous interrupt? */
xTimeBetweenInterrupts = xTimeISRLastExecuted – xTimeNow;
/* If more than 200 ticks occurred between this and the previous interrupt then
do something. */
if( xTimeBetweenInterrupts > 200 )
{
/* Take appropriate action here. */
}
95
2.13 vTaskList()
#include “FreeRTOS.h”
#include “task.h”
Summary
Creates a human readable table in a character buffer that describes the state of each task at
the time vTaskList() was called. An example is shown in Figure 2.
Name – This is the name given to the task when the task was created.
State – The state of the task at the time vTaskList() was called, as follows:
o ‘S’ if the task is in the Suspended state, or in the Blocked state without a
timeout.
o ‘D’ if the task has been deleted, but the idle task has not yet freed the memory
that was being used by the task to hold its data structures and stack.
Priority – The priority assigned to the task at the time vTaskList() was called.
96
Stack – Shows the ‘high water mark’ of the task’s stack. This is the minimum amount of
free stack that has been available during the lifetime of the task. The closer this value is
to zero, the closer the task has come to overflowing its stack.
Num – This is a unique number that is assigned to each task. It has no purpose other
than to help identify tasks when more than one task has been assigned the same name.
Parameters
pcWriteBuffer The buffer into which the table text is written. This must be large enough to
hold the entire table as no boundary checking is performed.
Return Values
None.
Notes
vTaskList() is a utility function that is provided for convenience only. It is not considered part
of the kernel. vTaskList() obtains its raw data using the xTaskGetSystemState() API function.
vTaskList() will disable interrupts for the duration of its execution. This might not be
acceptable for applications that include hard real time functionality.
By default, vTaskList() makes use of the standard library sprintf() function. This can result in a
marked increase in the compiled image size, and in stack usage. The FreeRTOS download
includes an open source cut down version of sprintf() in a file called printf-stdarg.c. This can
be used in place of the standard library sprintf() to help minimise the code size impact. Note
that printf-stdarg.c is licensed separately to FreeRTOS. Its license terms are contained in the
file itself.
97
Example
98
2.14 xTaskNotify()
#include “FreeRTOS.h”
#include “task.h”
Summary
Each task has a 32-bit notification value that is initialized to zero when the task is created.
xTaskNotify() is used to send an event directly to and potentially unblock a task, and optionally
update the receiving task’s notification value in one of the following ways:
Parameters
To obtain a task’s handle create the task using xTaskCreate() and make use
of the pxCreatedTask parameter, or create the task using xTaskCreateStatic()
and store the returned value, or use the task’s name in a call to
xTaskGetHandle().
ulValue Used to update the notification value of the task being notified. How ulValue
is interpreted depends on the value of the eAction parameter.
eAction is an enumerated type and can take one of the following values:
99
changed. In this case ulValue is not used.
Return Values
If eAction is set to eSetValueWithoutOverwrite and the task’s notification value is not updated
then pdFAIL is returned. In all other cases pdPASS is returned.
Notes
If the task’s notification value is being used as a light weight and faster alternative to a binary
or counting semaphore then use the simpler xTaskNotifyGive() API function instead of
xTaskNotify().
RTOS task notification functionality is enabled by default, and can be excluded from a build
(saving 8 bytes per task) by setting configUSE_TASK_NOTIFICATIONS to 0 in
FreeRTOSConfig.h.
100
Example
101
2.15 xTaskNotifyAndQuery()
#include “FreeRTOS.h”
#include “task.h”
Summary
Each task has a 32-bit notification value that is initialized to zero when the task is created.
xTaskNotifyAndQuery() is used to send an event directly to and potentially unblock a task, and
optionally update the receiving task’s notification value in one of the following ways:
Parameters
ulValue Used to update the notification value of the task being notified. How
ulValue is interpreted depends on the value of the eAction
parameter.
102
eAction The action to perform when notifying the task.
pulPreviousNotifyValue Used to pass out the subject task's notification value before any bits
are modified by the action of xTaskNotifyAndQuery().
103
Return Values
If eAction is set to eSetValueWithoutOverwrite and the task’s notification value is not updated
then pdFAIL is returned. In all other cases pdPASS is returned.
Notes
If the task’s notification value is being used as a light weight and faster alternative to a binary
or counting semaphore then use the simpler xTaskNotifyGive() API function instead of
xTaskNotify().
RTOS task notification functionality is enabled by default, and can be excluded from a build
(saving 8 bytes per task) by setting configUSE_TASK_NOTIFICATIONS to 0 in
FreeRTOSConfig.h.
104
Example
uint32_t ulPreviousValue;
/* Set bit 8 in the notification value of the task referenced by xTask1Handle. The
task’s previous notification value is not needed, so the last pulPreviousNotifyValue
parameter is set to NULL. */
xTaskNotifyAndQuery( xTask1Handle, ( 1UL << 8UL ), eSetBits, NULL );
/* Set the notification value of the task referenced by xTask3Handle to 0x50, even if
the task had not read its previous notification value. Save the task’s previous
notification value (before it was set to 0x50) in ulPreviousValue. */
xTaskNotifyAndQuery( xTask3Handle, 0x50, eSetValueWithOverwrite, &ulPreviousValue );
/* Set the notification value of the task referenced by xTask4Handle to 0xfff, but
only if to do so would not overwrite the task's existing notification value before
the task had obtained it (by a call to xTaskNotifyWait() or ulTaskNotifyTake()).
Save the task’s previous notification value (before it was set to 0xfff) in
ulPreviousValue. */
if( xTaskNotifyAndQuery( xTask4Handle,
0xfff,
eSetValueWithoutOverwrite,
&ulPreviousValue ) == pdPASS )
{
/* The task's notification value was updated. */
}
else
{
/* The task's notification value was not updated. */
}
105
2.16 xTaskNotifyAndQueryFromISR()
#include “FreeRTOS.h”
#include “task.h”
Summary
Each task has a 32-bit notification value that is initialized to zero when the task is created.
xTaskNotifyAndQueryFromISR() is used to send an event directly to and potentially unblock a
task, and optionally update the receiving task’s notification value in one of the following ways:
Parameters
ulValue Used to update the notification value of the task being notified.
106
How ulValue is interpreted depends on the value of the eAction
parameter.
pulPreviousNotifyValue Used to pass out the subject task's notification value before any
bits are modified by the action of xTaskNotifyAndQuery().
107
used then consider using xTaskNotifyFromISR() in place of
xTaskNotifyAndQueryFromISR().
Return Values
If eAction is set to eSetValueWithoutOverwrite and the task’s notification value is not updated
then pdFAIL is returned. In all other cases pdPASS is returned.
Notes
RTOS task notification functionality is enabled by default, and can be excluded from a build
(saving 8 bytes per task) by setting configUSE_TASK_NOTIFICATIONS to 0 in
FreeRTOSConfig.h.
108
Example
uint32_t ulPreviousValue;
/* Set bit 8 in the notification value of the task referenced by xTask1Handle. The
task’s previous notification value is not needed, so the last pulPreviousNotifyValue
parameter is set to NULL. */
xTaskNotifyAndQueryFromISR( xTask1Handle,
( 1UL << 8UL ),
eSetBits,
NULL,
&xHigherPriorityTaskWoken );
109
2.17 xTaskNotifyFromISR()
#include “FreeRTOS.h”
#include “task.h”
Summary
A version of xTaskNotify() that can be called from an interrupt service routine (ISR).
Each task has a 32-bit notification value that is initialized to zero when the task is created.
xTaskNotifyFromISR() is used to send an event directly to and potentially unblock a task, and
optionally update the receiving task’s notification value in one of the following ways:
Parameters
ulValue Used to update the notification value of the task being notified.
How ulValue is interpreted depends on the value of the eAction
parameter.
110
eAction is an enumerated type and can take one of the following
values:
111
pxHigherPriorityTaskWoken is an optional parameter and can
be set to NULL.
Return Values
If eAction is set to eSetValueWithoutOverwrite and the task’s notification value is not updated
then pdFAIL is returned. In all other cases pdPASS is returned.
Notes
If the task’s notification value is being used as a light weight and faster alternative to a binary
or counting semaphore then use the simpler vTaskNotifyGiveFromISR() API function instead
of xTaskNotifyFromISR().
RTOS task notification functionality is enabled by default, and can be excluded from a build
(saving 8 bytes per task) by setting configUSE_TASK_NOTIFICATIONS to 0 in
FreeRTOSConfig.h.
Example
This example demonstrates a single RTOS task being used to process events that originate
from two separate interrupt service routines - a transmit interrupt and a receive interrupt.
Many peripherals will use the same handler for both, in which case the peripheral's interrupt
status register can simply be bitwise ORed with the receiving task's notification value.
112
/* First bits are defined to represent each interrupt source. */
#define TX_BIT 0x01
#define RX_BIT 0x02
/* The handle of the task that will receive notifications from the interrupts. The
handle was obtained when the task was created. */
static TaskHandle_t xHandlingTask;
/* Notify the task that the transmission is complete by setting the TX_BIT in the
task's notification value. */
xTaskNotifyFromISR( xHandlingTask, TX_BIT, eSetBits, &xHigherPriorityTaskWoken );
/* Notify the task that the reception is complete by setting the RX_BIT in the
task's notification value. */
xTaskNotifyFromISR( xHandlingTask, RX_BIT, eSetBits, &xHigherPriorityTaskWoken );
113
/* The implementation of the task that is notified by the interrupt service
routines. */
static void prvHandlingTask( void *pvParameter )
{
const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 500 );
BaseType_t xResult;
for( ;; )
{
/* Wait to be notified of an interrupt. */
xResult = xTaskNotifyWait( pdFALSE, /* Don't clear bits on entry. */
ULONG_MAX, /* Clear all bits on exit. */
&ulNotifiedValue, /* Stores the notified value. */
xMaxBlockTime );
114
2.18 xTaskNotifyGive()
#include “FreeRTOS.h”
#include “task.h”
Summary
Each task has a 32-bit notification value that is initialized to zero when the task is created. A
task notification is an event sent directly to a task that can unblock the receiving task, and
optionally update the receiving task’s notification value.
xTaskNotifyGive() is a macro intended for use when a task notification value is being used as
a lighter weight and faster alternative to a binary semaphore or a counting semaphore.
FreeRTOS semaphores are given using the xSemaphoreGive() API function, and
xTaskNotifyGive() is the equivalent that uses the receiving task's notification value instead of a
separate semaphore object.
Parameters
xTaskToNotify The handle of the task being notified and having its notification value
incremented.
To obtain a task’s handle create the task using xTaskCreate() and make use
of the pxCreatedTask parameter, or create the task using xTaskCreateStatic()
and store the returned value, or use the task’s name in a call to
xTaskGetHandle().
Return Values
xTaskNotifyGive() is a macro that calls xTaskNotify() with the eAction parameter set to
eIncrement. Therefore pdPASS is always returned.
115
Notes
When a task notification value is being used as a binary or counting semaphore then the task
being notified should wait for the notification using the simpler ulTaskNotifyTake() API function
rather than the xTaskNotifyWait() API function.
RTOS task notification functionality is enabled by default, and can be excluded from a build
(saving 8 bytes per task) by setting configUSE_TASK_NOTIFICATIONS to 0 in
FreeRTOSConfig.h.
116
Example
/* Create two tasks that send notifications back and forth to each other, then
start the RTOS scheduler. */
void main( void )
{
xTaskCreate( prvTask1, "Task1", 200, NULL, tskIDLE_PRIORITY, &xTask1 );
xTaskCreate( prvTask2, "Task2", 200, NULL, tskIDLE_PRIORITY, &xTask2 );
vTaskStartScheduler();
}
/*-----------------------------------------------------------*/
117
2.19 vTaskNotifyGiveFromISR()
#include “FreeRTOS.h”
#include “task.h”
Summary
A version of xTaskNotifyGive() that can be called from an interrupt service routine (ISR).
Each task has a 32-bit notification value that is initialized to zero when the task is created. A
task notification is an event sent directly to a task that can unblock the receiving task, and
optionally update the receiving task’s notification value.
vTaskNotifyGiveFromISR() is intended for use when a task notification value is being used as
a lighter weight and faster alternative to a binary semaphore or a counting semaphore.
FreeRTOS semaphores are given using the xSemaphoreGiveFromISR() API function, and
vTaskNotifyGiveFromISR() is the equivalent that uses the receiving task's notification value
instead of a separate semaphore object.
Parameters
xTaskToNotify The handle of the RTOS task being notified and having its
notification value incremented.
118
If vTaskNotifyGiveFromISR() sets this value to pdTRUE then a
context switch should be requested before the interrupt is
exited. See Listing 73 for an example.
Notes
When a task notification value is being used as a binary or counting semaphore then the task
being notified should wait for the notification using the ulTaskNotifyTake() API function rather
than the xTaskNotifyWait() API function.
RTOS task notification functionality is enabled by default, and can be excluded from a build
(saving 8 bytes per task) by setting configUSE_TASK_NOTIFICATIONS to 0 in
FreeRTOSConfig.h.
Example
This is an example of a transmit function in a generic peripheral driver. An task calls the
transmit function, then waits in the Blocked state (so not using an CPU time) until it is notified
that the transmission is complete. The transmission is performed by a DMA, and the DMA end
interrupt is used to notify the task.
119
/* The transmit end interrupt. */
void vTransmitEndISR( void )
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* The task that initiates the transmission, then enters the Blocked state (so
not consuming any CPU time) to wait for it to complete. */
void vAFunctionCalledFromATask( uint8_t ucDataToTransmit, size_t xDataLength )
{
uint32_t ulNotificationValue;
const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 200 );
if( ulNotificationValue == 1 )
{
/* The transmission ended as expected. */
}
else
{
/* The call to ulTaskNotifyTake() timed out. */
}
}
120
2.20 xTaskNotifyStateClear()
#include “FreeRTOS.h”
#include “task.h”
Summary
Each task has a 32-bit notification value that is initialized to zero when the task is created. A
task notification is an event sent directly to a task that can unblock the receiving task, and
optionally update the receiving task’s notification value.
If a task is in the Blocked state to wait for a notification when the notification arrives then the
task immediately exits the Blocked state and the notification does not remain pending. If a
task is not waiting for a notification when a notification arrives then the notification will remain
pending until either:
xTaskNotifyStateClear() will clear a pending notification, but does not change the notification
value.
Parameters
xTask The handle of the task that will have a pending notification cleared. Setting xTask to
NULL will clear a pending notification in the task that called xTaskNotifyStateClear().
Return Values
If the task referenced by xTask had a notification pending then pdPASS is returned. If the task
referenced by xTask did not have a notification pending then pdFAIL is returned.
121
Example
/* An example UART transmit function. The function starts a UART transmission then
waits to be notified that the transmission is complete. The transmission complete
notification is sent from the UART interrupt. The calling task’s notification state
is cleared before the transmission is started to ensure it is not co-incidentally
already pending before the task attempts to block on its notification state. */
void vSerialPutString( const signed char * const pcStringToSend,
uint16_t usStringLength )
{
const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 5000 );
/* xSendingTask holds the handle of the task waiting for the transmission to
complete. If xSendingTask is NULL then a transmission is not in progress.
Don't start to send a new string unless transmission of the previous string
is complete. */
if( ( xSendingTask == NULL ) && ( usStringLength > 0 ) )
{
/* Ensure the calling task’s notification state is not already pending. */
xTaskNotifyStateClear( NULL );
/* Wait in the Blocked state (so not using any CPU time) until the UART
ISR sends a notification to xSendingTask to notify (and unblock) the task
when the transmission is complete. */
ulTaskNotifyTake( pdTRUE, xMaxBlockTime );
}
}
122
2.21 ulTaskNotifyTake()
#include “FreeRTOS.h”
#include “task.h”
Summary
Each task has a 32-bit notification value that is initialized to zero when the task is created. A
task notification is an event sent directly to a task that can unblock the receiving task, and
optionally update the receiving task’s notification value.
ulTaskNotifyTake() is intended for use when a task notification is used as a faster and lighter
weight alternative to a binary semaphore or a counting semaphore. FreeRTOS semaphores
are taken using the xSemaphoreTake() API function, ulTaskNotifyTake() is the equivalent that
uses a task notification value instead of a separate semaphore object.
A task can use ulTaskNotifyTake() to optionally block to wait for a the task's notification value
to be non-zero. The task does not consume any CPU time while it is in the Blocked state.
ulTaskNotifyTake() can either clear the task's notification value to zero on exit, in which case
the notification value acts like a binary semaphore, or decrement the task's notification value
on exit, in which case the notification value acts more like a counting semaphore.
Parameters
123
is reset to 0 before ulTaskNotifyTake() exits. This is equivalent to the
value of a binary semaphore being left at zero (or empty, or 'not
available') after a successful call to xSemaphoreTake().
xTicksToWait The maximum time to wait in the Blocked state for a notification to be
received if a notification is not already pending when ulTaskNotifyTake()
is called.
The RTOS task does not consume any CPU time when it is in the
Blocked state.
Return Values
The value of the task's notification value before it is decremented or cleared (see the
description of xClearCountOnExit).
Notes
When a task is using its notification value as a binary or counting semaphore other tasks and
interrupts should send notifications to it using either the xTaskNotifyGive() macro, or the
xTaskNotify() function with the function's eAction parameter set to eIncrement (the two are
equivalent).
RTOS task notification functionality is enabled by default, and can be excluded from a build
(saving 8 bytes per task) by setting configUSE_TASK_NOTIFICATIONS to 0 in
FreeRTOSConfig.h.
124
Example
/* An interrupt handler that unblocks a high priority task in which the event that
generated the interrupt is processed. If the priority of the task is high enough
then the interrupt will return directly to the task (so it will interrupt one task
then return to a different task), so the processing will occur contiguously in time -
just as if all the processing had been done in the interrupt handler itself. */
void vANInterruptHandler( void )
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* Unblock the handling task so the task can perform any processing necessitated
by the interrupt. xHandlingTask is the task's handle, which was obtained
when the task was created. */
vTaskNotifyGiveFromISR( xHandlingTask, &xHigherPriorityTaskWoken );
/* Task that blocks waiting to be notified that the peripheral needs servicing. */
void vHandlingTask( void *pvParameters )
{
BaseType_t xEvent;
for( ;; )
{
/* Block indefinitely (without a timeout, so no need to check the function's
return value) to wait for a notification. Here the RTOS task notification
is being used as a binary semaphore, so the notification value is cleared
to zero on exit. NOTE! Real applications should not block indefinitely,
but instead time out occasionally in order to handle error conditions
that may prevent the interrupt from sending any more notifications. */
ulTaskNotifyTake( pdTRUE, /* Clear the notification value on exit. */
portMAX_DELAY );/* Block indefinitely. */
125
2.22 xTaskNotifyWait()
#include “FreeRTOS.h”
#include “task.h”
Summary
Each task has a 32-bit notification value that is initialized to zero when the task is created. A
task notification is an event sent directly to a task that can unblock the receiving task, and
optionally update the receiving task’s notification value in a number of different ways. For
example, a notification may overwrite the receiving task's notification value, or just set one or
more bits in the receiving task's notification value. See the xTaskNotify() API documentation
for examples.
xTaskNotifyWait() waits, with an optional timeout, for the calling task to receive a notification.
If the receiving task was already Blocked waiting for a notification when one arrives the
receiving task will be removed from the Blocked state and the notification cleared.
Parameters
ulBitsToClearOnExit Any bits set in ulBitsToClearOnExit will be cleared in the calling task's
126
notification value before xTaskNotifyWait() function exits if a
notification was received.
The bits are cleared after the task's notification value has been saved
in *pulNotificationValue (see the description of pulNotificationValue
below).
pulNotificationValue Used to pass out the task's notification value. The value copied to
*pulNotificationValue is the task's notification value as it was before
any bits were cleared due to the ulBitsToClearOnExit setting.
xTicksToWait The maximum time to wait in the Blocked state for a notification to be
received if a notification is not already pending when
xTaskNotifyWait() is called.
The task does not consume any CPU time when it is in the Blocked
state.
Return Values
pdTRUE is returned if a notification was received, or if a notification was already pending when
xTaskNotifyWait() was called.
pdFALSE is returned if the call to xTaskNotifyWait() timed out before a notification was
received.
127
Notes
If you are using task notifications to implement binary or counting semaphore type behavior
then use the simpler ulTaskNotifyTake() API function instead of xTaskNotifyWait().
RTOS task notification functionality is enabled by default, and can be excluded from a build
(saving 8 bytes per task) by setting configUSE_TASK_NOTIFICATIONS to 0 in
FreeRTOSConfig.h.
Example
/* This task shows bits within the RTOS task notification value being used to pass different
events to the task in the same way that flags in an event group might be used for the same
purpose. */
void vAnEventProcessingTask( void *pvParameters )
{
uint32_t ulNotifiedValue;
for( ;; )
{
/* Block indefinitely (without a timeout, so no need to check the function's
return value) to wait for a notification.
Bits in this RTOS task's notification value are set by the notifying
tasks and interrupts to indicate which events have occurred. */
xTaskNotifyWait( 0x00, /* Don't clear any notification bits on entry. */
ULONG_MAX, /* Reset the notification value to 0 on exit. */
&ulNotifiedValue, /* Notified value pass out in ulNotifiedValue. */
portMAX_DELAY ); /* Block indefinitely. */
/* Process any events that have been latched in the notified value. */
/* Etc. */
}
}
128
2.23 uxTaskPriorityGet()
#include “FreeRTOS.h”
#include “task.h”
Summary
Parameters
pxTask The handle of the task being queried (the subject task).
To obtain a task’s handle create the task using xTaskCreate() and make use of the
pxCreatedTask parameter, or create the task using xTaskCreateStatic() and store
the returned value, or use the task’s name in a call to xTaskGetHandle().
A task may query its own priority by passing NULL in place of a valid task handle.
Return Values
The value returned is the priority of the task being queried at the time uxTaskPriorityGet() is
called.
129
Example
/* Is the priority of this task higher than the priority of the task
just created? */
if( uxOurPriority > uxCreatedPriority )
{
/* Yes. */
}
}
}
130
2.24 vTaskPrioritySet()
#include “FreeRTOS.h”
#include “task.h”
Summary
Parameters
pxTask The handle of the task being modified (the subject task).
To obtain a task’s handle create the task using xTaskCreate() and make use
of the pxCreatedTask parameter, or create the task using xTaskCreateStatic()
and store the returned value, or use the task’s name in a call to
xTaskGetHandle().
A task can change its own priority by passing NULL in place of a valid task
handle.
uxNewPriority The priority to which the subject task will be set. Priorities can be assigned
from 0, which is the lowest priority, to (configMAX_PRIORITIES – 1), which is
the highest priority.
Return Values
None.
131
Notes
vTaskPrioritySet() must only be called from an executing task, and therefore must not be
called while the scheduler is in the Initialization state (prior to the scheduler being started).
It is possible to have a set of tasks that are all blocked waiting for the same queue or
semaphore event. These tasks will be ordered according to their priority – for example, the
first event will unblock the highest priority task that was waiting for the event, the second event
will unblock the second highest priority task that was originally waiting for the event, etc.
Using vTaskPrioritySet() to change the priority of such a blocked task will not cause the order
in which the blocked tasks are assessed to be re-evaluated.
Example
/* Use NULL in place of a valid task handle to set the priority of the
calling task to 1. */
vTaskPrioritySet( NULL, 1 );
}
}
132
2.25 vTaskResume()
#include “FreeRTOS.h”
#include “task.h”
Summary
Transition a task from the Suspended state to the Ready state. The task must have previously
been placed into the Suspended state using a call to vTaskSuspend().
Parameters
pxTaskToResume The handle of the task being resumed (transitioned out of the Suspended
state). This is the subject task.
To obtain a task’s handle create the task using xTaskCreate() and make
use of the pxCreatedTask parameter, or create the task using
xTaskCreateStatic() and store the returned value, or use the task’s name
in a call to xTaskGetHandle().
Return Values
None.
Notes
A task can be blocked to wait for a queue event, specifying a timeout period. It is legitimate to
move such a Blocked task into the Suspended state using a call to vTaskSuspend(), then out
of the Suspended state and into the Ready state using a call to vTaskResume(). Following
this scenario, the next time the task enters the Running state it will check whether or not its
timeout period has (in the meantime) expired. If the timeout period has not expired, the task
will once again enter the Blocked state to wait for the queue event for the remainder of the
originally specified timeout period.
133
A task can also be blocked to wait for a temporal event using the vTaskDelay() or
vTaskDelayUntil() API functions. It is legitimate to move such a Blocked task into the
Suspended state using a call to vTaskSuspend(), then out of the Suspended state and into the
Ready state using a call to vTaskResume(). Following this scenario, the next time the task
enters the Running state it will exit the vTaskDelay() or vTaskDelayUntil() function as if the
specified delay period had expired, even if this is not actually the case.
vTaskResume() must only be called from an executing task and therefore must not be called
while the scheduler is in the Initialization state (prior to the scheduler being started).
Example
/* The suspended task will not run during this period, unless another task
calls vTaskResume( xHandle ). */
/* The created task is again available to the scheduler and can enter
The Running state. */
}
}
134
2.26 xTaskResumeAll()
#include “FreeRTOS.h”
#include “task.h”
Summary
Parameters
None.
Return Values
pdTRUE The scheduler was transitioned into the Active state. The transition caused a
pending context switch to occur.
pdFALSE Either the scheduler was transitioned into the Active state and the transition did not
cause a context switch to occur, or the scheduler was left in the Suspended state
due to nested calls to vTaskSuspendAll().
Notes
Calls to vTaskSuspendAll() can be nested. The same number of calls must be made to
xTaskResumeAll() as have previously been made to vTaskSuspendAll() before the scheduler
will leave the Suspended state and re-enter the Active state.
xTaskResumeAll() must only be called from an executing task and therefore must not be
called while the scheduler is in the Initialization state (prior to the scheduler being started).
135
Other FreeRTOS API functions should not be called while the scheduler is suspended.
Example
136
/* A function that suspends then resumes the scheduler. */
void vDemoFunction( void )
{
/* This function suspends the scheduler. When it is called from vTask1 the
scheduler is already suspended, so this call creates a nesting depth of 2. */
vTaskSuspendAll();
/* The operation is complete. Set the scheduler back into the Active
state. */
if( xTaskResumeAll() == pdTRUE )
{
/* A context switch occurred within xTaskResumeAll(). */
}
else
{
/* A context switch did not occur within xTaskResumeAll(). */
}
}
}
137
2.27 xTaskResumeFromISR()
#include “FreeRTOS.h”
#include “task.h”
Summary
Parameters
pxTaskToResume The handle of the task being resumed (transitioned out of the Suspended
state). This is the subject task.
To obtain a task’s handle create the task using xTaskCreate() and make
use of the pxCreatedTask parameter, or create the task using
xTaskCreateStatic() and store the returned value, or use the task’s name
in a call to xTaskGetHandle().
Return Values
pdTRUE Returned if the task being resumed (unblocked) has a priority equal to or higher
than the currently executing task (the task that was interrupted) – meaning a
context switch should be performed before exiting the interrupt.
pdFALSE Returned if the task being resumed has a priority lower that the currently executing
task (the task that was interrupted) – meaning it is not necessary to perform a
context switch before exiting the interrupt.
Notes
A task can be suspended by calling vTaskSuspend(). While in the Suspended state the task
will not be selected to enter the Running state. vTaskResume() and xTaskResumeFromISR()
can be used to resume (un-suspend) a suspended task. xTaskResumeFromISR() can be
called from an interrupt, but vTaskResume() cannot.
138
Calls to vTaskSuspend() do not maintain a nesting count. A task that has been suspended by
one of more calls to vTaskSuspend() will always be un-suspended by a single call to
vTaskResume() or xTaskResumeFromISR().
139
Example
TaskHandle_t xHandle;
/* The task is now suspended, so will not reach here until the ISR resumes
(un-suspends) it. */
}
}
140
2.28 vTaskSetApplicationTaskTag()
#include “FreeRTOS.h”
#include “task.h”
Summary
The vTaskSetApplicationTaskTag() API function can be used to assign a ‘tag’ value to a task.
The meaning and use of the tag value is defined by the application writer. The kernel itself will
not normally access the tag value.
Parameters
xTask The handle of the task to which a tag value is being assigned. This is the
subject task.
A task can assign a tag value to itself by either using its own task handle or by
using NULL in place of a valid task handle.
pxTagValue The value being assigned as the tag value of the subject task. This is of type
TaskHookFunction_t to permit a function pointer to be assigned to the tag,
although, indirectly by casting, tag values can be of any type.
Return Values
None.
Notes
The tag value can be used to hold a function pointer. When this is done the function assigned
to the tag value can be called using the xTaskCallApplicationTaskHook() API function. This
technique is in effect assigning a callback function to the task. It is common for such a
callback to be used in combination with the traceTASK_SWITCHED_IN() macro to implement
an execution trace feature.
141
configUSE_APPLICATION_TASK_TAG must be set to 1 in FreeRTOSConfig.h for
vTaskSetApplicationTaskTag() to be available.
Example
for( ;; )
{
/* Rest of task code goes here. */
}
}
/* In this example a callback function is assigned as the task tag. First define the
callback function - this must have type TaskHookFunction_t, as per this example. */
static BaseType_t prvExampleTaskHook( void * pvParameter )
{
/* Perform some action - this could be anything from logging a value, updating
the task state, outputting a value, etc. */
return 0;
}
/* Now define the task that sets prvExampleTaskHook() as its hook/tag value. This is
in effect registering the task callback function. */
void vAnotherTask( void *pvParameters )
{
/* Register a callback function for the currently running (calling) task. */
vTaskSetApplicationTaskTag( NULL, prvExampleTaskHook );
for( ;; )
{
/* Rest of task code goes here. */
}
}
142
2.29 vTaskSetThreadLocalStoragePointer()
#include “FreeRTOS.h”
#include “task.h”
Summary
Thread local storage (or TLS) allows the application writer to store values inside a task's
control block, making the value specific to (local to) the task itself, and allowing each task to
have its own unique value.
Each task has its own array of pointers that can be used as thread local storage. The number
of indexes in the array is set by the configNUM_THREAD_LOCAL_STORAGE_POINTERS
compile time configuration constant in FreeRTOSConfig.h.
Parameters
xTaskToSet The handle of the task to which the thread local data is being written.
A task can write to its own thread local data by using NULL as the parameter
value..
xIndex The index into the thread local storage array to which data is being written.
pvValue The value to write into the into the index specified by xIndex.
Return Values
None.
143
Example
uint32_t ulVariable;
/* Write the 32-bit 0x12345678 value directly into index 1 of the thread local
storage array. Passing NULL as the task handle has the effect of writing to the
calling task's thread local storage array. */
vTaskSetThreadLocalStoragePointer( NULL, /* Task handle. */
1, /* Index into the array. */
( void * ) 0x12345678 );
/* Store the value of the 32-bit variable ulVariable to index 0 of the calling
task's thread local storage array. */
ulVariable = ERROR_CODE;
vTaskSetThreadLocalStoragePointer( NULL, /* Task handle. */
0, /* Index into the array. */
( void * ) &ulVariable );
144
2.30 vTaskSetTimeOutState()
#include “FreeRTOS.h”
#include “task.h”
Summary
A task can enter the Blocked state to wait for an event. Typically, the task will not wait in the
Blocked state indefinitely, but instead a timeout period will be specified. The task will be
removed from the Blocked state if the timeout period expires before the event the task is
waiting for occurs.
If a task enters and exits the Blocked state more than once while it is waiting for the event to
occur then the timeout used each time the task enters the Blocked state must be adjusted to
ensure the total of all the time spent in the Blocked state does not exceed the originally
specified timeout period. xTaskCheckForTimeOut() performs the adjustment, taking into
account occasional occurrences such as tick count overflows, which would otherwise make a
manual adjustment prone to error.
Parameters
145
Example
/* Driver library function used to receive uxWantedBytes from an Rx buffer that is filled
by a UART interrupt. If there are not enough bytes in the Rx buffer then the task enters
the Blocked state until it is notified that more data has been placed into the buffer. If
there is still not enough data then the task re-enters the Blocked state, and
xTaskCheckForTimeOut() is used to re-calculate the Block time to ensure the total amount
of time spent in the Blocked state does not exceed MAX_TIME_TO_WAIT. This continues until
either the buffer contains at least uxWantedBytes bytes, or the total amount of time spent
in the Blocked state reaches MAX_TIME_TO_WAIT – at which point the task reads however many
bytes are available up to a maximum of uxWantedBytes. */
size_t xUART_Receive( uint8_t *pucBuffer, size_t uxWantedBytes )
{
size_t uxReceived = 0;
TickType_t xTicksToWait = MAX_TIME_TO_WAIT;
TimeOut_t xTimeOut;
/* Initialize xTimeOut. This records the time at which this function was entered. */
vTaskSetTimeOutState( &xTimeOut );
/* Loop until the buffer contains the wanted number of bytes, or a timeout occurs. */
while( UART_bytes_in_rx_buffer( pxUARTInstance ) < uxWantedBytes )
{
/* The buffer didn’t contain enough data so this task is going to enter the Blocked
state. Adjusting xTicksToWait to account for any time that has been spent in the
Blocked state within this function so far to ensure the total amount of time spent
in the Blocked state does not exceed MAX_TIME_TO_WAIT. */
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) != pdFALSE )
{
/* Timed out before the wanted number of bytes were available, exit the loop. */
break;
}
/* Attempt to read uxWantedBytes from the receive buffer into pucBuffer. The actual
number of bytes read (which might be less than uxWantedBytes) is returned. */
uxReceived = UART_read_from_receive_buffer( pxUARTInstance, pucBuffer, uxWantedBytes );
return uxReceived;
}
146
2.31 vTaskStartScheduler()
#include “FreeRTOS.h”
#include “task.h”
Summary
Typically, before the scheduler has been started, main() (or a function called by main()) will be
executing. After the scheduler has been started, only tasks and interrupts will ever execute.
Starting the scheduler causes the highest priority task that was created while the scheduler
was in the Initialization state to enter the Running state.
Parameters
None.
Return Values
The Idle task is created automatically when the scheduler is started. vTaskStartScheduler()
will only return if there is not enough FreeRTOS heap memory available for the Idle task to be
created.
Notes
Ports that execute on ARM7 and ARM9 microcontrollers require the processor to be in
Supervisor mode before vTaskStartScheduler() is called.
147
Example
TaskHandle_t xHandle;
/* This code will only be reached if the idle task could not be created inside
vTaskStartScheduler(). An infinite loop is used to assist debugging by
ensuring this scenario does not result in main() exiting. */
for( ;; );
}
148
2.32 vTaskStepTick()
#include “FreeRTOS.h”
#include “task.h”
Summary
If the RTOS is configured to use tickless idle functionality then the tick interrupt will be
stopped, and the microcontroller placed into a low power state, whenever the Idle task is the
only task able to execute. Upon exiting the low power state the tick count value must be
corrected to account for the time that passed while it was stopped.
Parameters
xTicksToJump The number of RTOS tick periods that passed between the tick interrupt
being stopped and restarted (how long the tick interrupt was suppressed for).
For correct operation the parameter must be less than or equal to the
portSUPPRESS_TICKS_AND_SLEEP() parameter.
Return Values
None.
Notes
149
Example
Only vTaskStepTick() is part of the FreeRTOS API. The other function calls are for
demonstration only. */
/* Read the current time from a time source that will remain operational when
the microcontroller is in a low power state. */
ulLowPowerTimeBeforeSleep = ulGetExternalTime();
/* Configure an interrupt to bring the microcontroller out of its low power state
at the time the kernel next needs to execute. The interrupt must be generated
from a source that remains operational when the microcontroller is in a low
power state. */
vSetWakeTimeInterrupt( xExpectedIdleTime );
/* Determine how long the microcontroller was actually in a low power state for,
which will be less than xExpectedIdleTime if the microcontroller was brought out
of low power mode by an interrupt other than that configured by the
vSetWakeTimeInterrupt() call. Note that the scheduler is suspended before
portSUPPRESS_TICKS_AND_SLEEP() is called, and resumed when
portSUPPRESS_TICKS_AND_SLEEP() returns. Therefore no other tasks will execute
until this function completes. */
ulLowPowerTimeAfterSleep = ulGetExternalTime();
/* Correct the kernels tick count to account for the time the microcontroller
spent in its low power state. */
vTaskStepTick( ulLowPowerTimeAfterSleep – ulLowPowerTimeBeforeSleep );
150
2.33 vTaskSuspend()
#include “FreeRTOS.h”
#include “task.h”
Summary
Places a task into the Suspended state. A task that is in the Suspended state will never be
selected to enter the Running state.
The only way of removing a task from the Suspended state is to make it the subject of a call to
vTaskResume().
Parameters
To obtain a task’s handle create the task using xTaskCreate() and make
use of the pxCreatedTask parameter, or create the task using
xTaskCreateStatic() and store the returned value, or use the task’s name
in a call to xTaskGetHandle().
Return Values
None.
Notes
If FreeRTOS version 6.1.0 or later is being used, then vTaskSuspend() can be called to place
a task into the Suspended state before the scheduler has been started (before
vTaskStartScheduler() has been called). This will result in the task (effectively) starting in the
Suspended state.
151
Example
/* The created task will not run during this period, unless another task
calls vTaskResume( xHandle ). */
/* This task can only execute past the call to vTaskSuspend( NULL ) if
another task has resumed (un-suspended) it using a call to vTaskResume(). */
}
}
152
2.34 vTaskSuspendAll()
#include “FreeRTOS.h”
#include “task.h”
Summary
Suspends the scheduler. Suspending the scheduler prevents a context switch from occurring
but leaves interrupts enabled. If an interrupt requests a context switch while the scheduler is
suspended, then the request is held pending and is performed only when the scheduler is
resumed (un-suspended).
Parameters
None.
Return Values
None.
Notes
Calls to xTaskResumeAll() transition the scheduler out of the Suspended state following a
previous call to vTaskSuspendAll().
Calls to vTaskSuspendAll() can be nested. The same number of calls must be made to
xTaskResumeAll() as have previously been made to vTaskSuspendAll() before the scheduler
will leave the Suspended state and re-enter the Active state.
xTaskResumeAll() must only be called from an executing task and therefore must not be
called while the scheduler is in the Initialization state (prior to the scheduler being started).
Other FreeRTOS API functions must not be called while the scheduler is suspended.
153
Example
/* At some point the task wants to perform an operation during which it does
not want to get swapped out, or it wants to access data which is also
accessed from another task (but not from an interrupt). It cannot use
taskENTER_CRITICAL()/taskEXIT_CRITICAL() as the length of the operation may
cause interrupts to be missed. */
/* The operation is complete. Set the scheduler back into the Active
state. */
if( xTaskResumeAll() == pdTRUE )
{
/* A context switch occurred within xTaskResumeAll(). */
}
else
{
/* A context switch did not occur within xTaskResumeAll(). */
}
}
}
154
2.35 taskYIELD()
#include “FreeRTOS.h”
#include “task.h”
Summary
Yielding is where a task volunteers to leave the Running state, without being pre-empted, and
before its time slice has been fully utilized.
Parameters
None.
Return Values
None.
Notes
taskYIELD() must only be called from an executing task and therefore must not be called while
the scheduler is in the Initialization state (prior to the scheduler being started).
When a task calls taskYIELD(), the scheduler will select another Ready state task of equal
priority to enter the Running state in its place. If there are no other Ready state tasks of equal
priority then the task that called taskYIELD() will itself be transitioned straight back into the
Running state.
The scheduler will only ever select a task of equal priority to the task that called taskYIELD()
because, if there were any tasks of higher priority that were in the Ready state, the task that
called taskYIELD() would not have been executing in the first place.
155
Example
/* If there are any tasks of equal priority to this task that are in the
Ready state then let them execute now - even though this task has not used
all of its time slice. */
taskYIELD();
/* If there were any tasks of equal priority to this task in the Ready state,
then they will have executed before this task reaches here. */
}
}
156
Chapter 3
Queue API
157
3.1 vQueueAddToRegistry()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Assigns a human readable name to a queue, and adds the queue to the queue registry.
Parameters
xQueue The handle of the queue that will be added to the registry. Semaphore
handles can also be used.
pcQueueName A descriptive name for the queue or semaphore. This is not used by
FreeRTOS in any way. It is included purely as a debugging aid. Identifying a
queue or semaphore by a human readable name is much simpler than
attempting to identify it by its handle.
Return Values
None.
Notes
1. It allows a text name to be associated with a queue or semaphore for easy queue and
semaphore identification in a debugging interface.
158
and semaphores that need to be viewed in a kernel aware debugging interface need to be
registered.
The queue registry is only required when a kernel aware debugger is being used. At all other
times it has no purpose and can be omitted by setting configQUEUE_REGISTRY_SIZE to 0,
or by omitting the configQUEUE_REGISTRY_SIZE configuration constant definition
altogether.
Example
159
3.2 xQueueAddToSet()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Adds a queue or semaphore to a queue set that was previously created by a call to
xQueueCreateSet().
A receive (in the case of a queue) or take (in the case of a semaphore) operation must not be
performed on a member of a queue set unless a call to xQueueSelectFromSet() has first
returned a handle to that set member.
Parameters
xQueueOrSemaphore The handle of the queue or semaphore being added to the queue set
(cast to an QueueSetMemberHandle_t type).
xQueueSet The handle of the queue set to which the queue or semaphore is
being added.
Return Values
pdPASS The queue or semaphore was successfully added to the queue set.
pdFAIL The queue or semaphore could not be added to the queue set because it is
already a member of a different set.
Notes
160
Example
See the example provided for the xQueueCreateSet() function in this manual.
161
3.3 xQueueCreate()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Creates a new queue and returns a handle by which the queue can be referenced.
Each queue requires RAM that is used to hold the queue state, and to hold the items that are
contained in the queue (the queue storage area). If a queue is created using xQueueCreate()
then the required RAM is automatically allocated from the FreeRTOS heap. If a queue is
created using xQueueCreateStatic() then the RAM is provided by the application writer, which
results in a greater number of parameters, but allows the RAM to be statically allocated at
compile time.
Parameters
uxQueueLength The maximum number of items that the queue being created can hold at
any one time.
uxItemSize The size, in bytes, of each data item that can be stored in the queue.
Return Values
NULL The queue cannot be created because there is insufficient heap memory
available for FreeRTOS to allocate the queue data structures and storage
area.
Any other value The queue was created successfully. The returned value is a handle by
which the created queue can be referenced.
162
Notes
Queues are used to pass data between tasks, and between tasks and interrupts.
Queues can be created before or after the scheduler has been started.
Example
/* Create the queue, storing the returned handle in the xQueue variable. */
xQueue = xQueueCreate( QUEUE_LENGTH, QUEUE_ITEM_SIZE );
if( xQueue == NULL )
{
/* The queue could not be created. */
}
163
3.4 xQueueCreateSet()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Queue sets provide a mechanism to allow an RTOS task to block (pend) on a read operation
from multiple RTOS queues or semaphores simultaneously. Note that there are simpler
alternatives to using queue sets. See the Blocking on Multiple Objects page of the
FreeRTOS.org website for more information.
A queue set must be explicitly created using a call to xQueueCreateSet() before it can be
used. Once created, standard FreeRTOS queues and semaphores can be added to the set
using calls to xQueueAddToSet(). xQueueSelectFromSet() is then used to determine which, if
any, of the queues or semaphores contained in the set is in a state where a queue read or
semaphore take operation would be successful.
Parameters
uxEventQueueLength Queue sets store events that occur on the queues and semaphores
contained in the set. uxEventQueueLength specifies the maximum
number of events that can be queued at once.
164
uxEventQueueLength should be set to (1 + 1 + 1 ), or 3.
Return Values
Any other value The queue set was created successfully. The returned value is a handle by
which the created queue set can be referenced.
Notes
Blocking on a queue set that contains a mutex will not cause the mutex holder to inherit the
priority of the blocked task.
An additional 4 bytes of RAM are required for each space in every queue added to a queue
set. Therefore a counting semaphore that has a high maximum count value should not be
added to a queue set.
A receive (in the case of a queue) or take (in the case of a semaphore) operation must not be
performed on a member of a queue set unless a call to xQueueSelectFromSet() has first
returned a handle to that set member.
165
Example
/* Define the lengths of the queues that will be added to the queue set. */
#define QUEUE_LENGTH_1 10
#define QUEUE_LENGTH_2 10
/* Define the size of the item to be held by queue 1 and queue 2 respectively. The
values used here are just for demonstration purposes. */
#define ITEM_SIZE_QUEUE_1 sizeof( uint32_t )
#define ITEM_SIZE_QUEUE_2 sizeof( something_else_t )
/* The combined length of the two queues and binary semaphore that will be added to
the queue set. */
#define COMBINED_LENGTH ( QUEUE_LENGTH_1 + QUEUE_LENGTH_2 + BINARY_SEMAPHORE_LENGTH )
/* Create a queue set large enough to hold an event for every space in every
queue and semaphore that is to be added to the set. */
xQueueSet = xQueueCreateSet( COMBINED_LENGTH );
/* Create the queues and semaphores that will be contained in the set. */
xQueue1 = xQueueCreate( QUEUE_LENGTH_1, ITEM_SIZE_QUEUE_1 );
xQueue2 = xQueueCreate( QUEUE_LENGTH_2, ITEM_SIZE_QUEUE_2 );
/* Take the semaphore, so it starts empty. A block time of zero can be used
as the semaphore is guaranteed to be available - it has just been created. */
xSemaphoreTake( xSemaphore, 0 );
/* Add the queues and semaphores to the set. Reading from these queues and
semaphore can only be performed after a call to xQueueSelectFromSet() has
returned the queue or semaphore handle from this point on. */
xQueueAddToSet( xQueue1, xQueueSet );
xQueueAddToSet( xQueue2, xQueueSet );
xQueueAddToSet( xSemaphore, xQueueSet );
166
/* CONTINUED FROM PREVIOUS PAGE */
for( ;; )
{
/* Block to wait for something to be available from the queues or semaphore
that have been added to the set. Don't block longer than 200ms. */
xActivatedMember = xQueueSelectFromSet( xQueueSet, pdMS_TO_TICKS( 200 ) );
/* Which set member was selected? Receives/takes can use a block time of
zero as they are guaranteed to pass because xQueueSelectFromSet() would not
have returned the handle unless something was available. */
if( xActivatedMember == xQueue1 )
{
xQueueReceive( xActivatedMember, &xReceivedFromQueue1, 0 );
vProcessValueFromQueue1( xReceivedFromQueue1 );
}
else if( xActivatedQueue == xQueue2 )
{
xQueueReceive( xActivatedMember, &xReceivedFromQueue2, 0 );
vProcessValueFromQueue2( &xReceivedFromQueue2 );
}
else if( xActivatedQueue == xSemaphore )
{
/* Take the semaphore to make sure it can be "given" again. */
xSemaphoreTake( xActivatedMember, 0 );
vProcessEventNotifiedBySemaphore();
break;
}
else
{
/* The 200ms block time expired without an RTOS queue or semaphore
being ready to process. */
}
}
}
Listing 111 Example use of xQueueCreateSet() and other queue set API functions
167
3.5 xQueueCreateStatic()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Creates a new queue and returns a handle by which the queue can be referenced.
Each queue requires RAM that is used to hold the queue state, and to hold the items that are
contained in the queue (the queue storage area). If a queue is created using xQueueCreate()
then the required RAM is automatically allocated from the FreeRTOS heap. If a queue is
created using xQueueCreateStatic() then the RAM is provided by the application writer, which
results in a greater number of parameters, but allows the RAM to be statically allocated at
compile time.
Parameters
uxQueueLength The maximum number of items that the queue being created can
hold at any one time.
uxItemSize The size, in bytes, of each data item that can be stored in the
queue.
168
Return Values
NULL The queue was not created because pxQueueBuffer was NULL.
Any other value The queue was created and the value returned is the handle of the created
queue.
Notes
Queues are used to pass data between tasks, and between tasks and interrupts.
Queues can be created before or after the scheduler has been started.
Example
/* The array to use as the queue's storage area. This must be at least
(uxQueueLength * uxItemSize) bytes. */
uint8_t ucQueueStorageArea[ QUEUE_LENGTH * ITEM_SIZE ];
169
3.6 vQueueDelete()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Parameters
pxQueueToDelete The handle of the queue being deleted. Semaphore handles can also be
used.
Return Values
None
Notes
Queues are used to pass data between tasks and between tasks and interrupts.
Tasks can opt to block on a queue/semaphore (with an optional timeout) if they attempt to
send data to the queue/semaphore and the queue/semaphore is already full, or they attempt
to receive data from a queue/semaphore and the queue/semaphore is already empty. A
queue/semaphore must not be deleted if there are any tasks currently blocked on it.
170
Example
/* Create the queue, storing the returned handle in the xQueue variable. */
xQueue = xQueueCreate( QUEUE_LENGTH, QUEUE_ITEM_SIZE );
if( xQueue == NULL )
{
/* The queue could not be created. */
}
else
{
/* Delete the queue again by passing xQueue to vQueueDelete(). */
vQueueDelete( xQueue );
}
}
171
3.7 pcQueueGetName()
#include “FreeRTOS.h”
#include “queue.h”
Summary
A queue will only have a text name if it has been added to the queue registry. See the
vQueueAddToRegistry() API function.
Parameters
Return Values
Queue names are standard NULL terminated C strings. The value returned is a pointer to the
name of the queue being queried.
172
3.8 xQueueIsQueueEmptyFromISR()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Queries a queue to see if it contains items, or if it is already empty. Items cannot be received
from a queue if the queue is empty.
Parameters
Return Values
pdFALSE The queue being queried is empty (does not contain any data items) at
the time xQueueIsQueueEmptyFromISR() was called.
Any other value The queue being queried was not empty (contained data items) at the
time xQueueIsQueueEmptyFromISR() was called.
Notes
None.
173
3.9 xQueueIsQueueFullFromISR()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Queries a queue to see if it is already full, or if it has space to receive a new item. A queue
can only successfully receive new items when it is not full.
Parameters
Return Values
Any other value The queue being queried was full at the time
xQueueIsQueueFullFromISR() was called.
Notes
None.
174
3.10 uxQueueMessagesWaiting()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Parameters
Returned Value
The number of items that are held in the queue being queried at the time that
uxQueueMessagesWaiting() is called.
Example
/* How many items are currently in the queue referenced by the xQueue handle? */
uxNumberOfItems = uxQueueMessagesWaiting( xQueue );
}
175
3.11 uxQueueMessagesWaitingFromISR()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Parameters
Returned Value
The number of items that are contained in the queue being queried at the time that
uxQueueMessagesWaitingFromISR() is called.
176
Example
/* Check the status of the queue, if it contains more than 10 items then wake the
task that will drain the queue. */
/* How many items are currently in the queue referenced by the xQueue handle? */
uxNumberOfItems = uxQueueMessagesWaitingFromISR( xQueue );
177
3.12 xQueueOverwrite()
#include “FreeRTOS.h”
#include “queue.h”
Summary
A version of xQueueSendToBack() that will write to the queue even if the queue is full,
overwriting data that is already held in the queue.
xQueueOverwrite() is intended for use with queues that have a length of one, meaning the
queue is either empty or full.
This function must not be called from an interrupt service routine. See
xQueueOverwriteFromISR() for an alternative which may be used in an interrupt service
routine.
Parameters
pvItemToQueue A pointer to the item that is to be placed in the queue. The size of each item
the queue can hold is set when the queue is created, and that many bytes
will be copied from pvItemToQueue into the queue storage area.
Returned Value
xQueueOverwrite() is a macro that calls xQueueGenericSend(), and therefore has the same
return values as xQueueSendToFront(). However, pdPASS is the only value that can be
returned because xQueueOverwrite() will write to the queue even when the queue is already
full.
178
Example
/* Peeking the queue should now return 10, but leave the value 10 in
the queue. A block time of zero is used as it is known that the
queue holds a value. */
ulValReceived = 0;
xQueuePeek( xQueue, &ulValReceived, 0 );
if( ulValReceived != 10 )
{
/* Error, unless another task removed the value. */
}
/* This time read from the queue, leaving the queue empty once more.
A block time of 0 is used again. */
xQueueReceive( xQueue, &ulValReceived, 0 );
/* The value read should be the last value written, even though the
queue was already full when the value was written. */
if( ulValReceived != 100 )
{
/* Error unless another task is using the same queue. */
}
/* ... */
}
179
3.13 xQueueOverwriteFromISR()
#include “FreeRTOS.h”
#include “queue.h”
Summary
xQueueOverwriteFromISR() is intended for use with queues that have a length of one,
meaning the queue is either empty or full.
Parameters
pvItemToQueue A pointer to the item that is to be placed in the queue. The size
of each item the queue can hold is set when the queue is
created, and that many bytes will be copied from
pvItemToQueue into the queue storage area.
180
Returned Value
Example
QueueHandle_t xQueue;
/* ... */
181
3.14 xQueuePeek()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Reads an item from a queue, but without removing the item from the queue. The same item
will be returned the next time xQueueReceive() or xQueuePeek() is used to obtain an item
from the same queue.
Parameters
pvBuffer A pointer to the memory into which the data read from the queue will be
copied.
The length of the buffer must be at least equal to the queue item size. The
item size will have been set by the uxItemSize parameter of the call to
xQueueCreate() or xQueueCreateStatic() used to create the queue.
xTicksToWait The maximum amount of time the task should remain in the Blocked state to
wait for data to become available on the queue, should the queue already be
empty.
The block time is specified in tick periods, so the absolute time it represents is
dependent on the tick frequency. The pdMS_TO_TICKS() macro can be used
to convert a time specified in milliseconds to a time specified in ticks.
182
in FreeRTOSConfig.h.
Return Values
errQUEUE_EMPTY Returned if data cannot be read from the queue because the queue is
already empty.
If a block time was specified (xTicksToWait was not zero) then the
calling task will have been placed into the Blocked state to wait for
another task or interrupt to send data to the queue, but the block time
expired before this happened.
Notes
None.
183
Example
struct AMessage
{
char ucMessageID;
char ucData[ 20 ];
} xMessage;
QueueHandle_t xQueue;
if( xQueue != 0 )
{
/* Peek a message on the created queue. Block for 10 ticks if a message is
not available immediately. */
if( xQueuePeek( xQueue, &( pxRxedMessage ), 10 ) == pdPASS )
{
/* pxRxedMessage now points to the struct AMessage variable posted by
vATask, but the item still remains on the queue. */
}
}
else
{
/* The queue could not or has not been created. */
}
184
3.15 xQueuePeekFromISR()
#include “FreeRTOS.h”
#include “queue.h”
Summary
A version of xQueuePeek() that can be used from an interrupt service routine (ISR).
Reads an item from a queue, but without removing the item from the queue. The same item
will be returned the next time xQueueReceive() or xQueuePeek() is used to obtain an item
from the same queue.
Parameters
pvBuffer A pointer to the memory into which the data read from the queue will be copied.
The length of the buffer must be at least equal to the queue item size. The item
size will have been set by the uxItemSize parameter of the call to xQueueCreate()
or xQueueCreateStatic() used to create the queue.
Return Values
errQUEUE_EMPTY Returned if data cannot be read from the queue because the queue is
already empty.
Notes
None.
185
3.16 xQueueReceive()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Parameters
xQueue The handle of the queue from which the data is being received (read). The
queue handle will have been returned from the call to xQueueCreate() or
xQueueCreateStatic() used to create the queue.
pvBuffer A pointer to the memory into which the received data will be copied.
The length of the buffer must be at least equal to the queue item size. The
item size will have been set by the uxItemSize parameter of the call to
xQueueCreate() or xQueueCreateStatic() used to create the queue.
xTicksToWait The maximum amount of time the task should remain in the Blocked state to
wait for data to become available on the queue, should the queue already be
empty.
The block time is specified in tick periods, so the absolute time it represents is
dependent on the tick frequency. The pdMS_TO_TICKS() macro can be used
to convert a time specified in milliseconds to a time specified in ticks.
186
in FreeRTOSConfig.h.
Return Values
errQUEUE_EMPTY Returned if data cannot be read from the queue because the queue is
already empty.
If a block time was specified (xTicksToWait was not zero) then the
calling task will have been placed into the Blocked state to wait for
another task or interrupt to send data to the queue, but the block time
expired before this happened.
Notes
None.
187
Example
/* Create the queue, storing the returned handle in the xQueue variable. */
xQueue = xQueueCreate( QUEUE_LENGTH, QUEUE_ITEM_SIZE );
if( xQueue == NULL )
{
/* The queue could not be created – do something. */
}
/* Execution will only reach here if there was not enough FreeRTOS heap memory
remaining for the idle task to be created. */
for( ;; );
}
/* The queue handle is passed into this task as the task parameter. Cast the
void * parameter back to a queue handle. */
xQueue = ( QueueHandle_t ) pvParameters;
for( ;; )
{
/* Wait for the maximum period for data to become available on the queue.
The period will be indefinite if INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
if( xQueueReceive( xQueue, &xMessage, portMAX_DELAY ) != pdPASS )
{
/* Nothing was received from the queue – even after blocking to wait
for data to arrive. */
}
else
{
/* xMessage now contains the received data. */
}
}
}
188
3.17 xQueueReceiveFromISR()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Parameters
xQueue The handle of the queue from which the data is being received
(read). The queue handle will have been returned from the call
to xQueueCreate() or xQueueCreateStatic() used to create the
queue.
pvBuffer A pointer to the memory into which the received data will be
copied.
The length of the buffer must be at least equal to the queue item
size. The item size will have been set by the uxItemSize
parameter of the call to xQueueCreate() or
xQueueCreateStatic() used to create the queue.
pxHigherPriorityTaskWoken It is possible that a single queue will have one or more tasks
blocked on it waiting for space to become available on the
queue. Calling xQueueReceiveFromISR() can make space
available, and so cause such a task to leave the Blocked state.
If calling the API function causes a task to leave the Blocked
state, and the unblocked task has a priority equal to or higher
than the currently executing task (the task that was interrupted),
then, internally, the API function will set
*pxHigherPriorityTaskWoken to pdTRUE.
189
If xQueueReceiveFromISR() sets this value to pdTRUE, then a
context switch should be performed before the interrupt is
exited. This will ensure that the interrupt returns directly to the
highest priority Ready state task.
Return Values
pdFAIL Data was not received from the queue because the queue was already empty.
Notes
xQueueReceiveFromISR() must not be called prior to the scheduler being started. Therefore
an interrupt that calls xQueueReceiveFromISR() must not be allowed to execute prior to the
scheduler being started.
Example
For clarity of demonstration, the example in this section makes multiple calls to
xQueueReceiveFromISR() to receive multiple small data items. This is inefficient and
therefore not recommended for most applications. A preferable approach would be to send
the multiple data items in a structure to the queue in a single post, allowing
xQueueReceiveFromISR() to be called only once. Alternatively, and preferably, processing
can be deferred to the task level.
190
/* vISR is an interrupt service routine that empties a queue of values, sending each
to a peripheral. It might be that there are multiple tasks blocked on the queue
waiting for space to write more data to the queue. */
void vISR( void )
{
char cByte;
BaseType_t xHigherPriorityTaskWoken;
/* Now the queue is empty and we have cleared the interrupt we can perform a
context switch if one is required (if xHigherPriorityTaskWoken has been set to
pdTRUE. NOTE: The syntax required to perform a context switch from an ISR varies
from port to port, and from compiler to compiler. Check the web documentation and
examples for the port being used to find the correct syntax required for your
application. */
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
191
3.18 xQueueRemoveFromSet()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Summary
A queue or semaphore can only be removed from a queue set if the queue or semaphore is
empty.
Parameters
xQueueOrSemaphore The handle of the queue or semaphore being removed from the
queue set (cast to an QueueSetMemberHandle_t type).
xQueueSet The handle of the queue set in which the queue or semaphore is
included.
Return Values
pdPASS The queue or semaphore was successfully removed from the queue set.
pdFAIL The queue or semaphore was not removed from the queue set because either the
queue or semaphore was not in the queue set, or the queue or semaphore was not
empty.
Notes
192
Example
This example assumes xQueueSet is a queue set that has already been created, and xQueue
is a queue that has already been created and added to xQueueSet.
193
3.19 xQueueReset()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Resets a queue to its original empty state. Any data contained in the queue at the time it is
reset is discarded.
Parameters
xQueue The handle of the queue that is being reset. The queue handle will have been
returned from the call to xQueueCreate() or xQueueCreateStatic() used to create the
queue.
Return Values
194
3.20 xQueueSelectFromSet()
#include “FreeRTOS.h”
#include “queue.h”
Summary
xQueueSelectFromSet() selects from the members of a queue set a queue or semaphore that
either contains data (in the case of a queue) or is available to take (in the case of a
semaphore). xQueueSelectFromSet() effectively allows a task to block (pend) on a read
operation on all the queues and semaphores in a queue set simultaneously.
Parameters
xQueueSet The queue set on which the task will (potentially) block.
xTicksToWait The maximum time, in ticks, that the calling task will remain in the Blocked
state (with other tasks executing) to wait for a member of the queue set to be
ready for a successful queue read or semaphore take operation.
Return Values
NULL A queue or semaphore contained in the set did not become available before the
block time specified by the xTicksToWait parameter expired.
Notes
195
There are simpler alternatives to using queue sets. See the Blocking on Multiple Objects page
on the FreeRTOS.org website for more information.
Blocking on a queue set that contains a mutex will not cause the mutex holder to inherit the
priority of the blocked task.
A receive (in the case of a queue) or take (in the case of a semaphore) operation must not be
performed on a member of a queue set unless a call to xQueueSelectFromSet() has first
returned a handle to that set member.
Example
See the example provided for the xQueueCreateSet() function in this manual.
196
3.21 xQueueSelectFromSetFromISR()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Parameters
xQueueSet The queue set being queried. It is not possible to block on a read as this function
is designed to be used from an interrupt.
Return Values
Notes
197
Example
198
3.22 xQueueSend(), xQueueSendToFront(),
xQueueSendToBack()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Parameters
xQueue The handle of the queue to which the data is being sent (written). The
queue handle will have been returned from the call to xQueueCreate() or
xQueueCreateStatic() used to create the queue.
The size of each item the queue can hold is set when the queue is created,
and that many bytes will be copied from pvItemToQueue into the queue
storage area.
xTicksToWait The maximum amount of time the task should remain in the Blocked state to
wait for space to become available on the queue, should the queue already
be full.
199
xQueueSend(), xQueueSendToFront() and xQueueSendToBack() will
return immediately if xTicksToWait is zero and the queue is already full.
The block time is specified in tick periods, so the absolute time it represents
is dependent on the tick frequency. The pdMS_TO_TICKS() macro can be
used to convert a time specified in milliseconds to a time specified in ticks.
Return Values
errQUEUE_FULL Returned if data could not be written to the queue because the queue was
already full.
If a block time was specified (xTicksToWait was not zero) then the calling
task will have been placed into the Blocked state to wait for another task or
interrupt to make room in the queue, but the specified block time expired
before that happened.
Notes
None.
200
Example
char ucMessageID;
char ucData[ 20 ];
} AMessage;
/* Create the queue, storing the returned handle in the xQueue variable. */
xQueue = xQueueCreate( QUEUE_LENGTH, QUEUE_ITEM_SIZE );
if( xQueue == NULL )
{
/* The queue could not be created – do something. */
}
/* Execution will only reach here if there was not enough FreeRTOS heap memory
remaining for the idle task to be created. */
for( ;; );
}
/* The queue handle is passed into this task as the task parameter. Cast
the parameter back to a queue handle. */
xQueue = ( QueueHandle_t ) pvParameters;
for( ;; )
{
/* Create a message to send on the queue. */
xMessage.ucMessageID = SEND_EXAMPLE;
/* Send the message to the queue, waiting for 10 ticks for space to become
available if the queue is already full. */
if( xQueueSendToBack( xQueue, &xMessage, 10 ) != pdPASS )
{
/* Data could not be sent to the queue even after waiting 10 ticks. */
}
}
}
201
3.23 xQueueSendFromISR(),
xQueueSendToBackFromISR(),
xQueueSendToFrontFromISR()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Parameters
xQueue The handle of the queue to which the data is being sent
(written). The queue handle will have been returned from the
call to xQueueCreate() or xQueueCreateStatic() used to create
the queue.
The size of each item the queue can hold is set when the queue
is created, and that many bytes will be copied from
pvItemToQueue into the queue storage area.
202
pxHigherPriorityTaskWoken It is possible that a single queue will have one or more tasks
blocked on it waiting for data to become available. Calling
xQueueSendFromISR(), xQueueSendToFrontFromISR() or
xQueueSendToBackFromISR() can make data available, and so
cause such a task to leave the Blocked state. If calling the API
function causes a task to leave the Blocked state, and the
unblocked task has a priority equal to or higher than the
currently executing task (the task that was interrupted), then,
internally, the API function will set *pxHigherPriorityTaskWoken
to pdTRUE. If xQueueSendFromISR(),
xQueueSendToFrontFromISR() or
xQueueSendToBackFromISR() sets this value to pdTRUE, then
a context switch should be performed before the interrupt is
exited. This will ensure that the interrupt returns directly to the
highest priority Ready state task.
Return Values
errQUEUE_FULL Data could not be sent to the queue because the queue was already full.
Notes
203
perform a context switch. They will instead just indicate whether or not a context switch is
required.
Example
1. Packing the multiple data items into a structure, then using a single call to
xQueueSendToBackFromISR() to send the entire structure to the queue. This
approach is only appropriate if the number of data items is small.
2. Writing the data items into a circular RAM buffer, then using a single call to
xQueueSendToBackFromISR() to let a task know how many new data items the buffer
contains.
204
/* vBufferISR() is an interrupt service routine that empties a buffer of values,
writing each value to a queue. It might be that there are multiple tasks blocked
on the queue waiting for the data. */
void vBufferISR( void )
{
char cIn;
BaseType_t xHigherPriorityTaskWoken;
/* Now the buffer is empty, and the interrupt source has been cleared, a context
switch should be performed if xHigherPriorityTaskWoken is equal to pdTRUE.
NOTE: The syntax required to perform a context switch from an ISR varies from
port to port, and from compiler to compiler. Check the web documentation and
examples for the port being used to find the syntax required for your
application. */
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
205
3.24 uxQueueSpacesAvailable()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Returns the number of free spaces that are available in a queue. That is, the number of items
that can be posted to the queue before the queue becomes full.
Parameters
Returned Value
The number of free spaces that are available in the queue being queried at the time
uxQueueSpacesAvailable() is called.
Example
/* How many free spaces are currently available in the queue referenced by the
xQueue handle? */
uxNumberOfFreeSpaces = uxQueueSpacesAvailable( xQueue );
}
206
207
Chapter 4
Semaphore API
208
4.1 vSemaphoreCreateBinary()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
NOTE: The vSemaphoreCreateBinary() macro remains in the source code to ensure backward
compatibility, but it should not be used in new designs. Use the xSemaphoreCreateBinary()
function instead.
A macro that creates a binary semaphore. A semaphore must be explicitly created before it
can be used.
Parameters
xSemaphore Variable of type SemaphoreHandle_t that will store the handle of the
semaphore being created.
Return Values
None.
Notes
Binary semaphores and mutexes are very similar, but do have some subtle differences.
Mutexes include a priority inheritance mechanism, binary semaphores do not. This makes
binary semaphores the better choice for implementing synchronization (between tasks or
between tasks and an interrupt), and mutexes the better choice for implementing simple
mutual exclusion.
209
Binary Semaphores – A binary semaphore used for synchronization does not need to be
‘given’ back after it has been successfully ‘taken’ (obtained). Task synchronization is
implemented by having one task or interrupt ‘give’ the semaphore, and another task ‘take’ the
semaphore (see the xSemaphoreGiveFromISR() documentation).
Mutexes – The priority of a task that holds a mutex will be raised if another task of higher
priority attempts to obtain the same mutex. The task that already holds the mutex is said to
‘inherit’ the priority of the task that is attempting to ‘take’ the same mutex. The inherited
priority will be ‘disinherited’ when the mutex is returned (the task that inherited a higher priority
while it held a mutex will return to its original priority when the mutex is returned).
A task that obtains a mutex that is used for mutual exclusion must always give the mutex back
– otherwise no other task will ever be able to obtain the same mutex. An example of a mutex
being used to implement mutual exclusion is provided in the xSemaphoreTake() section of this
manual.
Mutexes and binary semaphores are both referenced using variables that have an
SemaphoreHandle_t type, and can be used in any API function that takes a parameter of that
type.
Mutexes and binary semaphores that were created using the old vSemaphoreCreateBinary()
macro, as opposed to the preferred xSemaphoreCreateBinary() function, are both created
such that the first call to xSemaphoreTake() on the semaphore or mutex will pass. Note
vSemaphoreCreateBinary() is deprecated and must not be used in new applications. Binary
semaphores created using the xSemaphoreCreateBinary() function are created ‘empty’, so the
semaphore must first be given before the semaphore can be taken (obtained) using a call to
xSemaphoreTake().
210
Example
SemaphoreHandle_t xSemaphore;
211
4.2 xSemaphoreCreateBinary()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Creates a binary semaphore, and returns a handle by which the semaphore can be
referenced.
Each binary semaphore requires a small amount of RAM that is used to hold the semaphore’s
state. If a binary semaphore is created using xSemaphoreCreateBinary() then the required
RAM is automatically allocated from the FreeRTOS heap. If a binary semaphore is created
using xSemaphoreCreateBinaryStatic() then the RAM is provided by the application writer,
which requires an additional parameter, but allows the RAM to be statically allocated at
compile time.
The semaphore is created in the ‘empty’ state, meaning the semaphore must first be given
before it can be taken (obtained) using the xSemaphoreTake() function.
Parameters
None.
Return Values
NULL The semaphore could not be created because there was insufficient heap
memory available for FreeRTOS to allocate the semaphore data structures.
Any other value The semaphore was created successfully. The returned value is a handle
by which the created semaphore can be referenced.
Notes
Direct to task notifications normally provide a lighter weight and faster alternative to binary
semaphores.
212
Binary semaphores and mutexes are very similar, but do have some subtle differences.
Mutexes include a priority inheritance mechanism, binary semaphores do not. This makes
binary semaphores the better choice for implementing synchronization (between tasks or
between an interrupt and a task), and mutexes the better choice for implementing simple
mutual exclusion.
Binary Semaphores – A binary semaphore used for synchronization does not need to be
‘given’ back after it has been successfully ‘taken’ (obtained). Task synchronization is
implemented by having one task or interrupt ‘give’ the semaphore, and another task ‘take’ the
semaphore (see the xSemaphoreGiveFromISR() documentation). Note the same functionality
can often be achieved in a more efficient way using a direct to task notification.
Mutexes – The priority of a task that holds a mutex will be raised if another task of higher
priority attempts to obtain the same mutex. The task that already holds the mutex is said to
‘inherit’ the priority of the task that is attempting to ‘take’ the same mutex. The inherited
priority will be ‘disinherited’ when the mutex is returned (the task that inherited a higher priority
while it held a mutex will return to its original priority when the mutex is returned).
A task that obtains a mutex that is used for mutual exclusion must always give the mutex back
– otherwise no other task will ever be able to obtain the same mutex. An example of a mutex
being used to implement mutual exclusion is provided in the xSemaphoreTake() section of this
manual.
Mutexes and binary semaphores are both referenced using variables that have an
SemaphoreHandle_t type, and can be used in any API function that takes a parameter of that
type.
Mutexes and binary semaphores that were created using the vSemaphoreCreateBinary()
macro (as opposed to the preferred xSemaphoreCreateBinary() function) are both created
such that the first call to xSemaphoreTake() on the semaphore or mutex will pass. Note
vSemaphoreCreateBinary() is deprecated and must not be used in new applications. Binary
semaphores created using the xSemaphoreCreateBinary() function are created ‘empty’, so the
semaphore must first be given before the semaphore can be taken (obtained) using a call to
xSemaphoreTake().
213
Example
SemaphoreHandle_t xSemaphore;
214
4.3 xSemaphoreCreateBinaryStatic()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Creates a binary semaphore, and returns a handle by which the semaphore can be
referenced.
Each binary semaphore requires a small amount of RAM that is used to hold the semaphore’s
state. If a binary semaphore is created using xSemaphoreCreateBinary() then the required
RAM is automatically allocated from the FreeRTOS heap. If a binary semaphore is created
using xSemaphoreCreateBinaryStatic() then the RAM is provided by the application writer,
which requires an additional parameter, but allows the RAM to be statically allocated at
compile time.
The semaphore is created in the ‘empty’ state, meaning the semaphore must first be given
before it can be taken (obtained) using the xSemaphoreTake() function.
Parameters
Return Values
Any other value The semaphore was created successfully. The returned value is a handle
by which the created semaphore can be referenced.
215
Notes
Direct to task notifications normally provide a lighter weight and faster alternative to binary
semaphores.
Binary semaphores and mutexes are very similar, but do have some subtle differences.
Mutexes include a priority inheritance mechanism, binary semaphores do not. This makes
binary semaphores the better choice for implementing synchronization (between tasks or
between an interrupt and a task), and mutexes the better choice for implementing simple
mutual exclusion.
Binary Semaphores – A binary semaphore used for synchronization does not need to be
‘given’ back after it has been successfully ‘taken’ (obtained). Task synchronization is
implemented by having one task or interrupt ‘give’ the semaphore, and another task ‘take’ the
semaphore (see the xSemaphoreGiveFromISR() documentation). Note the same functionality
can often be achieved in a more efficient way using a direct to task notification.
Mutexes – The priority of a task that holds a mutex will be raised if another task of higher
priority attempts to obtain the same mutex. The task that already holds the mutex is said to
‘inherit’ the priority of the task that is attempting to ‘take’ the same mutex. The inherited
priority will be ‘disinherited’ when the mutex is returned (the task that inherited a higher priority
while it held a mutex will return to its original priority when the mutex is returned).
A task that obtains a mutex that is used for mutual exclusion must always give the mutex back
– otherwise no other task will ever be able to obtain the same mutex. An example of a mutex
being used to implement mutual exclusion is provided in the xSemaphoreTake() section of this
manual.
Mutexes and binary semaphores are both referenced using variables that have an
SemaphoreHandle_t type, and can be used in any API function that takes a parameter of that
type.
Mutexes and binary semaphores that were created using the vSemaphoreCreateBinary()
macro (as opposed to the preferred xSemaphoreCreateBinary() function) are both created
such that the first call to xSemaphoreTake() on the semaphore or mutex will pass. Note
vSemaphoreCreateBinary() is deprecated and must not be used in new applications. Binary
semaphores created using the xSemaphoreCreateBinary() function are created ‘empty’, so the
216
semaphore must first be given before the semaphore can be taken (obtained) using a call to
xSemaphoreTake().
Example
SemaphoreHandle_t xSemaphoreHandle;
StaticSemaphore_t xSemaphoreBuffer;
/* pxSemaphoreBuffer was not NULL so the binary semaphore will have been created,
and xSemaphoreHandle will be a valid handle.
217
4.4 xSemaphoreCreateCounting()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Creates a counting semaphore, and returns a handle by which the semaphore can be
referenced.
Each counting semaphore requires a small amount of RAM that is used to hold the
semaphore’s state. If a counting semaphore is created using xSemaphoreCreateCounting()
then the required RAM is automatically allocated from the FreeRTOS heap. If a counting
semaphore is created using xSemaphoreCreateCountingStatic() then the RAM is provided by
the application writer, which requires an additional parameter, but allows the RAM to be
statically allocated at compile time.
Parameters
uxMaxCount The maximum count value that can be reached. When the semaphore
reaches this value it can no longer be ‘given’.
Return Values
Any other value The semaphore was created successfully. The returned value is a handle
by which the created semaphore can be referenced.
218
Notes
Direct to task notifications normally provide a lighter weight and faster alternative to counting
semaphores.
1. Counting events.
In this usage scenario, an event handler will ‘give’ the semaphore each time an event occurs,
and a handler task will ‘take’ the semaphore each time it processes an event.
The semaphore’s count value will be incremented each time it is ‘given’ and decremented
each time it is ‘taken’. The count value is therefore the difference between the number of
events that have occurred and the number of events that have been processed.
Semaphores created to count events should be created with an initial count value of zero,
because no events will have been counted prior to the semaphore being created.
2. Resource management.
In this usage scenario, the count value of the semaphore represents the number of resources
that are available.
To obtain control of a resource, a task must first successfully ‘take’ the semaphore. The action
of ‘taking’ the semaphore will decrement the semaphore’s count value. When the count value
reaches zero, no more resources are available, and further attempts to ‘take’ the semaphore
will fail.
When a task finishes with a resource, it must ‘give’ the semaphore. The action of ‘giving’ the
semaphore will increment the semaphore’s count value, indicating that a resource is available,
and allowing future attempts to ‘take’ the semaphore to be successful.
Semaphores created to manage resources should be created with an initial count value equal
to the number of resource that are available.
219
Example
220
4.5 xSemaphoreCreateCountingStatic()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Creates a counting semaphore, and returns a handle by which the semaphore can be
referenced.
Each counting semaphore requires a small amount of RAM that is used to hold the
semaphore’s state. If a counting semaphore is created using xSemaphoreCreateCounting()
then the required RAM is automatically allocated from the FreeRTOS heap. If a counting
semaphore is created using xSemaphoreCreateCountingStatic() then the RAM is provided by
the application writer, which requires an additional parameter, but allows the RAM to be
statically allocated at compile time.
Parameters
uxMaxCount The maximum count value that can be reached. When the semaphore
reaches this value it can no longer be ‘given’.
Return Values
Any other value The semaphore was created successfully. The returned value is a handle
by which the created semaphore can be referenced.
221
Notes
Direct to task notifications normally provide a lighter weight and faster alternative to counting
semaphores.
1. Counting events.
In this usage scenario, an event handler will ‘give’ the semaphore each time an event occurs,
and a handler task will ‘take’ the semaphore each time it processes an event.
The semaphore’s count value will be incremented each time it is ‘given’ and decremented
each time it is ‘taken’. The count value is therefore the difference between the number of
events that have occurred and the number of events that have been processed.
Semaphores created to count events should be created with an initial count value of zero,
because no events will have been counted prior to the semaphore being created.
2. Resource management.
In this usage scenario, the count value of the semaphore represents the number of resources
that are available.
To obtain control of a resource, a task must first successfully ‘take’ the semaphore. The action
of ‘taking’ the semaphore will decrement the semaphore’s count value. When the count value
reaches zero, no more resources are available, and further attempts to ‘take’ the semaphore
will fail.
When a task finishes with a resource, it must ‘give’ the semaphore. The action of ‘giving’ the
semaphore will increment the semaphore’s count value, indicating that a resource is available,
and allowing future attempts to ‘take’ the semaphore to be successful.
Semaphores created to manage resources should be created with an initial count value equal
to the number of resource that are available.
222
Example
/* The pxSemaphoreBuffer parameter was not NULL, so the semaphore will have been
created and is now ready for use. */
}
223
4.6 xSemaphoreCreateMutex()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Creates a mutex type semaphore, and returns a handle by which the mutex can be
referenced.
Each mutex type semaphore requires a small amount of RAM that is used to hold the
semaphore’s state. If a mutex is created using xSemaphoreCreateMutex() then the required
RAM is automatically allocated from the FreeRTOS heap. If a mutex is created using
xSemaphoreCreateMutexStatic() then the RAM is provided by the application writer, which
requires an additional parameter, but allows the RAM to be statically allocated at compile time.
Parameters
None
Return Values
Any other value The semaphore was created successfully. The returned value is a handle
by which the created semaphore can be referenced.
Notes
Binary semaphores and mutexes are very similar, but do have some subtle differences.
Mutexes include a priority inheritance mechanism, binary semaphores do not. This makes
binary semaphores the better choice for implementing synchronization (between tasks or
between tasks and an interrupt), and mutexes the better choice for implementing simple
mutual exclusion.
224
Binary Semaphores – A binary semaphore used for synchronization does not need to be
‘given’ back after it has been successfully ‘taken’ (obtained). Task synchronization is
implemented by having one task or interrupt ‘give’ the semaphore, and another task ‘take’ the
semaphore (see the xSemaphoreGiveFromISR() documentation).
Mutexes – The priority of a task that holds a mutex will be raised if another task of higher
priority attempts to obtain the same mutex. The task that already holds the mutex is said to
‘inherit’ the priority of the task that is attempting to ‘take’ the same mutex. The inherited
priority will be ‘disinherited’ when the mutex is returned (the task that inherited a higher priority
while it held a mutex will return to its original priority when the mutex is returned).
A task that obtains a mutex that is used for mutual exclusion must always give the mutex back
– otherwise no other task will ever be able to obtain the same mutex. An example of a mutex
being used to implement mutual exclusion is provided in the xSemaphoreTake() section of this
manual.
Mutexes and binary semaphores are both referenced using variables that have an
SemaphoreHandle_t type, and can be used in any API function that takes a parameter of that
type.
Example
SemaphoreHandle_t xSemaphore;
225
4.7 xSemaphoreCreateMutexStatic()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Creates a mutex type semaphore, and returns a handle by which the mutex can be
referenced.
Each mutex type semaphore requires a small amount of RAM that is used to hold the
semaphore’s state. If a mutex is created using xSemaphoreCreateMutex() then the required
RAM is automatically allocated from the FreeRTOS heap. If a mutex is created using
xSemaphoreCreateMutexStatic() then the RAM is provided by the application writer, which
requires an additional parameter, but allows the RAM to be statically allocated at compile time.
Parameters
pxMutexBuffer Must point to a variable of type StaticSemaphore_t, which will be used to hold
the mutex’s state.
Return Values
NULL The mutex could not be created because pxMutexBuffer was NULL.
Any other value The mutex was created successfully. The returned value is a handle by
which the created mutex can be referenced.
Notes
Binary semaphores and mutexes are very similar, but do have some subtle differences.
Mutexes include a priority inheritance mechanism, binary semaphores do not. This makes
binary semaphores the better choice for implementing synchronization (between tasks or
between tasks and an interrupt), and mutexes the better choice for implementing simple
mutual exclusion.
226
Binary Semaphores – A binary semaphore used for synchronization does not need to be
‘given’ back after it has been successfully ‘taken’ (obtained). Task synchronization is
implemented by having one task or interrupt ‘give’ the semaphore, and another task ‘take’ the
semaphore (see the xSemaphoreGiveFromISR() documentation).
Mutexes – The priority of a task that holds a mutex will be raised if another task of higher
priority attempts to obtain the same mutex. The task that already holds the mutex is said to
‘inherit’ the priority of the task that is attempting to ‘take’ the same mutex. The inherited
priority will be ‘disinherited’ when the mutex is returned (the task that inherited a higher priority
while it held a mutex will return to its original priority when the mutex is returned).
A task that obtains a mutex that is used for mutual exclusion must always give the mutex back
– otherwise no other task will ever be able to obtain the same mutex. An example of a mutex
being used to implement mutual exclusion is provided in the xSemaphoreTake() section of this
manual.
Mutexes and binary semaphores are both referenced using variables that have an
SemaphoreHandle_t type, and can be used in any API function that takes a parameter of that
type.
Example
SemaphoreHandle_t xSemaphoreHandle;
StaticSemaphore_t xSemaphoreBuffer;
/* The pxMutexBuffer parameter was not NULL so the mutex will have been
created and is now ready for use. */
}
227
4.8 xSemaphoreCreateRecursiveMutex()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Creates a recursive mutex type semaphore, and returns a handle by which the recursive
mutex can be referenced.
Each recursive mutex requires a small amount of RAM that is used to hold the mutex’s state.
If a recursive mutex is created using xSemaphoreCreateRecursiveMutex() then the required
RAM is automatically allocated from the FreeRTOS heap. If a recursive mutex is created
using xSemaphoreCreateRecursiveMutexStatic() then the RAM is provided by the application
writer, which requires an additional parameter, but allows the RAM to be statically allocated at
compile time.
Parameters
None.
Return Values
Any other value The mutex was created successfully. The returned value is a handle by
which the created mutex can be referenced.
Notes
228
A recursive mutex is ‘taken’ using the xSemaphoreTakeRecursive() function, and ‘given’ using
the xSemaphoreGiveRecursive() function. The xSemaphoreTake() and xSemaphoreGive()
functions must not be used with recursive mutexes.
As with standard mutexes, a recursive mutex can only be held/obtained by a single task at any
one time.
The priority of a task that holds a recursive mutex will be raised if another task of higher priority
attempts to obtain the same mutex. The task that already holds the recursive mutex is said to
‘inherit’ the priority of the task that is attempting to ‘take’ the same mutex. The inherited
priority will be ‘disinherited’ when the mutex is returned (the task that inherited a higher priority
while it held a mutex will return to its original priority when the mutex is returned).
229
Example
230
4.9 xSemaphoreCreateRecursiveMutexStatic()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Creates a recursive mutex type semaphore, and returns a handle by which the recursive
mutex can be referenced.
Each recursive mutex requires a small amount of RAM that is used to hold the mutex’s state.
If a recursive mutex is created using xSemaphoreCreateRecursiveMutex() then the required
RAM is automatically allocated from the FreeRTOS heap. If a recursive mutex is created
using xSemaphoreCreateRecursiveMutexStatic() then the RAM is provided by the application
writer, which requires an additional parameter, but allows the RAM to be statically allocated at
compile time.
Parameters
pxMutexBuffer Must point to a variable of type StaticSemaphore_t, which will be used to hold
the mutex’s state.
Return Values
NULL The semaphore could not be created because pxMutexBuffer was NULL.
Any other value The mutex was created successfully. The returned value is a handle by
which the created mutex can be referenced.
Notes
231
A recursive mutex is ‘taken’ using the xSemaphoreTakeRecursive() function, and ‘given’ using
the xSemaphoreGiveRecursive() function. The xSemaphoreTake() and xSemaphoreGive()
functions must not be used with recursive mutexes.
As with standard mutexes, a recursive mutex can only be held/obtained by a single task at any
one time.
The priority of a task that holds a recursive mutex will be raised if another task of higher priority
attempts to obtain the same mutex. The task that already holds the recursive mutex is said to
‘inherit’ the priority of the task that is attempting to ‘take’ the same mutex. The inherited
priority will be ‘disinherited’ when the mutex is returned (the task that inherited a higher priority
while it held a mutex will return to its original priority when the mutex is returned).
Example
/* The pxMutexBuffer parameter was not NULL so the recursive mutex will have
been created and is now ready for use. */
}
232
4.10 vSemaphoreDelete()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Parameters
Return Values
None
Notes
Tasks can opt to block on a semaphore (with an optional timeout) if they attempt to obtain a
semaphore that is not available. A semaphore must not be deleted if there are any tasks
currently blocked on it.
233
4.11 uxSemaphoreGetCount()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Binary semaphores can only have a count of zero or one. Counting semaphores can have a
count between zero and the maximum count specified when the counting semaphore was
created.
Parameters
Return Values
The count of the semaphore referenced by the handle passed in the xSemaphore parameter.
234
4.12 xSemaphoreGetMutexHolder()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Return the handle of the task that holds the mutex specified by the function parameter, if any.
Parameters
Return Values
NULL Either:
Any other value The handle of the task that holds the semaphore specified by the xMutex
parameter.
Notes
235
4.13 xSemaphoreGive()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
‘Gives’ (or releases) a semaphore that has previously been created using a call to
vSemaphoreCreateBinary(), xSemaphoreCreateCounting() or xSemaphoreCreateMutex() –
and has also been successfully ‘taken’.
Parameters
Return Values
pdFAIL The semaphore ‘give’ operation was not successful because the task calling
xSemaphoreGive() is not the semaphore holder. A task must successfully ‘take’ a
semaphore before it can successfully ‘give’ it back.
Notes
None.
236
Example
for( ;; )
{
if( xSemaphore != NULL )
{
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
{
/* This call should fail because the semaphore has not yet been
‘taken’. */
}
/* ... */
237
4.14 xSemaphoreGiveFromISR()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Parameters
238
optional parameter and can be set to NULL.
Return Values
Notes
Unlike the xSemaphoreGive() API function, xSemaphoreGiveFromISR() will not itself perform
a context switch. It will instead just indicate whether or not a context switch is required.
xSemaphoreGiveFromISR() must not be called prior to the scheduler being started. Therefore
an interrupt that calls xSemaphoreGiveFromISR() must not be allowed to execute prior to the
scheduler being started.
239
Example
/* Define a task that performs an action each time an interrupt occurs. The
Interrupt processing is deferred to this task. The task is synchronized with the
interrupt using a semaphore. */
void vATask( void * pvParameters )
{
/* It is assumed the semaphore has already been created outside of this task. */
for( ;; )
{
/* Wait for the next event. */
if( xSemaphoreTake( xSemaphore, portMAX_DELAY ) == pdTRUE )
{
/* The event has occurred, process it here. */
...
/* The event has occurred, use the semaphore to unblock the task so the task
can process the event. */
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
/* Now the task has been unblocked a context switch should be performed if
xHigherPriorityTaskWoken is equal to pdTRUE. NOTE: The syntax required to perform
a context switch from an ISR varies from port to port, and from compiler to
compiler. Check the web documentation and examples for the port being used to
find the syntax required for your application. */
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
240
4.15 xSemaphoreGiveRecursive()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
‘Gives’ (or releases) a recursive mutex type semaphore that has previously been created
using xSemaphoreCreateRecursiveMutex().
Parameters
Return Values
pdFAIL The call to xSemaphoreGiveRecursive() failed because the calling task is not the
mutex holder.
Notes
A recursive mutex is ‘taken’ using the xSemaphoreTakeRecursive() function, and ‘given’ using
the xSemaphoreGiveRecursive() function. The xSemaphoreTake() and xSemaphoreGive()
functions must not be used with recursive mutexes.
241
task until the task that successfully obtained the mutex has also ‘given’ the mutex back exactly
five times.
xSemaphoreGiveRecursive() must only be called from an executing task and therefore must
not be called while the scheduler is in the Initialization state (prior to the scheduler being
started).
xSemaphoreGiveRecursive() must not be called from within a critical section or while the
scheduler is suspended.
242
Example
...
/* For some reason, due to the nature of the code, further calls to
xSemaphoreTakeRecursive() are made on the same mutex. In real code these
would not be just sequential calls, as that would serve no purpose.
Instead, the calls are likely to be buried inside a more complex call
structure, for example in a TCP/IP stack.*/
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
/* The mutex has now been ‘taken’ three times, so will not be available
to another task until it has also been given back three times. Again it
is unlikely that real code would have these calls sequentially, but
instead buried in a more complex call structure. This is just for
illustrative purposes. */
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
243
4.16 xSemaphoreTake()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
‘Takes’ (or obtains) a semaphore that has previously been created using a call to
vSemaphoreCreateBinary(), xSemaphoreCreateCounting() or xSemaphoreCreateMutex().
Parameters
xTicksToWait The maximum amount of time the task should remain in the Blocked state to
wait for the semaphore to become available, if the semaphore is not available
immediately.
The block time is specified in tick periods, so the absolute time it represents is
dependent on the tick frequency. The pdMS_TO_TICKS() macro can be used
to convert a time specified in milliseconds to a time specified in ticks.
Return Values
pdPASS Returned only if the call to xSemaphoreTake() was successful in obtaining the
semaphore.
If a block time was specified (xTicksToWait was not zero), then it is possible that
244
the calling task was placed into the Blocked state to wait for the semaphore if it was
not immediately available, but the semaphore became available before the block
time expired.
pdFAIL Returned if the call to xSemaphoreTake() did not successfully obtain the
semaphore.
If a block time was specified (xTicksToWait was not zero), then the calling task will
have been placed into the Blocked state to wait for the semaphore to become
available, but the block time expired before this happened.
Notes
xSemaphoreTake() must only be called from an executing task and therefore must not be
called while the scheduler is in the Initialization state (prior to the scheduler being started).
xSemaphoreTake() must not be called from within a critical section or while the scheduler is
suspended.
245
Example
/* ... */
246
4.17 xSemaphoreTakeFromISR()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Parameters
If xSemaphoreTakeFromISR() sets
*pxHigherPriorityTaskWoken to pdTRUE, then a context switch
should be performed before the interrupt is exited. This will
ensure that the interrupt returns directly to the highest priority
Ready state task. The mechanism is identical to that used in
the xQueueReceiveFromISR() function, and readers are
referred to the xQueueReceiveFromISR() documentation for
247
further explanation.
Return Values
pdFAIL The semaphore was not successfully taken because it was not available.
248
4.18 xSemaphoreTakeRecursive()
#include “FreeRTOS.h”
#include “semphr.h”
Summary
‘Takes’ (or obtains) a recursive mutex type semaphore that has previously been created using
xSemaphoreCreateRecursiveMutex().
Parameters
xTicksToWait The maximum amount of time the task should remain in the Blocked state to
wait for the semaphore to become available, if the semaphore is not available
immediately.
The block time is specified in tick periods, so the absolute time it represents is
dependent on the tick frequency. The pdMS_TO_TICKS() macro can be used
to convert a time specified in milliseconds to a time specified in ticks.
Return Values
249
If a block time was specified (xTicksToWait was not zero), then it is possible that
the calling task was placed into the Blocked state to wait for the semaphore if it was
not immediately available, but the semaphore became available before the block
time expired.
pdFAIL Returned if the call to xSemaphoreTakeRecursive() did not successfully obtain the
semaphore.
If a block time was specified (xTicksToWait was not zero), then the calling task will
have been placed into the Blocked state to wait for the semaphore to become
available, but the block time expired before this happened.
Notes
A recursive mutex is ‘taken’ using the xSemaphoreTakeRecursive() function, and ‘given’ using
the xSemaphoreGiveRecursive() function. The xSemaphoreTake() and xSemaphoreGive()
functions must not be used with recursive mutexes.
xSemaphoreTakeRecursive() must only be called from an executing task and therefore must
not be called while the scheduler is in the Initialization state (prior to the scheduler being
started).
xSemaphoreTakeRecursive() must not be called from within a critical section or while the
scheduler is suspended.
250
Example
...
/* For some reason, due to the nature of the code, further calls to
xSemaphoreTakeRecursive() are made on the same mutex. In real code these
would not be just sequential calls, as that would serve no purpose.
Instead, the calls are likely to be buried inside a more complex call
structure, for example in a TCP/IP stack.*/
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
/* The mutex has now been ‘taken’ three times, so will not be available
to another task until it has also been given back three times. Again it
is unlikely that real code would have these calls sequentially, but
instead buried in a more complex call structure. This is just for
illustrative purposes. */
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
251
252
Chapter 5
253
5.1 xTimerChangePeriod()
#include “FreeRTOS.h”
#include “timers.h”
Summary
If xTimerChangePeriod() is used to change the period of a timer that is already running, then
the timer will use the new period value to recalculate its expiry time. The recalculated expiry
time will then be relative to when xTimerChangePeriod() was called, and not relative to when
the timer was originally started.
If xTimerChangePeriod() is used to change the period of a timer that is not already running,
then the timer will use the new period value to calculate an expiry time, and the timer will start
running.
Parameters
xNewPeriod The new period for the timer referenced by the xTimer parameter.
xTicksToWait Timer functionality is not provided by the core FreeRTOS code, but by a timer
254
service (or daemon) task. The FreeRTOS timer API sends commands to the
timer service task on a queue called the timer command queue. xTicksToWait
specifies the maximum amount of time the task should remain in the Blocked
state to wait for space to become available on the timer command queue,
should the queue already be full.
The block time is specified in tick periods, so the absolute time it represents is
dependent on the tick frequency. As with the xNewPeriod parameter, The
pdMS_TO_TICKS() macro can be used to convert a time specified in
milliseconds to a time specified in ticks.
Return Values
pdPASS The change period command was successfully sent to the timer command queue.
If a block time was specified (xTicksToWait was not zero), then it is possible that
the calling task was placed into the Blocked state to wait for space to become
available on the timer command queue before the function returned, but data was
successfully written to the queue before the block time expired.
When the command is actually processed will depend on the priority of the timer
service task relative to other tasks in the system, although the timer’s expiry time is
relative to when xTimerChangePeriod() is actually called. The priority of the timer
service task is set by the configTIMER_TASK_PRIORITY configuration constant.
pdFAIL The change period command was not sent to the timer command queue because
the queue was already full.
If a block time was specified (xTicksToWait was not zero) then the calling task will
have been placed into the Blocked state to wait for the timer service task to make
room in the queue, but the specified block time expired before that happened.
255
Notes
Example
/* This function assumes xTimer has already been created. If the timer referenced by
xTimer is already active when it is called, then the timer is deleted. If the timer
referenced by xTimer is not active when it is called, then the period of the timer is
set to 500ms, and the timer is started. */
void vAFunction( TimerHandle_t xTimer )
{
if( xTimerIsTimerActive( xTimer ) != pdFALSE )
{
/* xTimer is already active - delete it. */
xTimerDelete( xTimer );
}
else
{
/* xTimer is not active, change its period to 500ms. This will also cause
the timer to start. Block for a maximum of 100 ticks if the change period
command cannot immediately be sent to the timer command queue. */
if( xTimerChangePeriod( xTimer, pdMS_TO_TICKS( 500 ), 100 ) == pdPASS )
{
/* The command was successfully sent. */
}
else
{
/* The command could not be sent, even after waiting for 100 ticks to
pass. Take appropriate action here. */
}
}
}
256
5.2 xTimerChangePeriodFromISR()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Parameters
xNewPeriod The new period for the timer referenced by the xTimer
parameter.
257
Return Values
pdPASS The change period command was successfully sent to the timer command queue.
When the command is actually processed will depend on the priority of the timer
service task relative to other tasks in the system, although the timer’s expiry time is
relative to when xTimerChangePeriodFromISR() is actually called. The priority of
the timer service task is set by the configTIMER_TASK_PRIORITY configuration
constant.
pdFAIL The change period command was not sent to the timer command queue because
the queue was already full.
Notes
Example
/* This scenario assumes xTimer has already been created and started. When an
interrupt occurs, the period of xTimer should be changed to 500ms. */
258
5.3 xTimerCreate()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Creates a new software timer and returns a handle by which the created software timer can be
referenced.
Each software timer requires a small amount of RAM that is used to hold the timer’s state. If a
software timer is created using xTimerCreate() then this RAM is automatically allocated from
the FreeRTOS heap. If a software timer is created using xTimerCreateStatic() then the RAM
is provided by the application writer, which requires an additional parameter, but allows the
RAM to be statically allocated at compile time.
Creating a timer does not start the timer running. The xTimerStart(), xTimerReset(),
xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
xTimerChangePeriodFromISR() API functions can all be used to start the timer running.
Parameters
pcTimerName A plain text name that is assigned to the timer, purely to assist
debugging.
259
equal to 1000.
Once started, a one-shot timer will expire only once. A one-shot timer
can be manually restarted after it has expired.
pvTimerID An identifier that is assigned to the timer being created. The identifier
can later be updated using the vTimerSetTimerID() API function.
pxCallbackFunction The function to call when the timer expires. Callback functions must
have the prototype defined by the TimerCallbackFunction_t typedef.
The required prototype is shown in Listing 183.
Return Values
NULL The software timer could not be created because there was insufficient
FreeRTOS heap memory available to successfully allocate the timer data
structures.
Any other The software timer was created successfully and the returned value is the
value handle by which the created software timer can be referenced.
260
Notes
Example
/* Define a callback function that will be used by multiple timer instances. The callback
function does nothing but count the number of times the associated timer expires, and stop the
timer once the timer has expired 10 times. The count is saved as the ID of the timer. */
void vTimerCallback( TimerHandle_t xTimer )
{
const uint32_t ulMaxExpiryCountBeforeStopping = 10;
uint32_t ulCount;
/* The number of times this timer has expired is saved as the timer's ID. Obtain the
count. */
ulCount = ( uint32_t ) pvTimerGetTimerID( xTimer );
/* Increment the count, then test to see if the timer has expired
ulMaxExpiryCountBeforeStopping yet. */
ulCount++;
Listing 184 Definition of the callback function used in the calls to xTimerCreate() in
Listing 185
261
#define NUM_TIMERS 5
/* Create then start some timers. Starting the timers before the RTOS scheduler has been
started means the timers will start running immediately that the RTOS scheduler starts. */
for( x = 0; x < NUM_TIMERS; x++ )
{
xTimers[ x ] = xTimerCreate( /* Just a text name, not used by the RTOS kernel. */
"Timer",
/* The timer period in ticks, must be greater than 0. */
( 100 * x ) + 100,
/* The timers will auto-reload themselves when they
expire. */
pdTRUE,
/* The ID is used to store a count of the number of
times the timer has expired, which is initialized to 0. */
( void * ) 0,
/* Each timer calls the same callback when it expires. */
vTimerCallback );
/* ...
Create tasks here.
... */
/* Starting the RTOS scheduler will start the timers running as they have already been set
into the active state. */
vTaskStartScheduler();
262
5.4 xTimerCreateStatic()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Creates a new software timer and returns a handle by which the created software timer can be
referenced.
Each software timer requires a small amount of RAM that is used to hold the timer’s state. If a
software timer is created using xTimerCreate() then this RAM is automatically allocated from
the FreeRTOS heap. If a software timer is created using xTimerCreateStatic() then the RAM
is provided by the application writer, which requires an additional parameter, but allows the
RAM to be statically allocated at compile time.
Creating a timer does not start the timer running. The xTimerStart(), xTimerReset(),
xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
xTimerChangePeriodFromISR() API functions can all be used to start the timer running.
Parameters
pcTimerName A plain text name that is assigned to the timer, purely to assist
debugging.
263
pdMS_TO_TICKS( 500 ), provided configTICK_RATE_HZ is less than or
equal to 1000.
Once started, a one-shot timer will expire only once. A one-shot timer
can be manually restarted after it has expired.
pvTimerID An identifier that is assigned to the timer being created. The identifier
can later be updated using the vTimerSetTimerID() API function.
pxCallbackFunction The function to call when the timer expires. Callback functions must
have the prototype defined by the TimerCallbackFunction_t typedef.
The required prototype is shown in Listing 183.
pxTimerBuffer Must point to a variable of type StaticTimer_t, which is then used to hold
the timer's state.
Return Values
NULL The software timer could not be created because pxTimerBuffer was NULL.
Any other The software timer was created successfully and the returned value is the
value handle by which the created software timer can be referenced.
264
Notes
Example
/* Define a callback function that will be used by multiple timer instances. The callback
function does nothing but count the number of times the associated timer expires, and stop the
timer once the timer has expired 10 times. The count is saved as the ID of the timer. */
void vTimerCallback( TimerHandle_t xTimer )
{
const uint32_t ulMaxExpiryCountBeforeStopping = 10;
uint32_t ulCount;
/* The number of times this timer has expired is saved as the timer's ID. Obtain the
count. */
ulCount = ( uint32_t ) pvTimerGetTimerID( xTimer );
/* Increment the count, then test to see if the timer has expired
ulMaxExpiryCountBeforeStopping yet. */
ulCount++;
Listing 188 Definition of the callback function used in the calls to xTimerCreate() in
Listing 185
265
#define NUM_TIMERS 5
/* An array of StaticTimer_t structures, which are used to store the state of each created
timer. */
StaticTimer_t xTimerBuffers[ NUM_TIMERS ];
/* Create then start some timers. Starting the timers before the RTOS scheduler has been
started means the timers will start running immediately that the RTOS scheduler starts. */
for( x = 0; x < NUM_TIMERS; x++ )
{
xTimers[ x ] = xTimerCreateStatic( /* Just a text name, not used by the RTOS kernel. */
"Timer",
/* The timer period in ticks, must be greater than
0. */
( 100 * x ) + 100,
/* The timers will auto-reload themselves when they
expire. */
pdTRUE,
/* The ID is used to store a count of the number of
times the timer has expired, which is initialized
to 0. */
( void * ) 0,
/* Each timer calls the same callback when it
expires. */
vTimerCallback,
/* Pass in the address of a StaticTimer_t variable,
which will hold the data associated with the timer
being created. */
&( xTimerBuffers[ x ] ); );
/* ...
Create tasks here.
... */
/* Starting the RTOS scheduler will start the timers running as they have already been set
into the active state. */
vTaskStartScheduler();
266
5.5 xTimerDelete()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Deletes a timer. The timer must first have been created using the xTimerCreate() API
function.
Parameters
xTicksToWait Timer functionality is not provided by the core FreeRTOS code, but by a timer
service (or daemon) task. The FreeRTOS timer API sends commands to the
timer service task on a queue called the timer command queue. xTicksToWait
specifies the maximum amount of time the task should remain in the Blocked
state to wait for space to become available on the timer command queue,
should the queue already be full.
The block time is specified in tick periods, so the absolute time it represents is
dependent on the tick frequency. The pdMS_TO_TICKS() macro can be used
to convert a time specified in milliseconds to a time specified in ticks.
Return Values
pdPASS The delete command was successfully sent to the timer command queue.
267
If a block time was specified (xTicksToWait was not zero), then it is possible that
the calling task was placed into the Blocked state to wait for space to become
available on the timer command queue before the function returned, but data was
successfully written to the queue before the block time expired.
When the command is actually processed will depend on the priority of the timer
service task relative to other tasks in the system. The priority of the timer service
task is set by the configTIMER_TASK_PRIORITY configuration constant.
pdFAIL The delete command was not sent to the timer command queue because the queue
was already full.
If a block time was specified (xTicksToWait was not zero) then the calling task will
have been placed into the Blocked state to wait for the timer service task to make
room in the queue, but the specified block time expired before that happened.
Notes
Example
268
5.1 xTimerGetExpiryTime()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Returns the time at which a software timer will expire, which is the time the software timer's
callback function will execute.
Parameters
Return Values
If the timer referenced by xTimer is active, then the time at which the timer’s callback function
will next execute is returned. The time is specified in RTOS ticks.
The return value is undefined if the timer referenced by xTimer is not active. The
xTimerIsTimerActive() API function can be used to determine if a timer is active.
Notes
If the value returned by xTimerGetExpiryTime() is less than the current tick count then the
timer will not expire until after the tick count has overflowed and wrapped back to 0. Overflows
are handled in the RTOS implementation itself, so a timer’s callback function will execute at
the correct time whether it is before or after the tick count overflows.
269
Example
/* Calculate the time that remains before the timer referenced by xTimer
Expires and executes its callback function.
270
5.1 pcTimerGetName()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Returns the human readable text name assigned to the timer when the timer was created.
See the xTimerCreate() API function for more information.
Parameters
Return Values
Timer names are standard NULL terminated C strings. The value returned is a pointer to the
subject timer’s name.
Notes
271
5.2 xTimerGetPeriod()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Returns the period of a software timer. The period is specified in RTOS ticks.
The period of a software timer is initially specified by the xTimerPeriod parameter of the call to
xTimerCreate() used to create the timer. It can subsequently be changed using the
xTimerChangePeriod() and xTimerChangePeriodFromISR() API functions.
Parameters
Return Values
Notes
Example
272
5.3 xTimerGetTimerDaemonTaskHandle()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Returns the task handle associated with the software timer daemon (or service) task. If
configUSE_TIMERS is set to 1 in FreeRTOSConfig.h, then the timer daemon task is created
automatically when the scheduler is started. All FreeRTOS software timer callback functions
run in the context of the timer daemon task.
Parameters
None.
Return Values
The handle of the timer daemon task. FreeRTOS software timer callback functions run in the
context of the software daemon task.
Notes
273
5.4 pvTimerGetTimerID()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Returns the identifier (ID) assigned to the timer. An identifier is assigned to the timer when the
timer is created, and can be updated using the vTimerSetTimerID() API function. See the
xTimerCreate() API function for more information.
If the same callback function is assigned to multiple timers, the timer identifier can be
inspected inside the callback function to determine which timer actually expired. This is
demonstrated in the example code provided for the xTimerCreate() API function.
In addition the timer’s identifier can be used to store values in between calls to the timer’s
callback function.
Parameters
Return Values
Notes
274
Example
/* A count of the number of times this timer has expired and executed its
callback function is stored in the timer's ID. Retrieve the count, increment it,
then save it back into the timer's ID. */
ulCallCount = ( uint32_t ) pvTimerGetTimerID( pxExpiredTimer );
ulCallCount++;
vTimerSetTimerID( pxExpiredTimer, ( void * ) ulCallCount );
}
275
5.5 xTimerIsTimerActive()
#include “FreeRTOS.h”
#include “timers.h”
Summary
2. The timer is a one shot timer that has not been restarted since it expired.
Parameters
Return Values
Notes
276
Example
277
5.6 xTimerPendFunctionCall()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Used to defer the execution of a function to the RTOS daemon task (also known as the timer
service task, hence this function is implemented in timers.c and is prefixed with 'Timer').
This function must not be called from an interrupt service routine. See
xTimerPendFunctionCallFromISR() for a version that can be called from an interrupt service
routine.
Functions that can be deferred to the RTOS daemon task must have the prototype
demonstrated by Listing 202.
Listing 202 The prototype of a function that can be pended using a call to
xTimerPendFunctionCall()
The pvParameter1 and ulParameter2 parameters are provided for use by the application code.
Parameters
xFunctionToPend The function to execute from the timer service/daemon task. The function
must conform to the PendedFunction_t prototype shown in Listing 202.
pvParameter1 The value to pass into the callback function as the function's first
parameter. The parameter has a void * type to allow it to be used to pass
any type. For example, integer types can be cast to a void *, or the void *
can be used to point to a structure.
278
ulParameter2 The value to pass into the callback function as the function’s second
parameter.
Return Values
pdPASS The message was successfully sent to the RTOS daemon task.
Any other The message was not sent to the RTOS daemon task because the message
value queue was already full. The length of the queue is set by the value of
configTIMER_QUEUE_LENGTH in FreeRTOSConfig.h.
Notes
279
5.7 xTimerPendFunctionCallFromISR()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Used from application interrupt service routines to defer the execution of a function to the
RTOS daemon task (also known as the timer service task, hence this function is implemented
in timers.c and is prefixed with 'Timer').
Ideally an interrupt service routine (ISR) is kept as short as possible, but sometimes an ISR
either has a lot of processing to do, or needs to perform processing that is not deterministic. In
these cases xTimerPendFunctionCallFromISR() can be used to defer processing of a function
to the RTOS daemon task.
A mechanism is provided that allows the interrupt to return directly to the task that will
subsequently execute the pended function. This allows the callback function to execute
contiguously in time with the interrupt - just as if the callback had executed in the interrupt
itself.
Functions that can be deferred to the RTOS daemon task must have the prototype
demonstrated by Listing 204.
Listing 204 The prototype of a function that can be pended using a call to
xTimerPendFunctionCallFromISR()
The pvParameter1 and ulParameter2 parameters are provided for use by the application code.
280
Parameters
pvParameter1 The value that will be passed into the callback function as the
function’s first parameter. The parameter has a void * type to
allow it to be used to pass any type. For example, integer types
can be cast to a void *, or the void * can be used to point to a
structure.
ulParameter2 The value that will be passed into the callback function as the
function’s second parameter.
Return Values
pdPASS The message was successfully sent to the RTOS daemon task.
Any other The message was not sent to the RTOS daemon task because the message
value queue was already full. The length of the queue is set by the value of
configTIMER_QUEUE_LENGTH in FreeRTOSConfig.h.
Notes
281
Example
/* The callback function that will execute in the context of the daemon task.
Note callback functions must all use this same prototype. */
void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 )
{
BaseType_t xInterfaceToService;
282
5.8 xTimerReset()
#include “FreeRTOS.h”
#include “timers.h”
Summary
If the timer is already running, then the timer will recalculate its expiry time to be relative to
when xTimerReset() was called.
If the timer was not running, then the timer will calculate an expiry time relative to when
xTimerReset() was called, and the timer will start running. In this case, xTimerReset() is
functionally equivalent to xTimerStart().
Resetting a timer ensures the timer is running. If the timer is not stopped, deleted, or reset in
the meantime, the callback function associated with the timer will get called ‘n’ ticks after
xTimerReset() was called, where ‘n’ is the timer’s defined period.
If xTimerReset() is called before the scheduler is started, then the timer will not start running
until the scheduler has been started, and the timer’s expiry time will be relative to when the
scheduler started.
Parameters
xTicksToWait Timer functionality is not provided by the core FreeRTOS code, but by a timer
service (or daemon) task. The FreeRTOS timer API sends commands to the
timer service task on a queue called the timer command queue. xTicksToWait
specifies the maximum amount of time the task should remain in the Blocked
state to wait for space to become available on the timer command queue,
283
should the queue already be full.
The block time is specified in tick periods, so the absolute time it represents is
dependent on the tick frequency. The pdMS_TO_TICKS() macro can be used
to convert a time specified in milliseconds to a time specified in ticks.
Return Values
pdPASS The reset command was successfully sent to the timer command queue.
If a block time was specified (xTicksToWait was not zero), then it is possible that
the calling task was placed into the Blocked state to wait for space to become
available on the timer command queue before the function returned, but data was
successfully written to the queue before the block time expired.
When the command is actually processed will depend on the priority of the timer
service task relative to other tasks in the system, although the timer’s expiry time is
relative to when xTimerReset() is actually called. The priority of the timer service
task is set by the configTIMER_TASK_PRIORITY configuration constant.
pdFAIL The reset command was not sent to the timer command queue because the queue
was already full.
If a block time was specified (xTicksToWait was not zero) then the calling task will
have been placed into the Blocked state to wait for the timer service task to make
room in the queue, but the specified block time expired before that happened.
Notes
284
Example
/* In this example, when a key is pressed, an LCD back-light is switched on. If 5 seconds pass
without a key being pressed, then the LCD back-light is switched off by a one-shot timer. */
/* The callback function assigned to the one-shot timer. In this case the parameter is not
used. */
void vBacklightTimerCallback( TimerHandle_t pxTimer )
{
/* The timer expired, therefore 5 seconds must have passed since a key was pressed. Switch
off the LCD back-light.
vSetBacklightState( BACKLIGHT_OFF );
}
/* Starting the scheduler will start the timer running as xTimerStart has already been
called. */
xTaskStartScheduler();
}
285
5.9 xTimerResetFromISR()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Parameters
xTimer The handle of the timer that is being started, reset, or restarted.
Return Values
pdPASS The reset command was successfully sent to the timer command queue. When the
command is actually processed will depend on the priority of the timer service task
relative to other tasks in the system, although the timer’s expiry time is relative to
when xTimerResetFromISR() is actually called. The priority of the timer service
task is set by the configTIMER_TASK_PRIORITY configuration constant.
pdFAIL The reset command was not sent to the timer command queue because the queue
was already full.
286
Notes
Example
/* This scenario assumes xBacklightTimer has already been created. When a key is
pressed, an LCD back-light is switched on. If 5 seconds pass without a key being
pressed, then the LCD back-light is switched off by a one-shot timer. Unlike the
example given for the xTimerReset() function, the key press event handler is an
interrupt service routine. */
/* The callback function assigned to the one-shot timer. In this case the parameter
is not used. */
void vBacklightTimerCallback( TimerHandle_t pxTimer )
{
/* The timer expired, therefore 5 seconds must have passed since a key was
pressed. Switch off the LCD back-light. */
vSetBacklightState( BACKLIGHT_OFF );
}
/* Ensure the LCD back-light is on, then reset the timer that is responsible for
turning the back-light off after 5 seconds of key inactivity. This is an
interrupt service routine so can only call FreeRTOS API functions that end in
"FromISR". */
vSetBacklightState( BACKLIGHT_ON );
287
5.10 vTimerSetTimerID()
#include “FreeRTOS.h”
#include “timers.h”
Summary
An identifier (ID) is assigned to a timer when the timer is created, and can be changed at any
time using the vTimerSetTimerID() API function.
If the same callback function is assigned to multiple timers, the timer identifier can be
inspected inside the callback function to determine which timer actually expired.
The timer identifier can also be used to store data in the timer between calls to the timer’s
callback function.
Parameters
xTimer The handle of the timer being updated with a new identifier.
Notes
288
Example
/* A count of the number of times this timer has expired and executed its
callback function is stored in the timer's ID. Retrieve the count, increment it,
then save it back into the timer's ID. */
ulCallCount = ( uint32_t ) pvTimerGetTimerID( pxExpiredTimer );
ulCallCount++;
vTimerSetTimerID( pxExpiredTimer, ( void * ) ulCallCount );
}
289
5.11 xTimerStart()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Starts a timer running. xTimerStartFromISR() is an equivalent function that can be called from
an interrupt service routine.
If the timer was not already running, then the timer will calculate an expiry time relative to
when xTimerStart() was called.
If the timer was already running, then xTimerStart() is functionally equivalent to xTimerReset().
If the timer is not stopped, deleted, or reset in the meantime, the callback function associated
with the timer will get called ‘n’ ticks after xTimerStart() was called, where ‘n’ is the timer’s
defined period.
Parameters
xTicksToWait Timer functionality is not provided by the core FreeRTOS code, but by a timer
service (or daemon) task. The FreeRTOS timer API sends commands to the
timer service task on a queue called the timer command queue. xTicksToWait
specifies the maximum amount of time the task should remain in the Blocked
state to wait for space to become available on the timer command queue,
should the queue already be full.
The block time is specified in tick periods, so the absolute time it represents is
dependent on the tick frequency. The pdMS_TO_TICKS() macro can be used
to convert a time specified in milliseconds to a time specified in ticks.
290
indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1
in FreeRTOSConfig.h.
Return Values
pdPASS The start command was successfully sent to the timer command queue.
If a block time was specified (xTicksToWait was not zero), then it is possible that
the calling task was placed into the Blocked state to wait for space to become
available on the timer command queue before the function returned, but data was
successfully written to the queue before the block time expired.
When the command is actually processed will depend on the priority of the timer
service task relative to other tasks in the system, although the timer’s expiry time is
relative to when xTimerStart() is actually called. The priority of the timer service
task is set by the configTIMER_TASK_PRIORITY configuration constant.
pdFAIL The start command was not sent to the timer command queue because the queue
was already full.
If a block time was specified (xTicksToWait was not zero) then the calling task will
have been placed into the Blocked state to wait for the timer service task to make
room in the queue, but the specified block time expired before that happened.
Notes
Example
291
5.12 xTimerStartFromISR()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Parameters
xTimer The handle of the timer that is being started, reset, or restarted.
Return Values
pdPASS The start command was successfully sent to the timer command queue. When the
command is actually processed will depend on the priority of the timer service task
relative to other tasks in the system, although the timer’s expiry time is relative to
when xTimerStartFromISR() is actually called. The priority of the timer service task
is set by the configTIMER_TASK_PRIORITY configuration constant.
pdFAIL The start command was not sent to the timer command queue because the queue
was already full.
292
Notes
Example
/* This scenario assumes xBacklightTimer has already been created. When a key is
pressed, an LCD back-light is switched on. If 5 seconds pass without a key being
pressed, then the LCD back-light is switched off by a one-shot timer. Unlike the
example given for the xTimerReset() function, the key press event handler is an
interrupt service routine. */
/* The callback function assigned to the one-shot timer. In this case the parameter
is not used. */
void vBacklightTimerCallback( TimerHandle_t pxTimer )
{
/* The timer expired, therefore 5 seconds must have passed since a key was
pressed. Switch off the LCD back-light. */
vSetBacklightState( BACKLIGHT_OFF );
}
/* Ensure the LCD back-light is on, then restart the timer that is responsible
for turning the back-light off after 5 seconds of key inactivity. This is an
interrupt service routine so can only call FreeRTOS API functions that end in
"FromISR". */
vSetBacklightState( BACKLIGHT_ON );
293
5.13 xTimerStop()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Stops a timer running. xTimerStopFromISR() is an equivalent function that can be called from
an interrupt service routine.
Parameters
xTicksToWait Timer functionality is not provided by the core FreeRTOS code, but by a timer
service (or daemon) task. The FreeRTOS timer API sends commands to the
timer service task on a queue called the timer command queue. xTicksToWait
specifies the maximum amount of time the task should remain in the Blocked
state to wait for space to become available on the timer command queue,
should the queue already be full.
The block time is specified in tick periods, so the absolute time it represents is
dependent on the tick frequency. The pdMS_TO_TICKS() macro can be used
to convert a time specified in milliseconds to a time specified in ticks.
Return Values
pdPASS The stop command was successfully sent to the timer command queue.
294
If a block time was specified (xTicksToWait was not zero), then it is possible that
the calling task was placed into the Blocked state to wait for space to become
available on the timer command queue before the function returned, but data was
successfully written to the queue before the block time expired.
When the command is actually processed will depend on the priority of the timer
service task relative to other tasks in the system. The priority of the timer service
task is set by the configTIMER_TASK_PRIORITY configuration constant.
pdFAIL The stop command was not sent to the timer command queue because the queue
was already full.
If a block time was specified (xTicksToWait was not zero) then the calling task will
have been placed into the Blocked state to wait for the timer service task to make
room in the queue, but the specified block time expired before that happened.
Notes
Example
295
5.14 xTimerStopFromISR()
#include “FreeRTOS.h”
#include “timers.h”
Summary
Parameters
Return Values
pdPASS The stop command was successfully sent to the timer command queue. When the
command is actually processed will depend on the priority of the timer service task
relative to other tasks in the system. The priority of the timer service task is set by
the configTIMER_TASK_PRIORITY configuration constant.
pdFAIL The stop command was not sent to the timer command queue because the queue
was already full.
296
Notes
Example
/* This scenario assumes xTimer has already been created and started. When an
interrupt occurs, the timer should be simply stopped. */
297
Chapter 6
298
6.1 xEventGroupClearBits()
#include “FreeRTOS.h”
#include “event_groups.h”
Summary
Clear bits (flags) within an RTOS event group. This function cannot be called from an
interrupt. See xEventGroupClearBitsFromISR() for a version that can be called from an
interrupt.
Parameters
xEventGroup The event group in which the bits are to be cleared. The event group must
have previously been created using a call to xEventGroupCreate().
uxBitsToClear A bitwise value that indicates the bit or bits to clear in the event group. For
example set uxBitsToClear to 0x08 to clear just bit 3. Set uxBitsToClear to
0x09 to clear bit 3 and bit 0.
Return Values
All values The value of the bits in the event group before any bits were cleared.
Notes
The RTOS source file FreeRTOS/source/event_groups.c must be included in the build for the
xEventGroupClearBits() function to be available.
299
Example
300
6.2 xEventGroupClearBitsFromISR()
#include “FreeRTOS.h”
#include “event_groups.h”
Summary
Parameters
xEventGroup The event group in which the bits are to be cleared. The event group must
have previously been created using a call to xEventGroupCreate().
uxBitsToClear A bitwise value that indicates the bit or bits to clear in the event group. For
example set uxBitsToClear to 0x08 to clear just bit 3. Set uxBitsToClear to
0x09 to clear bit 3 and bit 0.
Return Values
pdFAIL The message could not be sent to the RTOS daemon task (also known as
the timer service task) because the timer command queue was full. The
length of the queue is set by the configTIMER_QUEUE_LENGTH setting in
FreeRTOSConfig.h.
Notes
The RTOS source file FreeRTOS/source/event_groups.c must be included in the build for the
xEventGroupClearBitsFromISR() function to be available.
301
302
Example
/* This code assumes the event group referenced by the xEventGroup variable has
already been created using a call to xEventGroupCreate(). */
void anInterruptHandler( void )
{
BaseType_t xSuccess;
303
6.3 xEventGroupCreate()
#include “FreeRTOS.h”
#include “event_groups.h”
Summary
Creates a new event group and returns a handle by which the created event group can be
referenced.
Each event group requires a [very] small amount of RAM that is used to hold the event group’s
state. If an event group is created using xEventGroupCreate() then this RAM is automatically
allocated from the FreeRTOS heap. If an event group is created using
xEventGroupCreateStatic() then the RAM is provided by the application writer, which requires
an additional parameter, but allows the RAM to be statically allocated at compile time.
Event groups are stored in variables of type EventGroupHandle_t. The number of bits (or
flags) implemented within an event group is 8 if configUSE_16_BIT_TICKS is set to 1, or 24 if
configUSE_16_BIT_TICKS is set to 0. The dependency on configUSE_16_BIT_TICKS results
from the data type used for thread local storage in the internal implementation of RTOS tasks.
Parameters
None
Return Values
NULL The event group could not be created because there was insufficient
FreeRTOS heap available.
Any other value The event group was created and the value returned is the handle of the
created event group.
304
Notes
Example
305
6.4 xEventGroupCreateStatic()
#include “FreeRTOS.h”
#include “event_groups.h”
Summary
Creates a new event group and returns a handle by which the created event group can be
referenced.
Each event group requires a [very] small amount of RAM that is used to hold the event group’s
state. If an event group is created using xEventGroupCreate() then this RAM is automatically
allocated from the FreeRTOS heap. If an event group is created using
xEventGroupCreateStatic() then the RAM is provided by the application writer, which requires
an additional parameter, but allows the RAM to be statically allocated at compile time.
Event groups are stored in variables of type EventGroupHandle_t. The number of bits (or
flags) implemented within an event group is 8 if configUSE_16_BIT_TICKS is set to 1, or 24 if
configUSE_16_BIT_TICKS is set to 0. The dependency on configUSE_16_BIT_TICKS results
from the data type used for thread local storage in the internal implementation of RTOS tasks.
Parameters
Return Values
NULL The event group could not be created because pxEventGroupBuffer was
NULL.
Any other value The event group was created and the value returned is the handle of the
created event group.
306
Notes
Example
/* Declare a variable to hold the data associated with the created event group. */
StaticEventGroup_t xCreatedEventGroup;
/* pxEventGroupBuffer was not null so expect the event group to have been
created. */
configASSERT( xEventGroupHandle );
}
307
6.1 vEventGroupDelete()
#include “FreeRTOS.h”
#include “event_groups.h”
Summary
Delete an event group that was previously created using a call to xEventGroupCreate().
Tasks that are blocked on the event group being deleted will be unblocked and report an event
group value of 0.
Parameters
Return Values
None
Notes
The RTOS source file FreeRTOS/source/event_groups.c must be included in the build for the
vEventGroupDelete() function to be available.
308
6.2 xEventGroupGetBits()
#include “FreeRTOS.h”
#include “event_groups.h”
Summary
Returns the current value of the event bits (event flags) in an event group. This function
cannot be used from an interrupt. See xEventGroupGetBitsFromISR() for a version that can
be used in an interrupt.
Parameters
xEventGroup The event group being queried. The event group must have previously been
created using a call to xEventGroupCreate().
Return Values
All values The value of the event bits in the event group at the time
xEventGroupGetBits() was called.
Notes
The RTOS source file FreeRTOS/source/event_groups.c must be included in the build for the
xEventGroupGetBits() function to be available.
309
6.1 xEventGroupGetBitsFromISR()
#include “FreeRTOS.h”
#include “event_groups.h”
Summary
Parameters
xEventGroup The event group being queried. The event group must have previously been
created using a call to xEventGroupCreate().
Return Values
All values The value of the event bits in the event group at the time
xEventGroupGetBitsFromISR() was called.
Notes
The RTOS source file FreeRTOS/source/event_groups.c must be included in the build for the
xEventGroupGetBitsFromISR() function to be available.
310
6.2 xEventGroupSetBits()
#include “FreeRTOS.h”
#include “event_groups.h”
Summary
Sets bits (flags) within an RTOS event group. This function cannot be called from an interrupt.
See xEventGroupSetBitsFromISR() for a version that can be called from an interrupt.
Setting bits in an event group will automatically unblock any tasks that were blocked waiting
for the bits to be set.
Parameters
xEventGroup The event group in which the bits are to be set. The event group must have
previously been created using a call to xEventGroupCreate().
uxBitsToSet A bitwise value that indicates the bit or bits to set in the event group. For
example, set uxBitsToSet to 0x08 to set only bit 3. Set uxBitsToSet to 0x09 to
set bit 3 and bit 0.
Return Values
Any Value The value of the bits in the event group at the time the call to
xEventGroupSetBits() returned.
There are two reasons why the returned value might have the bits specified
by the uxBitsToSet parameter cleared:
1. If setting a bit results in a task that was waiting for the bit leaving the
blocked state then it is possible the bit will have been cleared
automatically (see the xClearBitsOnExit parameter of
xEventGroupWaitBits()).
311
2. Any task that leaves the blocked state as a result of the bits being
set (or otherwise any Ready state task) that has a priority above that
of the task that called xEventGroupSetBits() will execute and may
change the event group value before the call to
xEventGroupSetBits() returns.
Notes
The RTOS source file FreeRTOS/source/event_groups.c must be included in the build for the
xEventGroupSetBits() function to be available.
Example
312
6.3 xEventGroupSetBitsFromISR()
#include “FreeRTOS.h”
#include “event_groups.h”
Summary
Set bits (flags) within an event group. A version of xEventGroupSetBits() that can be called
from an interrupt service routine (ISR).
Setting bits in an event group will automatically unblock any tasks that were blocked waiting
for the bits to be set.
Setting bits in an event group is not a deterministic operation because there are an unknown
number of tasks that may be waiting for the bit or bits being set. FreeRTOS does not allow
non-deterministic operations to be performed in interrupts or from critical sections. Therefore
xEventGroupSetBitsFromISR() sends a message to the RTOS daemon task to have the set
operation performed in the context of the daemon task - where a scheduler lock is used in
place of a critical section. The priority of the daemon task is set by
configTIMER_TASK_PRIORITY in FreeRTOSConfig.h.
Parameters
xEventGroup The event group in which the bits are to be set. The event
group must have previously been created using a call to
xEventGroupCreate().
uxBitsToSet A bitwise value that indicates the bit or bits to set in the event
group. For example, set uxBitsToSet to 0x08 to set only bit 3.
Set uxBitsToSet to 0x09 to set bit 3 and bit 0.
313
task (the task the interrupt interrupted) then
*pxHigherPriorityTaskWoken will be set to pdTRUE by
xEventGroupSetBitsFromISR(), indicating that a context switch
should be requested before the interrupt exits. For that reason
*pxHigherPriorityTaskWoken must be initialized to pdFALSE.
See the example code below.
Return Values
pdFAIL The message could not be sent to the RTOS daemon task (also known as
the timer service task) because the timer command queue was full. The
length of the queue is set by the configTIMER_QUEUE_LENGTH setting in
FreeRTOSConfig.h.
Notes
The RTOS source file FreeRTOS/source/event_groups.c must be included in the build for the
xEventGroupSetBitsFromISR() function to be available.
314
Example
315
6.1 xEventGroupSync()
#include “FreeRTOS.h”
#include “event_groups.h”
Summary
Atomically set bits (flags) within an event group, then wait for a combination of bits to be set
within the same event group. This functionality is typically used to synchronize multiple tasks
(often called a task rendezvous), where each task has to wait for the other tasks to reach a
synchronization point before proceeding.
The function will return before its block time expires if the bits specified by the uxBitsToWaitFor
parameter are set, or become set within that time. In this case all the bits specified by
uxBitsToWaitFor will be automatically cleared before the function returns.
Parameters
xEventGroup The event group in which the bits are being set and tested. The event group
must have previously been created using a call to xEventGroupCreate().
uxBitsToSet A bitwise value that indicates the bit or bits to set in the event group before
determining if (and possibly waiting for) all the bits specified by the
uxBitsToWaitFor parameter are set. For example, set uxBitsToSet to 0x04
to set bit 2 within the event group.
uxBitsToWaitFor A bitwise value that indicates the bit or bits to test inside the event group.
For example, set uxBitsToWaitFor to 0x05 to wait for bit 0 and bit 2. Set
uxBitsToWaitFor to 0x07 to wait for bit 0 and bit 1 and bit 2. Etc.
xTicksToWait The maximum amount of time (specified in 'ticks') to wait for all the bits
specified by the uxBitsToWaitFor parameter value to become set.
316
Return Values
All values The value of the event group at the time either the bits being waited for
became set, or the block time expired. Test the return value to know which
bits were set.
If xEventGroupSync() returned because its timeout expired then not all the
bits being waited for will be set in the returned value.
If xEventGroupSync() returned because all the bits it was waiting for were
set then the returned value is the event group value before any bits were
automatically cleared.
Notes
The RTOS source file FreeRTOS/source/event_groups.c must be included in the build for the
xEventGroupSync() function to be available.
317
Example
for( ;; )
{
/* Perform task functionality here. */
. . .
/* Set bit 0 in the event group to note this task has reached the
sync point. The other two tasks will set the other two bits defined
by ALL_SYNC_BITS. All three tasks have reached the synchronization
point when all the ALL_SYNC_BITS bits are set. Wait a maximum of 100ms
for this to happen. */
uxReturn = xEventGroupSync( xEventBits,
TASK_0_BIT, /* The bit to set. */
ALL_SYNC_BITS, /* The bits to wait for. */
xTicksToWait );/* Timeout value. */
/* Set bit 1 in the event group to note this task has reached the
synchronization point. The other two tasks will set the other two
bits defined by ALL_SYNC_BITS. All three tasks have reached the
synchronization point when all the ALL_SYNC_BITS are set. Wait
indefinitely for this to happen. */
xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
318
void vTask2( void *pvParameters )
{
for( ;; )
{
/* Perform task functionality here. */
. . .
/* Set bit 2 in the event group to note this task has reached the
synchronization point. The other two tasks will set the other two
bits defined by ALL_SYNC_BITS. All three tasks have reached the
synchronization point when all the ALL_SYNC_BITS are set. Wait
indefinitely for this to happen. */
xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
319
6.2 xEventGroupWaitBits()
#include “FreeRTOS.h”
#include “event_groups.h”
Summary
Read bits within an RTOS event group, optionally entering the Blocked state (with a timeout)
to wait for a bit or group of bits to become set.
Parameters
xEventGroup The event group in which the bits are being tested. The event group must
have previously been created using a call to xEventGroupCreate().
uxBitsToWaitFor A bitwise value that indicates the bit or bits to test inside the event group.
For example, to wait for bit 0 and/or bit 2 set uxBitsToWaitFor to 0x05. To
wait for bits 0 and/or bit 1 and/or bit 2 set uxBitsToWaitFor to 0x07. Etc.
xClearOnExit If xClearOnExit is set to pdTRUE then any bits set in the value passed as
the uxBitsToWaitFor parameter will be cleared in the event group before
xEventGroupWaitBits() returns if xEventGroupWaitBits() returns for any
reason other than a timeout. The timeout value is set by the xTicksToWait
parameter.
If xClearOnExit is set to pdFALSE then the bits set in the event group are
not altered when the call to xEventGroupWaitBits() returns.
xWaitAllBits xWaitForAllBits is used to create either a logical AND test (where all bits
must be set) or a logical OR test (where one or more bits must be set) as
320
follows:
xTicksToWait The maximum amount of time (specified in 'ticks') to wait for one/all
(depending on the xWaitForAllBits value) of the bits specified by
uxBitsToWaitFor to become set.
Return Values
Any Value The value of the event group at the time either the event bits being waited
for became set, or the block time expired. The current value of the event
bits in an event group will be different to the returned value if a higher
priority task or interrupt changed the value of an event bit between the
calling task leaving the Blocked state and exiting the xEventGroupWaitBits()
function.
Test the return value to know which bits were set. If xEventGroupWaitBits()
returned because its timeout expired then not all the bits being waited for
will be set. If xEventGroupWaitBits() returned because the bits it was
waiting for were set then the returned value is the event group value before
any bits were automatically cleared in the case that xClearOnExit parameter
was set to pdTRUE.
Notes
The RTOS source file FreeRTOS/source/event_groups.c must be included in the build for the
xEventGroupWaitBits() function to be available.
321
Example
322
Chapter 7
Kernel Configuration
323
7.1 FreeRTOSConfig.h
All the demo application projects included in the FreeRTOS download contains a pre-defined
FreeRTOSConfig.h that can be used as a reference or simply copied. Note, however, that
some of the demo projects were generated before all the options documented in this chapter
were available, so the FreeRTOSConfig.h header files they contain will not include all the
constants and options that are documented in the following sub-sections.
324
7.2 Constants that Start “INCLUDE_”
Constants that start with the text “INCLUDE_” are used to included or excluded FreeRTOS API
functions from the application. For example, setting INCLUDE_vTaskPrioritySet to 0 will
exclude the vTaskPrioritySet() API function from the build, meaning the application cannot call
vTaskPrioritySet(). Setting INCLUDE_vTaskPrioritySet to 1 will include the vTaskPrioritySet()
API function in the build, so the application can call vTaskPrioritySet().
In some cases, a single INCLUDE_ configuration constant will include or exclude multiple API
functions.
The “INCLUDE_” constants are provided to permit the code size to be reduced by removing
FreeRTOS functions and features that are not required. However, most linkers will, by default,
automatically remove unreferenced code unless optimization is turned completely off. Linkers
that do not have this default behavior can normally be configured to remove unreferenced
code. Therefore, in most practical cases, the INCLUDE_ configuration constants will have little
if any impact on the executable code size.
It is possible that excluding an API function from an application will also reduce the amount of
RAM used by the FreeRTOS kernel. For example, removing the vTaskSuspend() API function
will also prevent the structures that would otherwise reference Suspended tasks from ever
being allocated.
INCLUDE_xEventGroupSetBitsFromISR
INCLUDE_xSemaphoreGetMutexHolder
325
INCLUDE_xTaskAbortDelay
INCLUDE_vTaskDelay
INCLUDE_vTaskDelayUntil
INCLUDE_vTaskDelete
INCLUDE_xTaskGetCurrentTaskHandle
INCLUDE_xTaskGetHandle
INCLUDE_xTaskGetIdleTaskHandle
INCLUDE_xTaskGetSchedulerState
326
INCLUDE_uxTaskGetStackHighWaterMark
INCLUDE_uxTaskPriorityGet
INCLUDE_vTaskPrioritySet
INCLUDE_xTaskResumeFromISR
INCLUDE_eTaskGetState
INCLUDE_vTaskSuspend
Some queue and semaphore API functions allow the calling task to opt to be placed into the
Blocked state to wait for a queue or semaphore event to occur. These API functions require
that a maximum block period, or time out, is specified. The calling task will then be held in the
Blocked state until either the queue or semaphore event occurs, or the block period expires.
The maximum block period that can be specified is defined by portMAX_DELAY. If
INCLUDE_vTaskSuspend is set to 0, then specifying a block period of portMAX_DELAY will
327
result in the calling task being placed into the Blocked state for a maximum of
portMAX_DELAY ticks. If INCLUDE_vTaskSuspend is set to 1, then specifying a block period
of portMAX_DELAY will result in the calling task being placed into the Blocked state
indefinitely (without a time out). In the second case, the block period is indefinite, so the only
way out of the Blocked state is for the queue or semaphore event to occur.
INCLUDE_xTimerPendFunctionCall
328
7.3 Constants that Start “config”
Constants that start with the text “config” define attributes of the kernel, or include or exclude
features of the kernel.
configAPPLICATION_ALLOCATED_HEAP
By default the FreeRTOS heap is declared by FreeRTOS and placed in memory by the linker.
Setting configAPPLICATION_ALLOCATED_HEAP to 1 allows the heap to instead be declared
by the application writer, which allows the application writer to place the heap wherever they
like in memory.
Listing 237 Declaring an array that will be used as the FreeRTOS heap
configASSERT
If FreeRTOS is functioning correctly, and is being used correctly, then the configASSERT()
parameter will be non-zero. If the parameter is found to equal zero, then an error has
occurred.
It is likely that most errors trapped by configASSERT() will be a result of an invalid parameter
being passed into a FreeRTOS API function. configASSERT() can therefore assist in run time
debugging. However, defining configASSERT() will also increase the application code size,
and slow down its execution.
329
configASSERT() should be defined in FreeRTOSConfig.h. Listing 238 shows an example
configASSERT() definition that assumed vAssertCalled() is defined elsewhere by the
application.
configCHECK_FOR_STACK_OVERFLOW
Each task has a unique stack. If a task is created using the xTaskCreate() API function then
the stack is automatically allocated from the FreeRTOS heap, and the size of the stack is
specified by the xTaskCreate() usStackDepth parameter. If a task is created using the
xTaskCreateStatic() API function then the stack is pre-allocated by the application writer.
Stack overflow is a very common cause of application instability. FreeRTOS provides two
optional mechanisms that can be used to assist in stack overflow detection and debugging.
Which (if any) option is used is configured by the configCHECK_FOR_STACK_OVERFLOW
configuration constant.
The stack overflow hook function must be called vApplicationStackOverflowHook(), and have
the prototype shown in Listing 239.
The name and handle of the task that has exceeded its stack space are passed into the stack
overflow hook function using the pcTaskName and pxTask parameters respectively. It should
be noted that a stack overflow can potentially corrupted these parameters, in which case the
pxCurrentTCB variable can be inspected to determine which task caused the stack overflow
hook function to be called.
330
Stack overflow checking can only be used on architectures that have a linear (rather than
segmented) memory map.
Some processors will generate a fault exception in response to a stack corruption before the
stack overflow callback function can be called.
Stack overflow checking increases the time taken to perform a context switch.
It is likely that task stack utilization will reach its maximum when the
task’s context is saved to the stack during a context switch. Stack
overflow detection method one checks the stack utilization at that time
to ensure the task stack pointer remains within the valid stack area.
The stack overflow hook function will be called if the stack pointer
contains an invalid value (a value that references memory outside of
the valid stack area).
Method one is quick, but will not necessarily catch all stack overflow
occurrences.
The stack allocated to a task is filled with a known pattern at the time
the task is created. Method two checks the last n bytes within the
valid stack range to ensure this pattern remains unmodified (has not
been overwritten). The stack overflow hook function is called if any of
these n bytes have changed from their original values.
Method two is less efficient than method one, but still fast. It will catch
most stack overflow occurrences, although it is conceivable that some
could be missed (for example, where a stack overflow occurs without
331
the last n bytes being written to).
configCPU_CLOCK_HZ
This must be set to the frequency of the clock that drives the peripheral used to generate the
kernels periodic tick interrupt. This is very often, but not always, equal to the main system
clock frequency.
configSUPPORT_DYNAMIC_ALLOCATION
configENABLE_BACKWARD_COMPATIBILITY
The FreeRTOS.h header file includes a set of #define macros that map the names of data
types used in versions of FreeRTOS prior to version 8.0.0 to the names used in FreeRTOS
version 8.0.0. The macros allow application code to update the version of FreeRTOS they are
built against from a pre 8.0.0 version to a post 8.0.0 version without modification. Setting
configENABLE_BACKWARD_COMPATIBILITY to 0 in FreeRTOSConfig.h excludes the
macros from the build, and in so doing allowing validation that no pre version 8.0.0 names are
being used.
configGENERATE_RUN_TIME_STATS
The task run time statistics feature collects information on the amount of processing time each
task is receiving. The feature requires the application to configure a run time statistics time
base. The frequency of the run time statistics time base must be at least ten times greater
than the frequency of the tick interrupt.
332
configGENERATE_RUN_TIME_STATS to 0 will exclude the run time statistics gathering
functionality and associated API from the build.
configIDLE_SHOULD_YIELD
configIDLE_SHOULD_YIELD controls the behavior of the idle task if there are application
tasks that also run at the idle priority. It only has an effect if the preemptive scheduler is being
used.
333
Tasks that share a priority are scheduled using a round robin, time sliced, algorithm. Each
task will be selected in turn to enter the running state, but may not remain in the running state
for an entire tick period. For example, a task may be preempted, choose to yield, or choose to
enter the Blocked state before the next tick interrupt.
If configIDLE_SHOULD_YIELD is set to 0, then the idle task will never yield to another task,
and will only leave the Running state when it is pre-empted.
If configIDLE_SHOULD_YIELD is set to 1, then idle task will never perform more than one
iteration of its defined functionality without yielding to another task if there is another Idle
priority task that is in the Ready state. This ensures a minimum amount of time is spent in the
idle task when application tasks are available to run.
The Idle task consistently yielding to another Idle priority Ready state tasks has the side effect
shown in Figure 3.
Figure 3 Time line showing the execution of 4 tasks , all of which run at the idle
priority
Figure 3 shows the execution pattern of four tasks that all run at the idle priority. Tasks A, B
and C are application tasks. Task I is the idle task. The tick interrupt initiates a context switch
at regular intervals, shown at times T0, T1, T2, etc. It can be seen that the Idle task starts to
execute at time T2. It executes for part of a time slice, then yields to Task A. Task A executes
for the remainder of the same time slice, then gets pre-empted at time T3. Task I and task A
effectively share a single time slice, resulting in task B and task C consistently utilizing more
processing time than task A.
334
configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS
/* Call the library function, which now has access to all RAM. */
debug_printf( pcMessage );
Listing 240 An example of saving and restoring the processors privilege state
This technique should only be use during development, and not deployment, as it circumvents
the memory protection.
configKERNEL_INTERRUPT_PRIORITY,
configMAX_SYSCALL_INTERRUPT_PRIORITY,
configMAX_API_CALL_INTERRUPT_PRIORITY
335
configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY
are only relevant to ports that implement interrupt nesting.
As an example – imagine a hypothetical microcontroller that has seven interrupt priority levels.
In this hypothetical case, one is the lowest interrupt priority and seven is the highest interrupt
priority2. Figure 4 describes what can and cannot be done at each priority level when
configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY
are set to one and three respectively.
336
configMAX_SYSCALL_INTERRUPT_PRIORITY = 3
configKERNEL_INTERRUPT_PRIORITY = 1
configMAX_CO_ROUTINE_PRIORITIES
Sets the maximum priority that can be assigned to a co-routine. Co-routines can be assigned
a priority from zero, which is the lowest priority, to (configMAX_CO_ROUTINE_PRIORITIES –
1), which is the highest priority.
configMAX_PRIORITIES
Sets the maximum priority that can be assigned to a task. Tasks can be assigned a priority
from zero, which is the lowest priority, to (configMAX_PRIORITIES – 1), which is the highest
priority.
337
configMAX_TASK_NAME_LEN
Sets the maximum number of characters that can be used for the name of a task. The NULL
terminator is included in the count of characters.
configMAX_SYSCALL_INTERRUPT_PRIORITY
configMINIMAL_STACK_SIZE
Sets the size of the stack allocated to the Idle task. The value is specified in words, not bytes.
The kernel itself does not use configMINIMAL_STACK_SIZE for any other purpose, although
the constant is used extensively by the standard demo tasks.
A demo application is provided for every official FreeRTOS port. The value of
configMINIMAL_STACK_SIZE used in such a port specific demo application is the minimum
recommended stack size for any task created using that port.
configNUM_THREAD_LOCAL_STORAGE_POINTERS
Thread local storage (or TLS) allows the application writer to store values inside a task's
control block, making the value specific to (local to) the task itself, and allowing each task to
have its own unique value.
Each task has its own array of pointers that can be used as thread local storage. The number
of indexes in the array is set by configNUM_THREAD_LOCAL_STORAGE_POINTERS.
configQUEUE_REGISTRY_SIZE
Sets the maximum number of queues and semaphores that can be referenced from the queue
registry at any one time. Only queues and semaphores that need to be viewed in a kernel
aware debugging interface need to be registered.
The queue registry is only required when a kernel aware debugger is being used. At all other
times it has no purpose and can be omitted by setting configQUEUE_REGISTRY_SIZE to 0,
or by omitting the configQUEUE_REGISTRY_SIZE configuration constant definition
altogether.
338
configSUPPORT_STATIC_ALLOCATION
configTICK_RATE_HZ
configTIMER_QUEUE_LENGTH
Timer functionality is not provided by the core FreeRTOS code, but by a timer service (or
daemon) task. The FreeRTOS timer API sends commands to the timer service task on a
queue called the timer command queue. configTIMER_QUEUE_LENGTH sets the maximum
number of unprocessed commands that the timer command queue can hold at any one time.
Multiple timer API function calls being made before the scheduler has been started, and
therefore before the timer service task has been created.
Multiple (interrupt safe) timer API function calls being made from an interrupt service
routine (ISR), and therefore not allowing the timer service task to process the
commands.
Multiple timer API function calls being made from a task that has a priority above that of
the timer service task.
339
configTIMER_TASK_PRIORITY
Timer functionality is not provided by the core FreeRTOS code, but by a timer service (or
daemon) task. The FreeRTOS timer API sends commands to the timer service task on a
queue called the timer command queue. configTIMER_TASK_PRIORITY sets the priority of
the timer service task. Like all tasks, the timer service task can run at any priority between 0
and ( configMAX_PRIORITIES - 1 ).
This value needs to be chosen carefully to meet the requirements of the application. For
example, if the timer service task is made the highest priority task in the system, then
commands sent to the timer service task (when a timer API function is called), and expired
timers, will both get processed immediately. Conversely, if the timer service task is given a
low priority, then commands sent to the timer service task, and expired timers, will not be
processed until the timer service task is the highest priority task that is able to run. It is worth
noting however, that timer expiry times are calculated relative to when a command is sent, and
not relative to when a command is processed.
configTIMER_TASK_STACK_DEPTH
Timer functionality is not provided by the core FreeRTOS code, but by a timer service (or
daemon) task. The FreeRTOS timer API sends commands to the timer service task on a
queue called the timer command queue. configTIMER_TASK_STACK_DEPTH sets the size
of the stack (in words, not bytes) allocated to the timer service task.
Timer callback functions execute in the context of the timer service task. The stack
requirement of the timer service task therefore depends on the stack requirements of the timer
callback functions.
configTOTAL_HEAP_SIZE
The kernel allocates memory from the heap each time a task, queue or semaphore is created.
The official FreeRTOS download includes three sample memory allocation schemes for this
purpose. The schemes are implemented in the heap_1.c, heap_2.c, heap_3.c and heap_4.c
source files respectively. The schemes defined by heap_1.c, heap_2.c and heap_4.c allocate
memory from a statically allocated array, known as the FreeRTOS heap.
configTOTAL_HEAP_SIZE sets the size of this array. The size is specified in bytes.
340
The configTOTAL_HEAP_SIZE setting has no effect unless heap_1.c, heap_2.c or heap_4.c
are being used by the application.
configUSE_16_BIT_TICKS
The tick count is held in a variable of type TickType_t. When configUSE_16_BIT_TICKS is set
to 1, TickType_t is defined to be an unsigned 16-bit type. When configUSE_16_BIT_TICKS is
set to 0, TickType_t is defined to be an unsigned 32-bit type.
Using a 16-bit type can greatly improve efficiency on 8-bit and 16-bit microcontrollers, but at
the cost of limiting the maximum block time that can be specified.
configUSE_ALTERNATIVE_API
Two sets of API functions are provided to send to, and receive from, queues – the standard
API and the ‘alternative’ API. Only the standard API is documented in this manual. Use of the
alternative API is no longer recommended.
Note: Use of the alternative API is deprecated and therefore not recommended.
configUSE_APPLICATION_TASK_TAG
configUSE_CO_ROUTINES
Co-routines are light weight tasks that save RAM by sharing a stack, but have limited
functionality. Their use is omitted from this manual.
341
Setting configUSE_CO_ROUTINES to 1 will include all co-routine functionality and its
associated API functions in the build. Setting configUSE_CO_ROUTINES to 0 will exclude all
co-routine functionality and its associated API functions from the build.
configUSE_COUNTING_SEMAPHORES
configUSE_DAEMON_TASK_STARTUP_HOOK
Listing 241 The daemon task startup hook function name and prototype.
configUSE_IDLE_HOOK
The idle task hook function is a hook (or callback) function that, if defined and configured, will
be called by the Idle task on each iteration of its implementation.
If configUSE_IDLE_HOOK is set to 1 then the application must define an idle task hook
function. If configUSE_IDLE_HOOK is set to 0 then the idle task hook function will not be
called, even if one is defined.
Idle task hook functions must have the name and prototype shown in Listing 242.
Listing 242 The idle task hook function name and prototype.
342
configUSE_MALLOC_FAILED_HOOK
The kernel uses a call to pvPortMalloc() to allocate memory from the heap each time a task,
queue or semaphore is created. The official FreeRTOS download includes three sample
memory allocation schemes for this purpose. The schemes are implemented in the heap_1.c,
heap_2.c heap_3.c and heap_4.c source files respectively.
configUSE_MALLOC_FAILED_HOOK is only relevant when one of these three sample
schemes is being used.
The malloc() failed hook function is a hook (or callback) function that, if defined and
configured, will be called if pvPortMalloc() ever returns NULL. NULL will be returned only if
there is insufficient FreeRTOS heap memory remaining for the requested allocation to
succeed.
Malloc() failed hook functions must have the name and prototype shown in Listing 243.
Listing 243 The malloc() failed hook function name and prototype.
configUSE_MUTEXES
Setting configUSE_MUTEXES to 1 will include the mutex functionality and its associated API
in the build. Setting configUSE_MUTEXES to 0 will exclude the mutex functionality and its
associated API from the build.
configUSE_NEWLIB_REENTRANT
Note Newlib support has been included by popular demand, but is not used by the FreeRTOS
maintainers themselves. FreeRTOS is not responsible for resulting newlib operation. User
must be familiar with newlib and must provide system-wide implementations of the necessary
343
stubs. Be warned that (at the time of writing) the current newlib design implements a system-
wide malloc() that must be provided with locks.
configUSE_PORT_OPTIMISED_TASK_SELECTION
Some FreeRTOS ports have two methods of selecting the next task to execute – a generic
method, and a method that is specific to that port.
configUSE_PREEMPTION
When the pre-emptive scheduler is used the kernel will execute during each tick interrupt,
which can result in a context switch occurring in the tick interrupt.
344
When the co-operative scheduler is used a context switch will only occur when either:
2. A task explicitly calls an API function that results in it entering the Blocked state.
configUSE_QUEUE_SETS
Setting configUSE_QUEUE_SETS to 1 will include queue set functionality (the ability to block
on multiple queues at the same time) and its associated API in the build. Setting
configUSE_QUEUE_SETS to 0 will exclude queue set functionality and its associated API
from the build.
configUSE_RECURSIVE_MUTEXES
configUSE_STATS_FORMATTING_FUNCTIONS
functions in the build. Setting either to 0 will omit vTaskList() and vTaskGetRunTimeStates()
from the build.
configUSE_TASK_NOTIFICATIONS
Each task consumes 8 additional bytes of RAM when direct to task notifications are included in
the build.
345
configUSE_TICK_HOOK
The tick hook function is a hook (or callback) function that, if defined and configured, will be
called during each tick interrupt.
If configUSE_TICK_HOOK is set to 1 then the application must define a tick hook function. If
configUSE_TICK_HOOK is set to 0 then the tick hook function will not be called, even if one is
defined.
Tick hook functions must have the name and prototype shown in Listing 244.
configUSE_TICKLESS_IDLE
Set configUSE_TICKLESS_IDLE to 1 to use the low power tickless mode, or 0 to keep the tick
interrupt running at all times. Low power tickless implementations are not provided for all
FreeRTOS ports.
configUSE_TIMERS
Setting configUSE_TIMERS to 1 will include software timer functionality and its associated API
in the build. Setting configUSE_TIMERS to 0 will exclude software timer functionality and its
associated API from the build.
configUSE_TIME_SLICING
346
task that is in the Ready state, but will not switch between tasks of equal priority just because
a tick interrupt executed.
configUSE_TRACE_FACILITY
347
Chapter 8
348
8.1 xStreamBufferBytesAvailable()
#include “FreeRTOS.h”
#include “stream_buffer.h”
Summary
Queries a stream buffer to see how much data it contains, which is equal to the number of
bytes that can be read from the stream buffer before the stream buffer would be empty.
Parameters
Return Values
The number of bytes that can be read from the stream buffer before the stream buffer would
be emtpy.
349
8.2 xStreamBufferCreate()
#include “FreeRTOS.h”
#include “stream_buffer.h”
Summary
Parameters
xBufferSizeBytes The total number of bytes the stream buffer will be able to hold at any
one time.
xTriggerLevelBytes The number of bytes that must be in the stream buffer before a task that
is blocked on the stream buffer to wait for data is moved out of the
blocked state. For example, if a task is blocked on a read of an empty
stream buffer that has a trigger level of 1 then the task will be unblocked
when a single byte is written to the buffer or the task's block time expires.
As another example, if a task is blocked on a read of an empty stream
buffer that has a trigger level of 10 then the task will not be unblocked
until the stream buffer contains at least 10 bytes or the task's block time
expires. If a reading task's block time expires before the trigger level is
reached then the task will still receive however many bytes are actually
available. Setting a trigger level of 0 will result in a trigger level of 1 being
used. It is not valid to specify a trigger level that is greater than the buffer
350
size.
Return Values
If NULL is returned, then the stream buffer cannot be created because there is insufficient
heap memory available for FreeRTOS to allocate the stream buffer data structures and
storage area. A non-NULL value being returned indicates that the stream buffer has been
created successfully - the returned value should be stored as the handle to the created stream
buffer.
Example
/* Create a stream buffer that can hold 100 bytes. The memory used to hold
both the stream buffer structure and the data in the stream buffer is
allocated dynamically. */
xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
351
8.3 xStreamBufferCreateStatic()
#include “FreeRTOS.h”
#include “stream_buffer.h”
StreamBufferHandle_t xStreamBufferCreateStatic(
size_t xBufferSizeBytes,
size_t xTriggerLevelBytes,
uint8_t *pucStreamBufferStorageArea,
StaticStreamBuffer_t *pxStaticStreamBuffer );
Summary
Creates a new stream buffer using statically allocated memory. See xStreamBufferCreate() for
a version that uses dynamically allocated memory.
Parameters
xTriggerLevelBytes The number of bytes that must be in the stream buffer before
a task that is blocked on the stream buffer to wait for data is
moved out of the blocked state. For example, if a task is
blocked on a read of an empty stream buffer that has a trigger
level of 1 then the task will be unblocked when a single byte
is written to the buffer or the task's block time expires. As
another example, if a task is blocked on a read of an empty
stream buffer that has a trigger level of 10 then the task will
not be unblocked until the stream buffer contains at least 10
bytes or the task's block time expires. If a reading task's block
time expires before the trigger level is reached then the task
will still receive however many bytes are actually available.
352
Setting a trigger level of 0 will result in a trigger level of 1
being used. It is not valid to specify a trigger level that is
greater than the buffer size.
Return Values
If the stream buffer is created successfully then a handle to the created stream buffer is
returned. If either pucStreamBufferStorageArea or pxStaticstreamBuffer are NULL then NULL
is returned.
Example
/* Used to dimension the array used to hold the streams. The available space
will actually be one less than this, so 999. */
#define STORAGE_SIZE_BYTES 1000
/* Defines the memory that will actually hold the streams within the stream
buffer. */
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
353
8.4 vStreamBufferDelete()
#include “FreeRTOS.h”
#include “stream_buffer.h”
Summary
Deletes a stream buffer that was previously created using a call to xStreamBufferCreate() or
xStreamBufferCreateStatic(). If the stream buffer was created using dynamic memory (that is,
by xStreamBufferCreate()), then the allocated memory is freed.
A stream buffer handle must not be used after the stream buffer has been deleted.
Parameters
354
8.5 xStreamBufferIsEmpty()
#include “FreeRTOS.h”
#include “stream_buffer.h”
Summary
Queries a stream buffer to see if it is empty. A stream buffer is empty if it does not contain any
data.
Parameters
Return Values
If the stream buffer is empty then pdTRUE is returned. Otherwise pdFALSE is returned.
355
8.6 xStreamBufferIsFull()
#include “FreeRTOS.h”
#include “stream_buffer.h”
Summary
Queries a stream buffer to see if it is full. A stream buffer is full if it does not have any free
space, and therefore cannot accept any more data.
Parameters
Return Values
If the stream buffer is full then pdTRUE is returned. Otherwise pdFALSE is returned.
356
8.7 xStreamBufferReceive()
#include “FreeRTOS.h”
#include “stream_buffer.h”
Summary
Parameters
xStreamBuffer The handle of the stream buffer from which bytes are to be received.
pvRxData A pointer to the buffer into which the received bytes will be copied.
xBufferLengthBytes The length of the buffer pointed to by the pvRxData parameter. This sets
the maximum number of bytes to receive in one call.
xStreamBufferReceive will return as many bytes as possible up to a
maximum set by xBufferLengthBytes.
xTicksToWait The maximum amount of time the task should remain in the Blocked
state to wait for data to become available if the stream buffer is empty.
xStreamBufferReceive() will return immediately if xTicksToWait is zero.
The block time is specified in tick periods, so the absolute time it
represents is dependent on the tick frequency. The macro
pdMS_TO_TICKS() can be used to convert a time specified in
milliseconds into a time specified in ticks. Setting xTicksToWait to
portMAX_DELAY will cause the task to wait indefinitely (without timing
out), provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. A task does not use any CPU time when it is in the
Blocked state.
Return Values
357
The number of bytes actually read from the stream buffer, which will be less than
xBufferLengthBytes if the call to xStreamBufferReceive() timed out before xBufferLengthBytes
were available.
Notes
Uniquely among FreeRTOS objects, the stream buffer implementation (so also the message
buffer implementation, as message buffers are built on top of stream buffers) assumes there is
only one task or interrupt that will write to the buffer (the writer), and only one task or interrupt
that will read from the buffer (the reader). It is safe for the writer and reader to be different
tasks or interrupts, but, unlike other FreeRTOS objects, it is not safe to have multiple different
writers or multiple different readers. If there are to be multiple different writers then the
application writer must place each call to a writing API function (such as xStreamBufferSend())
inside a critical section and use a send block time of 0. Likewise, if there are to be multiple
different readers then the application writer must place each call to a reading API function
(such as xStreamBufferRead()) inside a critical section and use a receive block time of 0.
358
Example
359
8.8 xStreamBufferReceiveFromISR()
#include “FreeRTOS.h”
#include “stream_buffer.h”
Summary
An interrupt safe version of the API function that receives bytes from a stream buffer.
Parameters
xStreamBuffer The handle of the stream buffer from which bytes are to be
received.
pvRxData A pointer to the buffer into which the received bytes will be
copied.
360
then normally a context switch should be performed before the
interrupt is exited. That will ensure the interrupt returns directly
to the highest priority Ready state task.
*pxHigherPriorityTaskWoken should be set to pdFALSE before
it is passed into the function. See the code example below for
an example.
Return Values
Notes
Uniquely among FreeRTOS objects, the stream buffer implementation (so also the message
buffer implementation, as message buffers are built on top of stream buffers) assumes there is
only one task or interrupt that will write to the buffer (the writer), and only one task or interrupt
that will read from the buffer (the reader). It is safe for the writer and reader to be different
tasks or interrupts, but, unlike other FreeRTOS objects, it is not safe to have multiple different
writers or multiple different readers. If there are to be multiple different writers then the
application writer must place each call to a writing API function (such as xStreamBufferSend())
inside a critical section and use a send block time of 0. Likewise, if there are to be multiple
different readers then the application writer must place each call to a reading API function
(such as xStreamBufferRead()) inside a critical section and use a receive block time of 0.
361
Example
362
8.9 xStreamBufferReset()
#include “FreeRTOS.h”
#include “stream_buffer.h”
Summary
Resets a stream buffer to its initial, empty, state. Any data that was in the stream buffer is
discarded. A stream buffer can only be reset if there are no tasks blocked waiting to either
send to or receive from the stream buffer.
Parameters
Return Values
If the stream buffer is reset then pdPASS is returned. If there was a task blocked waiting to
send to or read from the stream buffer then the stream buffer will not be reset and pdFAIL is
returned.
363
8.10 xStreamBufferSend()
#include “FreeRTOS.h”
#include “stream_buffer.h”
Summary
Sends bytes to a stream buffer. The bytes are copied into the stream buffer.
Parameters
xStreamBuffer The handle of the stream buffer to which a stream is being sent.
pvTxData A pointer to the buffer that holds the bytes to be copied into the stream
buffer
xDataLengthBytes The maximum number of bytes to copy from pvTxData into the stream
buffer.
xTicksToWait The maximum amount of time the task should remain in the Blocked state
to wait for enough space to become available in the stream buffer, should
the stream buffer contain too little space to hold the another
xDataLengthBytes bytes. The block time is specified in tick periods, so
the absolute time it represents is dependent on the tick frequency. The
macro pdMS_TO_TICKS() can be used to convert a time specified in
milliseconds into a time specified in ticks. Setting xTicksToWait to
portMAX_DELAY will cause the task to wait indefinitely (without timing
out), provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.
If a task times out before it can write all xDataLengthBytes into the buffer
it will still write as many bytes as possible. A task does not use any CPU
time when it is in the blocked state.
Return Values
364
The number of bytes written to the stream buffer. If a task times out before it can write all
xDataLengthBytes into the buffer it will still write as many bytes as possible.
Notes
Uniquely among FreeRTOS objects, the stream buffer implementation (so also the message
buffer implementation, as message buffers are built on top of stream buffers) assumes there is
only one task or interrupt that will write to the buffer (the writer), and only one task or interrupt
that will read from the buffer (the reader). It is safe for the writer and reader to be different
tasks or interrupts, but, unlike other FreeRTOS objects, it is not safe to have multiple different
writers or multiple different readers. If there are to be multiple different writers then the
application writer must place each call to a writing API function (such as xStreamBufferSend())
inside a critical section and use a send block time of 0. Likewise, if there are to be multiple
different readers then the application writer must place each call to a reading API function
(such as xStreamBufferRead()) inside a critical section and use a receive block time of 0.
365
Example
/* Send the string to the stream buffer. Return immediately if there is not
enough space in the buffer. */
xBytesSent = xStreamBufferSend( xStreamBuffer,
( void * ) pcStringToSend,
strlen( pcStringToSend ), 0 );
366
8.11 xStreamBufferSendFromISR()
#include “FreeRTOS.h”
#include “stream_buffer.h”
Summary
Interrupt safe version of the API function that sends a stream of bytes to the stream buffer.
Parameters
xStreamBuffer The handle of the stream buffer to which a stream is being sent.
pvTxData A pointer to the buffer that holds the bytes to be copied into the
stream buffer.
xDataLengthBytes The maximum number of bytes to copy from pvTxData into the
stream buffer.
367
it is passed into the function. See the example code below for
an example.
Return Values
The number of bytes written to the stream buffer. If a task times out before it can write all
xDataLengthBytes into the buffer it will still write as many bytes as possible.
Notes
Uniquely among FreeRTOS objects, the stream buffer implementation (so also the message
buffer implementation, as message buffers are built on top of stream buffers) assumes there is
only one task or interrupt that will write to the buffer (the writer), and only one task or interrupt
that will read from the buffer (the reader). It is safe for the writer and reader to be different
tasks or interrupts, but, unlike other FreeRTOS objects, it is not safe to have multiple different
writers or multiple different readers. If there are to be multiple different writers then the
application writer must place each call to a writing API function (such as xStreamBufferSend())
inside a critical section and use a send block time of 0. Likewise, if there are to be multiple
different readers then the application writer must place each call to a reading API function
(such as xStreamBufferRead()) inside a critical section and use a receive block time of 0.
368
Example
369
8.12 xStreamBufferSetTriggerLevel()
#include “FreeRTOS.h”
#include “stream_buffer.h”
Summary
A stream buffer's trigger level is the number of bytes that must be in the stream buffer before a
task that is blocked on the stream buffer to wait for data is moved out of the blocked state. For
example, if a task is blocked on a read of an empty stream buffer that has a trigger level of 1
then the task will be unblocked when a single byte is written to the buffer or the task's block
time expires. As another example, if a task is blocked on a read of an empty stream buffer that
has a trigger level of 10 then the task will not be unblocked until the stream buffer contains at
least 10 bytes or the task's block time expires. If a reading task's block time expires before the
trigger level is reached then the task will still receive however many bytes are actually
available. Setting a trigger level of 0 will result in a trigger level of 1 being used. It is not valid
to specify a trigger level that is greater than the buffer size.
A trigger level is set when the stream buffer is created, and can be modified using
xStreamBufferSetTriggerLevel().
Parameters
Return Values
If xTriggerLevel was less than or equal to the steam buffer's length then the trigger level will be
updated and pdTRUE is returned. Otherwise pdFALSE is returned.
370
8.13 xStreamBufferSpacesAvailable()
#include “FreeRTOS.h”
#include “stream_buffer.h”
Summary
Queries a stream buffer to see how much free space it contains, which is equal to the amount
of data that can be sent to the stream buffer before it is full.
Parameters
Return Values
The number of bytes that can be written to the stream buffer before the stream buffer would be
full.
371
Chapter 9
372
9.1 xMessageBufferCreate()
#include “FreeRTOS.h”
#include “message_buffer.h”
Summary
Parameters
xBufferSizeBytes The total number of bytes (not messages) the message buffer will be able
to hold at any one time. When a message is written to the message buffer
an additional sizeof( size_t ) bytes are also written to store the message's
length. sizeof( size_t ) is typically 4 bytes on a 32-bit architecture, so on
most 32-bit architectures a 10 byte message will take up 14 bytes of
message buffer space.
Return Values
If NULL is returned, then the message buffer cannot be created because there is insufficient
heap memory available for FreeRTOS to allocate the message buffer data structures and
storage area. A non-NULL value being returned indicates that the message buffer has been
created successfully - the returned value should be stored as the handle to the created
message buffer.
373
Example
/* Create a message buffer that can hold 100 bytes. The memory used to hold
both the message buffer structure and the data in the message buffer is
allocated dynamically. */
xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
374
9.2 xMessageBufferCreateStatic()
#include “FreeRTOS.h”
#include “message_buffer.h”
MessageBufferHandle_t xMessageBufferCreateStatic(
size_t xBufferSizeBytes,
uint8_t *pucMessageBufferStorageArea,
StaticMessageBuffer_t *pxStaticMessageBuffer );
Summary
Parameters
375
+ 1 big. This is the array to which messages are copied
when they are written to the message buffer.
Return Values
If the message buffer is created successfully then a handle to the created message buffer is
returned. If either pucMessageBufferStorageArea or pxStaticMessageBuffer are NULL then
NULL is returned.
Example
/* Used to dimension the array used to hold the messages. The available space
will actually be one less than this, so 999. */
#define STORAGE_SIZE_BYTES 1000
/* Defines the memory that will actually hold the messages within the message
buffer. Should be one more than the value passed in the xBufferSizeBytes
parameter. */
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
376
9.3 vMessageBufferDelete()
#include “FreeRTOS.h”
#include “message_buffer.h”
Summary
Deletes a message buffer that was previously created using a call to xMessageBufferCreate()
or xMessageBufferCreateStatic(). If the message buffer was created using dynamic memory
(that is, by xMessageBufferCreate()), then the allocated memory is freed.
A message buffer handle must not be used after the message buffer has been deleted.
Parameters
377
9.4 xMessageBufferIsEmpty()
#include “FreeRTOS.h”
#include “message_buffer.h”
Summary
Queries a message buffer to see if it is empty. A message buffer is empty if it does not contain
any messages.
Parameters
Return Values
If the message buffer is empty then pdTRUE is returned. Otherwise pdFALSE is returned.
378
9.5 xMessageBufferIsFull()
#include “FreeRTOS.h”
#include “message_buffer.h”
Summary
Queries a message buffer to see if it is full. A message buffer is full if it cannot accept any
more messages, of any size, until space is made available by a message being removed from
the message buffer.
Parameters
Return Values
If the message buffer is full then pdTRUE is returned. Otherwise pdFALSE is returned.
379
9.6 xMessageBufferReceive()
#include “FreeRTOS.h”
#include “message_buffer.h”
Summary
Receives a discrete message from an RTOS message buffer. Messages can be of variable
length and are copied out of the buffer.
Parameters
xMessageBuffer The handle of the message buffer from which a message is being
received.
pvRxData A pointer to the buffer into which the received message is to be copied.
xBufferLengthBytes The length of the buffer pointed to by the pvRxData parameter. This sets
the maximum length of the message that can be received. If
xBufferLengthBytes is too small to hold the next message then the
message will be left in the message buffer and 0 will be returned.
xTicksToWait The maximum amount of time the task should remain in the
Blocked state to wait for a message, should the message buffer be
empty when xMessageBufferReceive() was called.
xMessageBufferReceive() will return immediately if xTicksToWait is zero
and the message buffer is empty. The block time is specified in tick
periods, so the absolute time it represents is dependent on the tick
frequency. The macro pdMS_TO_TICKS() can be used to convert a time
specified in milliseconds into a time specified in ticks. Setting
xTicksToWait to portMAX_DELAY will cause the task to wait indefinitely
(without timing out), provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. Tasks do not use any CPU time when they are in
380
the Blocked state.
Return Values
The length, in bytes, of the message read from the message buffer, if any. If
xMessageBufferReceive() times out before a message became available then zero is
returned. If the length of the message is greater than xBufferLengthBytes then the message
will be left in the message buffer and zero is returned.
Notes
Uniquely among FreeRTOS objects, the stream buffer implementation (so also the message
buffer implementation, as message buffers are built on top of stream buffers) assumes there is
only one task or interrupt that will write to the buffer (the writer), and only one task or interrupt
that will read from the buffer (the reader). It is safe for the writer and reader to be different
tasks or interrupts, but, unlike other FreeRTOS objects, it is not safe to have multiple different
writers or multiple different readers. If there are to be multiple different writers then the
application writer must place each call to a writing API function (such as
xMessageBufferSend()) inside a critical section and must use a send block time of 0. Likewise,
if there are to be multiple different readers then the application writer must place each call to a
reading API function (such as xMessageBufferRead()) inside a critical section and must use a
receive block time of 0.
381
Example
/* Receive the next message from the message buffer. Wait in the Blocked
state (so not using any CPU processing time) for a maximum of 100ms for
a message to become available. */
xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
( void * ) ucRxData,
sizeof( ucRxData ),
xBlockTime );
382
9.7 xMessageBufferReceiveFromISR()
#include “FreeRTOS.h”
#include “message_buffer.h”
Summary
An interrupt safe version of the API function that receives a discrete message from a message
buffer. Messages can be of variable length and are copied out of the buffer.
Parameters
pvRxData A pointer to the buffer into which the received message will be
copied.
383
*pxHigherPriorityTaskWoken to pdTRUE. If
xMessageBufferReceiveFromISR() sets this value to pdTRUE,
then normally a context switch should be performed before the
interrupt is exited. That will ensure the interrupt returns directly
to the highest priority Ready state task.
*pxHigherPriorityTaskWoken should be set to pdFALSE before
it is passed into the function. See the code example below for
an example.
Return Values
The length, in bytes, of the message read from the message buffer, if any.
Notes
Uniquely among FreeRTOS objects, the stream buffer implementation (so also the message
buffer implementation, as message buffers are built on top of stream buffers) assumes there is
only one task or interrupt that will write to the buffer (the writer), and only one task or interrupt
that will read from the buffer (the reader). It is safe for the writer and reader to be different
tasks or interrupts, but, unlike other FreeRTOS objects, it is not safe to have multiple different
writers or multiple different readers. If there are to be multiple different writers then the
application writer must place each call to a writing API function (such as
xMessageBufferSend()) inside a critical section and must use a send block time of 0. Likewise,
if there are to be multiple different readers then the application writer must place each call to a
reading API function (such as xMessageBufferRead()) inside a critical section and must use a
receive block time of 0.
384
Example
385
9.8 xMessageBufferReset()
#include “FreeRTOS.h”
#include “message_buffer.h”
Summary
Resets a message buffer to its initial, empty, state. Any data that was in the message buffer is
discarded. A message buffer can only be reset if there are no tasks blocked waiting to either
send to or receive from the message buffer.
Parameters
Return Values
If the message buffer is reset then pdPASS is returned. If there was a task blocked waiting to
send to or read from the message buffer then the message buffer will not be reset and pdFAIL
is returned.
386
9.9 xMessageBufferSend()
#include “FreeRTOS.h”
#include “message_buffer.h”
Summary
Sends a discrete message to a message buffer. The message can be any length that fits
within the buffer's free space, and is copied into the buffer.
Parameters
xMessageBuffer The handle of the message buffer to which a message is being sent.
pvTxData A pointer to the message that is to be copied into the message buffer.
xDataLengthBytes The length of the message. That is, the number of bytes to copy from
pvTxData into the message buffer. When a message is written to the
message buffer an additional sizeof( size_t ) bytes are also written to
store the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit
architecture, so on most 32-bit architecture setting xDataLengthBytes to
20 will reduce the free space in the message buffer by 24 bytes (20 bytes
of message data and 4 bytes to hold the message length).
xTicksToWait xTicksToWait The maximum amount of time the calling task should
remain in the Blocked state to wait for enough space to become available
in the message buffer, should the message buffer have insufficient space
when xMessageBufferSend() is called. The calling task will never block if
xTicksToWait is zero. The block time is specified in tick periods, so the
absolute time it represents is dependent on the tick frequency. The macro
pdMS_TO_TICKS() can be used to convert a time specified in
milliseconds into a time specified in ticks. Setting xTicksToWait to
387
portMAX_DELAY will cause the task to wait indefinitely (without timing
out), provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.
Tasks do not use any CPU time when they are in the Blocked state.
Return Values
The number of bytes written to the message buffer. If the call to xMessageBufferSend() times
out before there was enough space to write the message into the message buffer then zero is
returned. If the call did not time out then xDataLengthBytes is returned.
Notes
Uniquely among FreeRTOS objects, the stream buffer implementation (so also the message
buffer implementation, as message buffers are built on top of stream buffers) assumes there is
only one task or interrupt that will write to the buffer (the writer), and only one task or interrupt
that will read from the buffer (the reader). It is safe for the writer and reader to be different
tasks or interrupts, but, unlike other FreeRTOS objects, it is not safe to have multiple different
writers or multiple different readers. If there are to be multiple different writers then the
application writer must place each call to a writing API function (such as
xMessageBufferSend()) inside a critical section and use a send block time of 0. Likewise, if
there are to be multiple different readers then the application writer must place each call to a
reading API function (such as xMessageBufferRead()) inside a critical section and use a
receive block time of 0.
388
Example
389
9.10 xMessageBufferSendFromISR()
#include “FreeRTOS.h”
#include “message_buffer.h”
Summary
Interrupt safe version of the API function that sends a discrete message to the message
buffer. The message can be any length that fits within the buffer's free space, and is copied
into the buffer.
Parameters
xDataLengthBytes The length of the message. That is, the number of bytes to copy
from pvTxData into the message buffer. When a message is
written to the message buffer an additional sizeof( size_t ) bytes
are also written to store the message's length. sizeof( size_t ) is
typically 4 bytes on a 32-bit architecture, so on most 32-bit
architecture setting xDataLengthBytes to 20 will reduce the free
space in the message buffer by 24 bytes (20 bytes of message
data and 4 bytes to hold the message length).
390
Blocked state, and the unblocked task has a priority higher than
the currently executing task (the task that was interrupted), then,
internally, xMessageBufferSendFromISR() will set
*pxHigherPriorityTaskWoken to pdTRUE. If
xMessageBufferSendFromISR() sets this value to pdTRUE,
then normally a context switch should be performed before the
interrupt is exited. This will ensure that the interrupt returns
directly to the highest priority Ready state task.
*pxHigherPriorityTaskWoken should be set to pdFALSE before
it is passed into the function. See the code example below for
an example.
Return Values
The number of bytes actually written to the message buffer. If the message buffer didn't have
enough free space for the message to be stored then 0 is returned, otherwise
xDataLengthBytes is returned.
Notes
Uniquely among FreeRTOS objects, the stream buffer implementation (so also the message
buffer implementation, as message buffers are built on top of stream buffers) assumes there is
only one task or interrupt that will write to the buffer (the writer), and only one task or interrupt
that will read from the buffer (the reader). It is safe for the writer and reader to be different
tasks or interrupts, but, unlike other FreeRTOS objects, it is not safe to have multiple different
writers or multiple different readers. If there are to be multiple different writers then the
application writer must place each call to a writing API function (such as
xMessageBufferSend()) inside a critical section and use a send block time of 0. Likewise, if
there are to be multiple different readers then the application writer must place each call to a
reading API function (such as xMessageBufferRead()) inside a critical section and use a
receive block time of 0.
391
Message buffer functionality is enabled by including the FreeRTOS/source/stream_buffer.c
source file in the build (as message buffers use stream buffers).
Example
392
9.11 xMessageBufferSpacesAvailable()
#include “FreeRTOS.h”
#include “message_buffer.h”
Summary
Queries a message buffer to see how much free space it contains, which is equal to the
amount of data that can be sent to the message buffer before it is full. The returned value is 4
bytes larger than the maximum message size that can be sent to the message buffer.
Parameters
Return Values
The number of bytes that can be written to the message buffer before the message buffer
would be full. When a message is written to the message buffer an additional sizeof( size_t )
bytes are also written to store the message's length. sizeof( size_t ) is typically 4 bytes on a
32-bit architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size of the
largest message that can be written to the message buffer is 6 bytes.
393
APPENDIX 1: Data Types and Coding Style Guide
Data Types
Each port of FreeRTOS has a unique portmacro.h header file that contains (amongst other
things) definitions for two special data types, TickType_t and BaseType_t. These data types
are described in Table 3.
Macro or typedef
Actual type
used
TickType_t This is used to store the tick count value, and by variables that specify
block times.
Using a 16-bit type can greatly improve efficiency on 8-bit and 16-bit
architectures, but severely limits the maximum block period that can be
specified. There is no reason to use a 16-bit type on a 32-bit
architecture.
BaseType_t This is always defined to be the most efficient data type for the
architecture. Typically, this is a 32-bit type on a 32-bit architecture, a
16-bit type on a 16-bit architecture, and an 8-bit type on an 8-bit
architecture.
BaseType_t is generally used for variables that can take only a very
limited range of values, and for Booleans.
Standard data types other than ‘char’ are not used (see below), instead type names defined
within the compiler’s stdint.h header file are used. ‘char’ types are only permitted to point to
ASCII strings or reference single ASCII characters.
394
Variable Names
Variables are prefixed with their type: ‘c’ for char, ‘s’ for short, ‘l’ for long, and ‘x’ for
BaseType_t and any other types (structures, task handles, queue handles, etc.).
If a variable is unsigned, it is also prefixed with a ‘u’. If a variable is a pointer, it is also prefixed
with a ‘p’. Therefore, a variable of type unsigned char will be prefixed with ‘uc’, and a variable
of type pointer to char will be prefixed with ‘pc’.
Function Names
Functions are prefixed with both the type they return and the file they are defined in. For
example:
Formatting
Macro Names
Most macros are written in upper case and prefixed with lower case letters that indicate where
the macro is defined. Table 4 provides a list of prefixes.
395
Table 4. Macro prefixes
Note that the semaphore API is written almost entirely as a set of macros, but follows the
function naming convention, rather than the macro naming convention.
The macros defined in Table 5 are used throughout the FreeRTOS source code.
Macro Value
pdTRUE 1
pdFALSE 0
pdPASS 1
pdFAIL 0
The FreeRTOS source code can be compiled with many different compilers, all of which differ
in how and when they generate warnings. In particular, different compilers want casting to be
used in different ways. As a result, the FreeRTOS source code contains more type casting
than would normally be warranted.
396
INDEX
A F
API Usage Restrictions, 19 Formatting, 395
FreeRTOSConfig.h, 324
Function Names, 395
C
configASSERT, 329
configCHECK_FOR_STACK_OVERFLOW, 330
H
configCPU_CLOCK_HZ, 332 high water mark, 79
configGENERATE_RUN_TIME_STATS, 332 highest priority, 35, 40, 131
configIDLE_SHOULD_YIELD, 333
configINCLUDE_APPLICATION_DEFINED_PRIVILE
GED_FUNCTIONS, 335 I
configKERNEL_INTERRUPT_PRIORITY, 335 INCLUDE_ xTimerPendFunctionCall, 328
configMAX_CO_ROUTINE_PRIORITIES, 337 INCLUDE_eTaskGetState, 327
configMAX_PRIORITIES, 35, 40, 131, 337 INCLUDE_uxTaskGetStackHighWaterMark, 327
configMAX_SYSCALL_INTERRUPT_PRIORITY, 335, INCLUDE_uxTaskPriorityGet, 327
338 INCLUDE_vTaskDelay, 326
configMAX_TASK_NAME_LEN, 338 INCLUDE_vTaskDelayUntil, 326
configMINIMAL_STACK_DEPTH, 35 INCLUDE_vTaskDelete, 326
configMINIMAL_STACK_SIZE, 338 INCLUDE_vTaskPrioritySet, 327
configNUM_THREAD_LOCAL_STORAGE_POINTER INCLUDE_vTaskSuspend, 327
S, 338 INCLUDE_xEventGroupSetBitFromISR, 325
configQUEUE_REGISTRY_SIZE, 338 INCLUDE_xSemaphoreGetMutexHolder, 325
configTICK_RATE_HZ, 339 INCLUDE_xTaskGetCurrentTaskHandle, 326
configTIMER_QUEUE_LENGTH, 339 INCLUDE_xTaskGetIdleTaskHandle, 326
configTIMER_TASK_PRIORITY, 340 INCLUDE_xTaskGetSchedulerState, 326
configTIMER_TASK_STACK_DEPTH, 340 INCLUDE_xTaskResumeFromISR, 327
configTOTAL_HEAP_SIZE, 340
configUSE_16_BIT_TICKS, 341
configUSE_ALTERNATIVE_API, 341 L
configUSE_APPLICATION_TASK_TAG, 341
configUSE_CO_ROUTINES, 341 lowest priority, 35, 40, 131
configUSE_COUNTING_SEMAPHORES, 342
configUSE_IDLE_HOOK, 342 M
configUSE_MALLOC_FAILED_HOOK, 343
configUSE_MUTEXES, 343 Macro Names, 395
configUSE_NEWLIB_REENTRANT, 343
configUSE_PORT_OPTIMISED_TASK_SELECTION,
344
P
configUSE_PREEMPTION, 344 pcTaskGetName(), 91, 172
configUSE_QUEUE_SETS, 345 pcTimerGetName(), 271
configUSE_RECURSIVE_MUTEXES, 345 portBASE_TYPE, 394
configUSE_STATS_FORMATTING_FUNCTIONS, 345 portCONFIGURE_TIMER_FOR_RUN_TIME_STATS,
configUSE_TICK_HOOK, 345, 346 75, 333
configUSE_TICKLESS_IDLE, 346 portGET_RUN_TIME_COUNTER_VALUE, 76, 333
configUSE_TIME_SLICING, 346 portMAX_DELAY, 182, 186, 200
configUSE_TIMERS, 346 portSWITCH_TO_USER_MODE(), 23
configUSE_TRACE_FACILITY, 347 portTickType, 394
priority, 35, 40
pvTaskGetTheadLocalStoragePointer(), 89
D pvTimerGetTimerID(), 274
Data Types, 394
T
E tabs, 395
eTaskGetState(), 81 task handle, 36, 43
taskDISABLE_INTERRUPTS(), 55
taskENABLE_INTERRUPTS(), 57
397
taskENTER_CRITICAL(), 58 xMessageBufferSend(), 387
taskENTER_CRITICAL_FROM_ISR(), 61, 65 xMessageBufferSendFromISR(), 390
taskEXIT_CRITICAL(), 63 xMessageBufferSpacesAvailable(), 393
taskYIELD(), 155 xQueueAddToSet(), 160
Type Casting, 396 xQueueCreate(), 162
xQueueCreateSet(), 164
xQueueCreateStatic(), 168
U xQueueIsQueueEmptyFromISR(), 173
ulTaskNotifyTake(), 123 xQueueIsQueueFullFromISR(), 174
uxQueueMessagesWaiting(), 175 xQueueOverwrite(), 178
uxQueueMessagesWaitingFromISR(), 176 xQueueOverwriteFromISR(), 180
uxQueueSpacesAvailable(), 206 xQueuePeek(), 182
uxSemaphoreGetCount(), 234 xQueuePeekFromISR(), 185
uxTaskGetNumberOfTasks(), 73 xQueueReceive(), 186
uxTaskGetStackHighWaterMark (), 79 xQueueReceiveFromISR(), 189, 247
uxTaskGetSystemState(), 83, 87 xQueueRemoveFromSet(), 192
uxTaskPriorityGet(), 129 xQueueReset(), 194
xQueueSelectFromSet(), 195
xQueueSelectFromSetFromISR(), 197
V xQueueSend(), 199
xQueueSendFromISR(), 202
Variable Names, 395 xQueueSendToBack(), 199
vEventGroupDelete(), 308 xQueueSendToBackFromISR(), 202
vMessageBufferDelete(), 377 xQueueSendToFront(), 199
vQueueAddToRegistry(), 158 xQueueSendToFrontFromISR(), 202
vQueueDelete(), 170 xSemaphoreCreateBinary(), 212
vSemaphoreCreateBinary(), 209 xSemaphoreCreateBinaryStatic(), 215
vSemaphoreDelete(), 233 xSemaphoreCreateCounting(), 218
vStreamBufferDelete(), 354 xSemaphoreCreateCountingStatic(), 221
vTaskDelay(), 48 xSemaphoreCreateMutex(), 224
vTaskDelayUntil(), 50 xSemaphoreCreateMutexStatic(), 226
vTaskDelete(), 53 xSemaphoreCreateRecursiveMutex(), 228
vTaskGetRunTimeStats(), 74 xSemaphoreCreateRecursiveMutexStatic(), 231
vTaskList(), 96 xSemaphoreGetMutexHolder(), 235
vTaskNotifyGiveFromISR(), 118 xSemaphoreGive(), 236
vTaskPrioritySet(), 131 xSemaphoreGiveFromISR(), 238
vTaskResume(), 133 xSemaphoreGiveRecursive(), 241
vTaskSetApplicationTaskTag(), 141 xSemaphoreTake(), 244
vTaskSetThreadLocalStoragePointer(), 143 xSemaphoreTakeRecursive(), 249
vTaskSetTimeOutState(), 145 xStreamBufferBytesAvailable(), 349
vTaskStartScheduler(), 147 xStreamBufferCreate(), 350
vTaskStepTick(), 149 xStreamBufferCreateStatic(), 352
vTaskSuspend(), 151 xStreamBufferIsEmpty(), 355
vTaskSuspendAll(), 153 xStreamBufferIsFull(), 356
vTimerSetTimerID(), 288 xStreamBufferReceive(), 357
xStreamBufferReceiveFromISR(), 360
X xStreamBufferReset(), 363
xStreamBufferSend(), 364
xEventGroupClearBits(), 299 xStreamBufferSendFromISR(), 367
xEventGroupClearBitsFromISR(), 301 xStreamBufferSetTriggerLevel(), 370
xEventGroupCreate(), 304 xStreamBufferSpacesAvailable(), 371
xEventGroupCreateStatic(), 306 xTaskAbortDelay(), 27
xEventGroupGetBits(), 309 xTaskAllocateMPURegions(), 24
xEventGroupGetBitsFromISR(), 310 xTaskCallApplicationHook(), 29
xEventGroupSetBits(), 311 xTaskCheckForTimeOut(), 32
xEventGroupSetBitsFromISR(), 313 xTaskCreate(), 34
xEventGroupSync(), 316 xTaskCreateRestricted(), 43
xEventGroupWaitBits(), 320 xTaskCreateStatic(), 39
xMessageBufferCreate(), 373 xTaskGetApplicationTaskTag(), 67
xMessageBufferCreateStatic(), 375 xTaskGetCurrentTaskHandle(), 69
xMessageBufferIsEmpty(), 378 xTaskGetHandle(), 71
xMessageBufferIsFull(), 379 xTaskGetIdleTaskHandle(), 70
xMessageBufferReceive(), 380 xTaskGetSchedulerState(), 78
xMessageBufferReceiveFromISR(), 383 xTaskGetTickCount(), 92
xMessageBufferReset(), 386 xTaskGetTickCountFromISR(), 94
398
xTaskNotify(), 99 xTimerDelete(), 267
xTaskNotifyAndQuery(), 102 xTimerGetExpireTime(), 269
xTaskNotifyAndQueryFromISR(), 106 xTimerGetPeriod(), 272
xTaskNotifyFromISR(), 110 xTimerGetTimerDaemonTaskHandle(), 273
xTaskNotifyGive(), 115 xTimerIsTimerActive(), 276
xTaskNotifyStateClear(), 121 xTimerPendFunctionCall (), 278
xTaskNotifyWait(), 126 xTimerPendFunctionCallFromISR(), 280
xTaskResumeAll(), 135 xTimerReset(), 283
xTaskResumeFromISR(), 138 xTimerResetFromISR(), 286
xTimerChangePeriod(), 254 xTimerStart(), 290
xTimerChangePeriodFromISR(), 257 xTimerStartFromISR(), 292
xTimerCreate(), 259 xTimerStop(), 294
xTimerCreateStatic(), 263 xTimerStopFromISR(), 296
399
400