semphr.h 46 KB

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