semphr.h 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173
  1. /*
  2. * FreeRTOS Kernel V10.4.3
  3. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  6. * this software and associated documentation files (the "Software"), to deal in
  7. * the Software without restriction, including without limitation the rights to
  8. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  9. * the Software, and to permit persons to whom the Software is furnished to do so,
  10. * subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in all
  13. * copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  17. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  18. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  19. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * https://www.FreeRTOS.org
  23. * https://github.com/FreeRTOS
  24. *
  25. */
  26. #ifndef SEMAPHORE_H
  27. #define SEMAPHORE_H
  28. #ifndef INC_FREERTOS_H
  29. #error "include FreeRTOS.h" must appear in source files before "include semphr.h"
  30. #endif
  31. #include "queue.h"
  32. typedef QueueHandle_t SemaphoreHandle_t;
  33. #define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U )
  34. #define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U )
  35. #define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U )
  36. /**
  37. * semphr. h
  38. * <pre>
  39. * vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore );
  40. * </pre>
  41. *
  42. * In many usage scenarios it is faster and more memory efficient to use a
  43. * direct to task notification in place of a binary semaphore!
  44. * https://www.FreeRTOS.org/RTOS-task-notifications.html
  45. *
  46. * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the
  47. * xSemaphoreCreateBinary() function. Note that binary semaphores created using
  48. * the vSemaphoreCreateBinary() macro are created in a state such that the
  49. * first call to 'take' the semaphore would pass, whereas binary semaphores
  50. * created using xSemaphoreCreateBinary() are created in a state such that the
  51. * the semaphore must first be 'given' before it can be 'taken'.
  52. *
  53. * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
  54. * The queue length is 1 as this is a binary semaphore. The data size is 0
  55. * as we don't want to actually store any data - we just want to know if the
  56. * queue is empty or full.
  57. *
  58. * This type of semaphore can be used for pure synchronisation between tasks or
  59. * between an interrupt and a task. The semaphore need not be given back once
  60. * obtained, so one task/interrupt can continuously 'give' the semaphore while
  61. * another continuously 'takes' the semaphore. For this reason this type of
  62. * semaphore does not use a priority inheritance mechanism. For an alternative
  63. * that does use priority inheritance see xSemaphoreCreateMutex().
  64. *
  65. * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t.
  66. *
  67. * Example usage:
  68. * <pre>
  69. * SemaphoreHandle_t xSemaphore = NULL;
  70. *
  71. * void vATask( void * pvParameters )
  72. * {
  73. * // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
  74. * // This is a macro so pass the variable in directly.
  75. * vSemaphoreCreateBinary( xSemaphore );
  76. *
  77. * if( xSemaphore != NULL )
  78. * {
  79. * // The semaphore was created successfully.
  80. * // The semaphore can now be used.
  81. * }
  82. * }
  83. * </pre>
  84. * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
  85. * \ingroup Semaphores
  86. */
  87. #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
  88. #define vSemaphoreCreateBinary( xSemaphore ) \
  89. { \
  90. ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
  91. if( ( xSemaphore ) != NULL ) \
  92. { \
  93. ( void ) xSemaphoreGive( ( xSemaphore ) ); \
  94. } \
  95. }
  96. #endif
  97. /**
  98. * semphr. h
  99. * <pre>
  100. * SemaphoreHandle_t xSemaphoreCreateBinary( void );
  101. * </pre>
  102. *
  103. * Creates a new binary semaphore instance, and returns a handle by which the
  104. * new semaphore can be referenced.
  105. *
  106. * In many usage scenarios it is faster and more memory efficient to use a
  107. * direct to task notification in place of a binary semaphore!
  108. * https://www.FreeRTOS.org/RTOS-task-notifications.html
  109. *
  110. * Internally, within the FreeRTOS implementation, binary semaphores use a block
  111. * of memory, in which the semaphore structure is stored. If a binary semaphore
  112. * is created using xSemaphoreCreateBinary() then the required memory is
  113. * automatically dynamically allocated inside the xSemaphoreCreateBinary()
  114. * function. (see https://www.FreeRTOS.org/a00111.html). If a binary semaphore
  115. * is created using xSemaphoreCreateBinaryStatic() then the application writer
  116. * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a
  117. * binary semaphore to be created without using any dynamic memory allocation.
  118. *
  119. * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this
  120. * xSemaphoreCreateBinary() function. Note that binary semaphores created using
  121. * the vSemaphoreCreateBinary() macro are created in a state such that the
  122. * first call to 'take' the semaphore would pass, whereas binary semaphores
  123. * created using xSemaphoreCreateBinary() are created in a state such that the
  124. * the semaphore must first be 'given' before it can be 'taken'.
  125. *
  126. * This type of semaphore can be used for pure synchronisation between tasks or
  127. * between an interrupt and a task. The semaphore need not be given back once
  128. * obtained, so one task/interrupt can continuously 'give' the semaphore while
  129. * another continuously 'takes' the semaphore. For this reason this type of
  130. * semaphore does not use a priority inheritance mechanism. For an alternative
  131. * that does use priority inheritance see xSemaphoreCreateMutex().
  132. *
  133. * @return Handle to the created semaphore, or NULL if the memory required to
  134. * hold the semaphore's data structures could not be allocated.
  135. *
  136. * Example usage:
  137. * <pre>
  138. * SemaphoreHandle_t xSemaphore = NULL;
  139. *
  140. * void vATask( void * pvParameters )
  141. * {
  142. * // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
  143. * // This is a macro so pass the variable in directly.
  144. * xSemaphore = xSemaphoreCreateBinary();
  145. *
  146. * if( xSemaphore != NULL )
  147. * {
  148. * // The semaphore was created successfully.
  149. * // The semaphore can now be used.
  150. * }
  151. * }
  152. * </pre>
  153. * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary
  154. * \ingroup Semaphores
  155. */
  156. #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
  157. #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
  158. #endif
  159. /**
  160. * semphr. h
  161. * <pre>
  162. * SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer );
  163. * </pre>
  164. *
  165. * Creates a new binary semaphore instance, and returns a handle by which the
  166. * new semaphore can be referenced.
  167. *
  168. * NOTE: In many usage scenarios it is faster and more memory efficient to use a
  169. * direct to task notification in place of a binary semaphore!
  170. * https://www.FreeRTOS.org/RTOS-task-notifications.html
  171. *
  172. * Internally, within the FreeRTOS implementation, binary semaphores use a block
  173. * of memory, in which the semaphore structure is stored. If a binary semaphore
  174. * is created using xSemaphoreCreateBinary() then the required memory is
  175. * automatically dynamically allocated inside the xSemaphoreCreateBinary()
  176. * function. (see https://www.FreeRTOS.org/a00111.html). If a binary semaphore
  177. * is created using xSemaphoreCreateBinaryStatic() then the application writer
  178. * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a
  179. * binary semaphore to be created without using any dynamic memory allocation.
  180. *
  181. * This type of semaphore can be used for pure synchronisation between tasks or
  182. * between an interrupt and a task. The semaphore need not be given back once
  183. * obtained, so one task/interrupt can continuously 'give' the semaphore while
  184. * another continuously 'takes' the semaphore. For this reason this type of
  185. * semaphore does not use a priority inheritance mechanism. For an alternative
  186. * that does use priority inheritance see xSemaphoreCreateMutex().
  187. *
  188. * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t,
  189. * which will then be used to hold the semaphore's data structure, removing the
  190. * need for the memory to be allocated dynamically.
  191. *
  192. * @return If the semaphore is created then a handle to the created semaphore is
  193. * returned. If pxSemaphoreBuffer is NULL then NULL is returned.
  194. *
  195. * Example usage:
  196. * <pre>
  197. * SemaphoreHandle_t xSemaphore = NULL;
  198. * StaticSemaphore_t xSemaphoreBuffer;
  199. *
  200. * void vATask( void * pvParameters )
  201. * {
  202. * // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
  203. * // The semaphore's data structures will be placed in the xSemaphoreBuffer
  204. * // variable, the address of which is passed into the function. The
  205. * // function's parameter is not NULL, so the function will not attempt any
  206. * // dynamic memory allocation, and therefore the function will not return
  207. * // return NULL.
  208. * xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
  209. *
  210. * // Rest of task code goes here.
  211. * }
  212. * </pre>
  213. * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic
  214. * \ingroup Semaphores
  215. */
  216. #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
  217. #define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE )
  218. #endif /* configSUPPORT_STATIC_ALLOCATION */
  219. /**
  220. * semphr. h
  221. * <pre>
  222. * xSemaphoreTake(
  223. * SemaphoreHandle_t xSemaphore,
  224. * TickType_t xBlockTime
  225. * );
  226. * </pre>
  227. *
  228. * <i>Macro</i> to obtain a semaphore. The semaphore must have previously been
  229. * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
  230. * xSemaphoreCreateCounting().
  231. *
  232. * @param xSemaphore A handle to the semaphore being taken - obtained when
  233. * the semaphore was created.
  234. *
  235. * @param xBlockTime The time in ticks to wait for the semaphore to become
  236. * available. The macro portTICK_PERIOD_MS can be used to convert this to a
  237. * real time. A block time of zero can be used to poll the semaphore. A block
  238. * time of portMAX_DELAY can be used to block indefinitely (provided
  239. * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
  240. *
  241. * @return pdTRUE if the semaphore was obtained. pdFALSE
  242. * if xBlockTime expired without the semaphore becoming available.
  243. *
  244. * Example usage:
  245. * <pre>
  246. * SemaphoreHandle_t xSemaphore = NULL;
  247. *
  248. * // A task that creates a semaphore.
  249. * void vATask( void * pvParameters )
  250. * {
  251. * // Create the semaphore to guard a shared resource.
  252. * xSemaphore = xSemaphoreCreateBinary();
  253. * }
  254. *
  255. * // A task that uses the semaphore.
  256. * void vAnotherTask( void * pvParameters )
  257. * {
  258. * // ... Do other things.
  259. *
  260. * if( xSemaphore != NULL )
  261. * {
  262. * // See if we can obtain the semaphore. If the semaphore is not available
  263. * // wait 10 ticks to see if it becomes free.
  264. * if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
  265. * {
  266. * // We were able to obtain the semaphore and can now access the
  267. * // shared resource.
  268. *
  269. * // ...
  270. *
  271. * // We have finished accessing the shared resource. Release the
  272. * // semaphore.
  273. * xSemaphoreGive( xSemaphore );
  274. * }
  275. * else
  276. * {
  277. * // We could not obtain the semaphore and can therefore not access
  278. * // the shared resource safely.
  279. * }
  280. * }
  281. * }
  282. * </pre>
  283. * \defgroup xSemaphoreTake xSemaphoreTake
  284. * \ingroup Semaphores
  285. */
  286. #define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
  287. /**
  288. * semphr. h
  289. * <pre>
  290. * xSemaphoreTakeRecursive(
  291. * SemaphoreHandle_t xMutex,
  292. * TickType_t xBlockTime
  293. * );
  294. * </pre>
  295. *
  296. * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
  297. * The mutex must have previously been created using a call to
  298. * xSemaphoreCreateRecursiveMutex();
  299. *
  300. * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
  301. * macro to be available.
  302. *
  303. * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
  304. *
  305. * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
  306. * doesn't become available again until the owner has called
  307. * xSemaphoreGiveRecursive() for each successful 'take' request. For example,
  308. * if a task successfully 'takes' the same mutex 5 times then the mutex will
  309. * not be available to any other task until it has also 'given' the mutex back
  310. * exactly five times.
  311. *
  312. * @param xMutex A handle to the mutex being obtained. This is the
  313. * handle returned by xSemaphoreCreateRecursiveMutex();
  314. *
  315. * @param xBlockTime The time in ticks to wait for the semaphore to become
  316. * available. The macro portTICK_PERIOD_MS can be used to convert this to a
  317. * real time. A block time of zero can be used to poll the semaphore. If
  318. * the task already owns the semaphore then xSemaphoreTakeRecursive() will
  319. * return immediately no matter what the value of xBlockTime.
  320. *
  321. * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
  322. * expired without the semaphore becoming available.
  323. *
  324. * Example usage:
  325. * <pre>
  326. * SemaphoreHandle_t xMutex = NULL;
  327. *
  328. * // A task that creates a mutex.
  329. * void vATask( void * pvParameters )
  330. * {
  331. * // Create the mutex to guard a shared resource.
  332. * xMutex = xSemaphoreCreateRecursiveMutex();
  333. * }
  334. *
  335. * // A task that uses the mutex.
  336. * void vAnotherTask( void * pvParameters )
  337. * {
  338. * // ... Do other things.
  339. *
  340. * if( xMutex != NULL )
  341. * {
  342. * // See if we can obtain the mutex. If the mutex is not available
  343. * // wait 10 ticks to see if it becomes free.
  344. * if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
  345. * {
  346. * // We were able to obtain the mutex and can now access the
  347. * // shared resource.
  348. *
  349. * // ...
  350. * // For some reason due to the nature of the code further calls to
  351. * // xSemaphoreTakeRecursive() are made on the same mutex. In real
  352. * // code these would not be just sequential calls as this would make
  353. * // no sense. Instead the calls are likely to be buried inside
  354. * // a more complex call structure.
  355. * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
  356. * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
  357. *
  358. * // The mutex has now been 'taken' three times, so will not be
  359. * // available to another task until it has also been given back
  360. * // three times. Again it is unlikely that real code would have
  361. * // these calls sequentially, but instead buried in a more complex
  362. * // call structure. This is just for illustrative purposes.
  363. * xSemaphoreGiveRecursive( xMutex );
  364. * xSemaphoreGiveRecursive( xMutex );
  365. * xSemaphoreGiveRecursive( xMutex );
  366. *
  367. * // Now the mutex can be taken by other tasks.
  368. * }
  369. * else
  370. * {
  371. * // We could not obtain the mutex and can therefore not access
  372. * // the shared resource safely.
  373. * }
  374. * }
  375. * }
  376. * </pre>
  377. * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
  378. * \ingroup Semaphores
  379. */
  380. #if ( configUSE_RECURSIVE_MUTEXES == 1 )
  381. #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
  382. #endif
  383. /**
  384. * semphr. h
  385. * <pre>
  386. * xSemaphoreGive( SemaphoreHandle_t xSemaphore );
  387. * </pre>
  388. *
  389. * <i>Macro</i> to release a semaphore. The semaphore must have previously been
  390. * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
  391. * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
  392. *
  393. * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for
  394. * an alternative which can be used from an ISR.
  395. *
  396. * This macro must also not be used on semaphores created using
  397. * xSemaphoreCreateRecursiveMutex().
  398. *
  399. * @param xSemaphore A handle to the semaphore being released. This is the
  400. * handle returned when the semaphore was created.
  401. *
  402. * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.
  403. * Semaphores are implemented using queues. An error can occur if there is
  404. * no space on the queue to post a message - indicating that the
  405. * semaphore was not first obtained correctly.
  406. *
  407. * Example usage:
  408. * <pre>
  409. * SemaphoreHandle_t xSemaphore = NULL;
  410. *
  411. * void vATask( void * pvParameters )
  412. * {
  413. * // Create the semaphore to guard a shared resource.
  414. * xSemaphore = vSemaphoreCreateBinary();
  415. *
  416. * if( xSemaphore != NULL )
  417. * {
  418. * if( xSemaphoreGive( xSemaphore ) != pdTRUE )
  419. * {
  420. * // We would expect this call to fail because we cannot give
  421. * // a semaphore without first "taking" it!
  422. * }
  423. *
  424. * // Obtain the semaphore - don't block if the semaphore is not
  425. * // immediately available.
  426. * if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
  427. * {
  428. * // We now have the semaphore and can access the shared resource.
  429. *
  430. * // ...
  431. *
  432. * // We have finished accessing the shared resource so can free the
  433. * // semaphore.
  434. * if( xSemaphoreGive( xSemaphore ) != pdTRUE )
  435. * {
  436. * // We would not expect this call to fail because we must have
  437. * // obtained the semaphore to get here.
  438. * }
  439. * }
  440. * }
  441. * }
  442. * </pre>
  443. * \defgroup xSemaphoreGive xSemaphoreGive
  444. * \ingroup Semaphores
  445. */
  446. #define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
  447. /**
  448. * semphr. h
  449. * <pre>
  450. * xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex );
  451. * </pre>
  452. *
  453. * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
  454. * The mutex must have previously been created using a call to
  455. * xSemaphoreCreateRecursiveMutex();
  456. *
  457. * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
  458. * macro to be available.
  459. *
  460. * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
  461. *
  462. * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
  463. * doesn't become available again until the owner has called
  464. * xSemaphoreGiveRecursive() for each successful 'take' request. For example,
  465. * if a task successfully 'takes' the same mutex 5 times then the mutex will
  466. * not be available to any other task until it has also 'given' the mutex back
  467. * exactly five times.
  468. *
  469. * @param xMutex A handle to the mutex being released, or 'given'. This is the
  470. * handle returned by xSemaphoreCreateMutex();
  471. *
  472. * @return pdTRUE if the semaphore was given.
  473. *
  474. * Example usage:
  475. * <pre>
  476. * SemaphoreHandle_t xMutex = NULL;
  477. *
  478. * // A task that creates a mutex.
  479. * void vATask( void * pvParameters )
  480. * {
  481. * // Create the mutex to guard a shared resource.
  482. * xMutex = xSemaphoreCreateRecursiveMutex();
  483. * }
  484. *
  485. * // A task that uses the mutex.
  486. * void vAnotherTask( void * pvParameters )
  487. * {
  488. * // ... Do other things.
  489. *
  490. * if( xMutex != NULL )
  491. * {
  492. * // See if we can obtain the mutex. If the mutex is not available
  493. * // wait 10 ticks to see if it becomes free.
  494. * if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
  495. * {
  496. * // We were able to obtain the mutex and can now access the
  497. * // shared resource.
  498. *
  499. * // ...
  500. * // For some reason due to the nature of the code further calls to
  501. * // xSemaphoreTakeRecursive() are made on the same mutex. In real
  502. * // code these would not be just sequential calls as this would make
  503. * // no sense. Instead the calls are likely to be buried inside
  504. * // a more complex call structure.
  505. * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
  506. * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
  507. *
  508. * // The mutex has now been 'taken' three times, so will not be
  509. * // available to another task until it has also been given back
  510. * // three times. Again it is unlikely that real code would have
  511. * // these calls sequentially, it would be more likely that the calls
  512. * // to xSemaphoreGiveRecursive() would be called as a call stack
  513. * // unwound. This is just for demonstrative purposes.
  514. * xSemaphoreGiveRecursive( xMutex );
  515. * xSemaphoreGiveRecursive( xMutex );
  516. * xSemaphoreGiveRecursive( xMutex );
  517. *
  518. * // Now the mutex can be taken by other tasks.
  519. * }
  520. * else
  521. * {
  522. * // We could not obtain the mutex and can therefore not access
  523. * // the shared resource safely.
  524. * }
  525. * }
  526. * }
  527. * </pre>
  528. * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
  529. * \ingroup Semaphores
  530. */
  531. #if ( configUSE_RECURSIVE_MUTEXES == 1 )
  532. #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
  533. #endif
  534. /**
  535. * semphr. h
  536. * <pre>
  537. * xSemaphoreGiveFromISR(
  538. * SemaphoreHandle_t xSemaphore,
  539. * BaseType_t *pxHigherPriorityTaskWoken
  540. * );
  541. * </pre>
  542. *
  543. * <i>Macro</i> to release a semaphore. The semaphore must have previously been
  544. * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting().
  545. *
  546. * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
  547. * must not be used with this macro.
  548. *
  549. * This macro can be used from an ISR.
  550. *
  551. * @param xSemaphore A handle to the semaphore being released. This is the
  552. * handle returned when the semaphore was created.
  553. *
  554. * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
  555. * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
  556. * to unblock, and the unblocked task has a priority higher than the currently
  557. * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then
  558. * a context switch should be requested before the interrupt is exited.
  559. *
  560. * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
  561. *
  562. * Example usage:
  563. * <pre>
  564. \#define LONG_TIME 0xffff
  565. \#define TICKS_TO_WAIT 10
  566. * SemaphoreHandle_t xSemaphore = NULL;
  567. *
  568. * // Repetitive task.
  569. * void vATask( void * pvParameters )
  570. * {
  571. * for( ;; )
  572. * {
  573. * // We want this task to run every 10 ticks of a timer. The semaphore
  574. * // was created before this task was started.
  575. *
  576. * // Block waiting for the semaphore to become available.
  577. * if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
  578. * {
  579. * // It is time to execute.
  580. *
  581. * // ...
  582. *
  583. * // We have finished our task. Return to the top of the loop where
  584. * // we will block on the semaphore until it is time to execute
  585. * // again. Note when using the semaphore for synchronisation with an
  586. * // ISR in this manner there is no need to 'give' the semaphore back.
  587. * }
  588. * }
  589. * }
  590. *
  591. * // Timer ISR
  592. * void vTimerISR( void * pvParameters )
  593. * {
  594. * static uint8_t ucLocalTickCount = 0;
  595. * static BaseType_t xHigherPriorityTaskWoken;
  596. *
  597. * // A timer tick has occurred.
  598. *
  599. * // ... Do other time functions.
  600. *
  601. * // Is it time for vATask () to run?
  602. * xHigherPriorityTaskWoken = pdFALSE;
  603. * ucLocalTickCount++;
  604. * if( ucLocalTickCount >= TICKS_TO_WAIT )
  605. * {
  606. * // Unblock the task by releasing the semaphore.
  607. * xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
  608. *
  609. * // Reset the count so we release the semaphore again in 10 ticks time.
  610. * ucLocalTickCount = 0;
  611. * }
  612. *
  613. * if( xHigherPriorityTaskWoken != pdFALSE )
  614. * {
  615. * // We can force a context switch here. Context switching from an
  616. * // ISR uses port specific syntax. Check the demo task for your port
  617. * // to find the syntax required.
  618. * }
  619. * }
  620. * </pre>
  621. * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
  622. * \ingroup Semaphores
  623. */
  624. #define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) )
  625. /**
  626. * semphr. h
  627. * <pre>
  628. * xSemaphoreTakeFromISR(
  629. * SemaphoreHandle_t xSemaphore,
  630. * BaseType_t *pxHigherPriorityTaskWoken
  631. * );
  632. * </pre>
  633. *
  634. * <i>Macro</i> to take a semaphore from an ISR. The semaphore must have
  635. * previously been created with a call to xSemaphoreCreateBinary() or
  636. * xSemaphoreCreateCounting().
  637. *
  638. * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
  639. * must not be used with this macro.
  640. *
  641. * This macro can be used from an ISR, however taking a semaphore from an ISR
  642. * is not a common operation. It is likely to only be useful when taking a
  643. * counting semaphore when an interrupt is obtaining an object from a resource
  644. * pool (when the semaphore count indicates the number of resources available).
  645. *
  646. * @param xSemaphore A handle to the semaphore being taken. This is the
  647. * handle returned when the semaphore was created.
  648. *
  649. * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set
  650. * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task
  651. * to unblock, and the unblocked task has a priority higher than the currently
  652. * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then
  653. * a context switch should be requested before the interrupt is exited.
  654. *
  655. * @return pdTRUE if the semaphore was successfully taken, otherwise
  656. * pdFALSE
  657. */
  658. #define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )
  659. /**
  660. * semphr. h
  661. * <pre>
  662. * SemaphoreHandle_t xSemaphoreCreateMutex( void );
  663. * </pre>
  664. *
  665. * Creates a new mutex type semaphore instance, and returns a handle by which
  666. * the new mutex can be referenced.
  667. *
  668. * Internally, within the FreeRTOS implementation, mutex semaphores use a block
  669. * of memory, in which the mutex structure is stored. If a mutex is created
  670. * using xSemaphoreCreateMutex() then the required memory is automatically
  671. * dynamically allocated inside the xSemaphoreCreateMutex() function. (see
  672. * https://www.FreeRTOS.org/a00111.html). If a mutex is created using
  673. * xSemaphoreCreateMutexStatic() then the application writer must provided the
  674. * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created
  675. * without using any dynamic memory allocation.
  676. *
  677. * Mutexes created using this function can be accessed using the xSemaphoreTake()
  678. * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
  679. * xSemaphoreGiveRecursive() macros must not be used.
  680. *
  681. * This type of semaphore uses a priority inheritance mechanism so a task
  682. * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
  683. * semaphore it is no longer required.
  684. *
  685. * Mutex type semaphores cannot be used from within interrupt service routines.
  686. *
  687. * See xSemaphoreCreateBinary() for an alternative implementation that can be
  688. * used for pure synchronisation (where one task or interrupt always 'gives' the
  689. * semaphore and another always 'takes' the semaphore) and from within interrupt
  690. * service routines.
  691. *
  692. * @return If the mutex was successfully created then a handle to the created
  693. * semaphore is returned. If there was not enough heap to allocate the mutex
  694. * data structures then NULL is returned.
  695. *
  696. * Example usage:
  697. * <pre>
  698. * SemaphoreHandle_t xSemaphore;
  699. *
  700. * void vATask( void * pvParameters )
  701. * {
  702. * // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
  703. * // This is a macro so pass the variable in directly.
  704. * xSemaphore = xSemaphoreCreateMutex();
  705. *
  706. * if( xSemaphore != NULL )
  707. * {
  708. * // The semaphore was created successfully.
  709. * // The semaphore can now be used.
  710. * }
  711. * }
  712. * </pre>
  713. * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex
  714. * \ingroup Semaphores
  715. */
  716. #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
  717. #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
  718. #endif
  719. /**
  720. * semphr. h
  721. * <pre>
  722. * SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer );
  723. * </pre>
  724. *
  725. * Creates a new mutex type semaphore instance, and returns a handle by which
  726. * the new mutex can be referenced.
  727. *
  728. * Internally, within the FreeRTOS implementation, mutex semaphores use a block
  729. * of memory, in which the mutex structure is stored. If a mutex is created
  730. * using xSemaphoreCreateMutex() then the required memory is automatically
  731. * dynamically allocated inside the xSemaphoreCreateMutex() function. (see
  732. * https://www.FreeRTOS.org/a00111.html). If a mutex is created using
  733. * xSemaphoreCreateMutexStatic() then the application writer must provided the
  734. * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created
  735. * without using any dynamic memory allocation.
  736. *
  737. * Mutexes created using this function can be accessed using the xSemaphoreTake()
  738. * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
  739. * xSemaphoreGiveRecursive() macros must not be used.
  740. *
  741. * This type of semaphore uses a priority inheritance mechanism so a task
  742. * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
  743. * semaphore it is no longer required.
  744. *
  745. * Mutex type semaphores cannot be used from within interrupt service routines.
  746. *
  747. * See xSemaphoreCreateBinary() for an alternative implementation that can be
  748. * used for pure synchronisation (where one task or interrupt always 'gives' the
  749. * semaphore and another always 'takes' the semaphore) and from within interrupt
  750. * service routines.
  751. *
  752. * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t,
  753. * which will be used to hold the mutex's data structure, removing the need for
  754. * the memory to be allocated dynamically.
  755. *
  756. * @return If the mutex was successfully created then a handle to the created
  757. * mutex is returned. If pxMutexBuffer was NULL then NULL is returned.
  758. *
  759. * Example usage:
  760. * <pre>
  761. * SemaphoreHandle_t xSemaphore;
  762. * StaticSemaphore_t xMutexBuffer;
  763. *
  764. * void vATask( void * pvParameters )
  765. * {
  766. * // A mutex cannot be used before it has been created. xMutexBuffer is
  767. * // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
  768. * // attempted.
  769. * xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
  770. *
  771. * // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
  772. * // so there is no need to check it.
  773. * }
  774. * </pre>
  775. * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic
  776. * \ingroup Semaphores
  777. */
  778. #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
  779. #define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) )
  780. #endif /* configSUPPORT_STATIC_ALLOCATION */
  781. /**
  782. * semphr. h
  783. * <pre>
  784. * SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void );
  785. * </pre>
  786. *
  787. * Creates a new recursive mutex type semaphore instance, and returns a handle
  788. * by which the new recursive mutex can be referenced.
  789. *
  790. * Internally, within the FreeRTOS implementation, recursive mutexs use a block
  791. * of memory, in which the mutex structure is stored. If a recursive mutex is
  792. * created using xSemaphoreCreateRecursiveMutex() then the required memory is
  793. * automatically dynamically allocated inside the
  794. * xSemaphoreCreateRecursiveMutex() function. (see
  795. * https://www.FreeRTOS.org/a00111.html). If a recursive mutex is created using
  796. * xSemaphoreCreateRecursiveMutexStatic() then the application writer must
  797. * provide the memory that will get used by the mutex.
  798. * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to
  799. * be created without using any dynamic memory allocation.
  800. *
  801. * Mutexes created using this macro can be accessed using the
  802. * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
  803. * xSemaphoreTake() and xSemaphoreGive() macros must not be used.
  804. *
  805. * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
  806. * doesn't become available again until the owner has called
  807. * xSemaphoreGiveRecursive() for each successful 'take' request. For example,
  808. * if a task successfully 'takes' the same mutex 5 times then the mutex will
  809. * not be available to any other task until it has also 'given' the mutex back
  810. * exactly five times.
  811. *
  812. * This type of semaphore uses a priority inheritance mechanism so a task
  813. * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
  814. * semaphore it is no longer required.
  815. *
  816. * Mutex type semaphores cannot be used from within interrupt service routines.
  817. *
  818. * See xSemaphoreCreateBinary() for an alternative implementation that can be
  819. * used for pure synchronisation (where one task or interrupt always 'gives' the
  820. * semaphore and another always 'takes' the semaphore) and from within interrupt
  821. * service routines.
  822. *
  823. * @return xSemaphore Handle to the created mutex semaphore. Should be of type
  824. * SemaphoreHandle_t.
  825. *
  826. * Example usage:
  827. * <pre>
  828. * SemaphoreHandle_t xSemaphore;
  829. *
  830. * void vATask( void * pvParameters )
  831. * {
  832. * // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
  833. * // This is a macro so pass the variable in directly.
  834. * xSemaphore = xSemaphoreCreateRecursiveMutex();
  835. *
  836. * if( xSemaphore != NULL )
  837. * {
  838. * // The semaphore was created successfully.
  839. * // The semaphore can now be used.
  840. * }
  841. * }
  842. * </pre>
  843. * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex
  844. * \ingroup Semaphores
  845. */
  846. #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
  847. #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
  848. #endif
  849. /**
  850. * semphr. h
  851. * <pre>
  852. * SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer );
  853. * </pre>
  854. *
  855. * Creates a new recursive mutex type semaphore instance, and returns a handle
  856. * by which the new recursive mutex can be referenced.
  857. *
  858. * Internally, within the FreeRTOS implementation, recursive mutexs use a block
  859. * of memory, in which the mutex structure is stored. If a recursive mutex is
  860. * created using xSemaphoreCreateRecursiveMutex() then the required memory is
  861. * automatically dynamically allocated inside the
  862. * xSemaphoreCreateRecursiveMutex() function. (see
  863. * https://www.FreeRTOS.org/a00111.html). If a recursive mutex is created using
  864. * xSemaphoreCreateRecursiveMutexStatic() then the application writer must
  865. * provide the memory that will get used by the mutex.
  866. * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to
  867. * be created without using any dynamic memory allocation.
  868. *
  869. * Mutexes created using this macro can be accessed using the
  870. * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
  871. * xSemaphoreTake() and xSemaphoreGive() macros must not be used.
  872. *
  873. * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
  874. * doesn't become available again until the owner has called
  875. * xSemaphoreGiveRecursive() for each successful 'take' request. For example,
  876. * if a task successfully 'takes' the same mutex 5 times then the mutex will
  877. * not be available to any other task until it has also 'given' the mutex back
  878. * exactly five times.
  879. *
  880. * This type of semaphore uses a priority inheritance mechanism so a task
  881. * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
  882. * semaphore it is no longer required.
  883. *
  884. * Mutex type semaphores cannot be used from within interrupt service routines.
  885. *
  886. * See xSemaphoreCreateBinary() for an alternative implementation that can be
  887. * used for pure synchronisation (where one task or interrupt always 'gives' the
  888. * semaphore and another always 'takes' the semaphore) and from within interrupt
  889. * service routines.
  890. *
  891. * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t,
  892. * which will then be used to hold the recursive mutex's data structure,
  893. * removing the need for the memory to be allocated dynamically.
  894. *
  895. * @return If the recursive mutex was successfully created then a handle to the
  896. * created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is
  897. * returned.
  898. *
  899. * Example usage:
  900. * <pre>
  901. * SemaphoreHandle_t xSemaphore;
  902. * StaticSemaphore_t xMutexBuffer;
  903. *
  904. * void vATask( void * pvParameters )
  905. * {
  906. * // A recursive semaphore cannot be used before it is created. Here a
  907. * // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
  908. * // The address of xMutexBuffer is passed into the function, and will hold
  909. * // the mutexes data structures - so no dynamic memory allocation will be
  910. * // attempted.
  911. * xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
  912. *
  913. * // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
  914. * // so there is no need to check it.
  915. * }
  916. * </pre>
  917. * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic
  918. * \ingroup Semaphores
  919. */
  920. #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
  921. #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore )
  922. #endif /* configSUPPORT_STATIC_ALLOCATION */
  923. /**
  924. * semphr. h
  925. * <pre>
  926. * SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount );
  927. * </pre>
  928. *
  929. * Creates a new counting semaphore instance, and returns a handle by which the
  930. * new counting semaphore can be referenced.
  931. *
  932. * In many usage scenarios it is faster and more memory efficient to use a
  933. * direct to task notification in place of a counting semaphore!
  934. * https://www.FreeRTOS.org/RTOS-task-notifications.html
  935. *
  936. * Internally, within the FreeRTOS implementation, counting semaphores use a
  937. * block of memory, in which the counting semaphore structure is stored. If a
  938. * counting semaphore is created using xSemaphoreCreateCounting() then the
  939. * required memory is automatically dynamically allocated inside the
  940. * xSemaphoreCreateCounting() function. (see
  941. * https://www.FreeRTOS.org/a00111.html). If a counting semaphore is created
  942. * using xSemaphoreCreateCountingStatic() then the application writer can
  943. * instead optionally provide the memory that will get used by the counting
  944. * semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting
  945. * semaphore to be created without using any dynamic memory allocation.
  946. *
  947. * Counting semaphores are typically used for two things:
  948. *
  949. * 1) Counting events.
  950. *
  951. * In this usage scenario an event handler will 'give' a semaphore each time
  952. * an event occurs (incrementing the semaphore count value), and a handler
  953. * task will 'take' a semaphore each time it processes an event
  954. * (decrementing the semaphore count value). The count value is therefore
  955. * the difference between the number of events that have occurred and the
  956. * number that have been processed. In this case it is desirable for the
  957. * initial count value to be zero.
  958. *
  959. * 2) Resource management.
  960. *
  961. * In this usage scenario the count value indicates the number of resources
  962. * available. To obtain control of a resource a task must first obtain a
  963. * semaphore - decrementing the semaphore count value. When the count value
  964. * reaches zero there are no free resources. When a task finishes with the
  965. * resource it 'gives' the semaphore back - incrementing the semaphore count
  966. * value. In this case it is desirable for the initial count value to be
  967. * equal to the maximum count value, indicating that all resources are free.
  968. *
  969. * @param uxMaxCount The maximum count value that can be reached. When the
  970. * semaphore reaches this value it can no longer be 'given'.
  971. *
  972. * @param uxInitialCount The count value assigned to the semaphore when it is
  973. * created.
  974. *
  975. * @return Handle to the created semaphore. Null if the semaphore could not be
  976. * created.
  977. *
  978. * Example usage:
  979. * <pre>
  980. * SemaphoreHandle_t xSemaphore;
  981. *
  982. * void vATask( void * pvParameters )
  983. * {
  984. * SemaphoreHandle_t xSemaphore = NULL;
  985. *
  986. * // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
  987. * // The max value to which the semaphore can count should be 10, and the
  988. * // initial value assigned to the count should be 0.
  989. * xSemaphore = xSemaphoreCreateCounting( 10, 0 );
  990. *
  991. * if( xSemaphore != NULL )
  992. * {
  993. * // The semaphore was created successfully.
  994. * // The semaphore can now be used.
  995. * }
  996. * }
  997. * </pre>
  998. * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
  999. * \ingroup Semaphores
  1000. */
  1001. #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
  1002. #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
  1003. #endif
  1004. /**
  1005. * semphr. h
  1006. * <pre>
  1007. * SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer );
  1008. * </pre>
  1009. *
  1010. * Creates a new counting semaphore instance, and returns a handle by which the
  1011. * new counting semaphore can be referenced.
  1012. *
  1013. * In many usage scenarios it is faster and more memory efficient to use a
  1014. * direct to task notification in place of a counting semaphore!
  1015. * https://www.FreeRTOS.org/RTOS-task-notifications.html
  1016. *
  1017. * Internally, within the FreeRTOS implementation, counting semaphores use a
  1018. * block of memory, in which the counting semaphore structure is stored. If a
  1019. * counting semaphore is created using xSemaphoreCreateCounting() then the
  1020. * required memory is automatically dynamically allocated inside the
  1021. * xSemaphoreCreateCounting() function. (see
  1022. * https://www.FreeRTOS.org/a00111.html). If a counting semaphore is created
  1023. * using xSemaphoreCreateCountingStatic() then the application writer must
  1024. * provide the memory. xSemaphoreCreateCountingStatic() therefore allows a
  1025. * counting semaphore to be created without using any dynamic memory allocation.
  1026. *
  1027. * Counting semaphores are typically used for two things:
  1028. *
  1029. * 1) Counting events.
  1030. *
  1031. * In this usage scenario an event handler will 'give' a semaphore each time
  1032. * an event occurs (incrementing the semaphore count value), and a handler
  1033. * task will 'take' a semaphore each time it processes an event
  1034. * (decrementing the semaphore count value). The count value is therefore
  1035. * the difference between the number of events that have occurred and the
  1036. * number that have been processed. In this case it is desirable for the
  1037. * initial count value to be zero.
  1038. *
  1039. * 2) Resource management.
  1040. *
  1041. * In this usage scenario the count value indicates the number of resources
  1042. * available. To obtain control of a resource a task must first obtain a
  1043. * semaphore - decrementing the semaphore count value. When the count value
  1044. * reaches zero there are no free resources. When a task finishes with the
  1045. * resource it 'gives' the semaphore back - incrementing the semaphore count
  1046. * value. In this case it is desirable for the initial count value to be
  1047. * equal to the maximum count value, indicating that all resources are free.
  1048. *
  1049. * @param uxMaxCount The maximum count value that can be reached. When the
  1050. * semaphore reaches this value it can no longer be 'given'.
  1051. *
  1052. * @param uxInitialCount The count value assigned to the semaphore when it is
  1053. * created.
  1054. *
  1055. * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t,
  1056. * which will then be used to hold the semaphore's data structure, removing the
  1057. * need for the memory to be allocated dynamically.
  1058. *
  1059. * @return If the counting semaphore was successfully created then a handle to
  1060. * the created counting semaphore is returned. If pxSemaphoreBuffer was NULL
  1061. * then NULL is returned.
  1062. *
  1063. * Example usage:
  1064. * <pre>
  1065. * SemaphoreHandle_t xSemaphore;
  1066. * StaticSemaphore_t xSemaphoreBuffer;
  1067. *
  1068. * void vATask( void * pvParameters )
  1069. * {
  1070. * SemaphoreHandle_t xSemaphore = NULL;
  1071. *
  1072. * // Counting semaphore cannot be used before they have been created. Create
  1073. * // a counting semaphore using xSemaphoreCreateCountingStatic(). The max
  1074. * // value to which the semaphore can count is 10, and the initial value
  1075. * // assigned to the count will be 0. The address of xSemaphoreBuffer is
  1076. * // passed in and will be used to hold the semaphore structure, so no dynamic
  1077. * // memory allocation will be used.
  1078. * xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
  1079. *
  1080. * // No memory allocation was attempted so xSemaphore cannot be NULL, so there
  1081. * // is no need to check its value.
  1082. * }
  1083. * </pre>
  1084. * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic
  1085. * \ingroup Semaphores
  1086. */
  1087. #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
  1088. #define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) )
  1089. #endif /* configSUPPORT_STATIC_ALLOCATION */
  1090. /**
  1091. * semphr. h
  1092. * <pre>
  1093. * void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
  1094. * </pre>
  1095. *
  1096. * Delete a semaphore. This function must be used with care. For example,
  1097. * do not delete a mutex type semaphore if the mutex is held by a task.
  1098. *
  1099. * @param xSemaphore A handle to the semaphore to be deleted.
  1100. *
  1101. * \defgroup vSemaphoreDelete vSemaphoreDelete
  1102. * \ingroup Semaphores
  1103. */
  1104. #define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) )
  1105. /**
  1106. * semphr.h
  1107. * <pre>
  1108. * TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );
  1109. * </pre>
  1110. *
  1111. * If xMutex is indeed a mutex type semaphore, return the current mutex holder.
  1112. * If xMutex is not a mutex type semaphore, or the mutex is available (not held
  1113. * by a task), return NULL.
  1114. *
  1115. * Note: This is a good way of determining if the calling task is the mutex
  1116. * holder, but not a good way of determining the identity of the mutex holder as
  1117. * the holder may change between the function exiting and the returned value
  1118. * being tested.
  1119. */
  1120. #define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )
  1121. /**
  1122. * semphr.h
  1123. * <pre>
  1124. * TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex );
  1125. * </pre>
  1126. *
  1127. * If xMutex is indeed a mutex type semaphore, return the current mutex holder.
  1128. * If xMutex is not a mutex type semaphore, or the mutex is available (not held
  1129. * by a task), return NULL.
  1130. *
  1131. */
  1132. #define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) )
  1133. /**
  1134. * semphr.h
  1135. * <pre>
  1136. * UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
  1137. * </pre>
  1138. *
  1139. * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns
  1140. * its current count value. If the semaphore is a binary semaphore then
  1141. * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the
  1142. * semaphore is not available.
  1143. *
  1144. */
  1145. #define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
  1146. #endif /* SEMAPHORE_H */