Projektarbeit Line Following Robot bei Prof. Chowanetz im WS22/23
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

vcos_msgqueue.h 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. Copyright (c) 2012, Broadcom Europe Ltd
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions are met:
  6. * Redistributions of source code must retain the above copyright
  7. notice, this list of conditions and the following disclaimer.
  8. * Redistributions in binary form must reproduce the above copyright
  9. notice, this list of conditions and the following disclaimer in the
  10. documentation and/or other materials provided with the distribution.
  11. * Neither the name of the copyright holder nor the
  12. names of its contributors may be used to endorse or promote products
  13. derived from this software without specific prior written permission.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  15. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
  18. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. /*=============================================================================
  26. VCOS - packet-like messages, based loosely on those found in TRIPOS.
  27. In the simple case, only the server thread creates a message queue, and
  28. clients wait for replies on a semaphore. In more complex cases, clients can
  29. also create message queues (not yet implemented).
  30. Although it's possible for a thread to create multiple queues and listen
  31. on them in turn, if you find yourself doing this it's probably a bug.
  32. =============================================================================*/
  33. #ifndef VCOS_MSGQUEUE_H
  34. #define VCOS_MSGQUEUE_H
  35. #ifdef __cplusplus
  36. extern "C" {
  37. #endif
  38. #include "vcos_types.h"
  39. #include "pthreads/vcos_platform.h"
  40. #include "vcos_blockpool.h"
  41. /**
  42. * \file
  43. *
  44. * Packet-like messages, based loosely on those found in TRIPOS and
  45. * derivatives thereof.
  46. *
  47. * A task can send a message *pointer* to another task, where it is
  48. * queued on a linked list and the task woken up. The receiving task
  49. * consumes all of the messages on its input queue, and optionally
  50. * sends back replies using the original message memory.
  51. *
  52. * A caller can wait for the reply to a specific message - any other
  53. * messages that arrive in the meantime are queued separately.
  54. *
  55. *
  56. * All messages have a standard common layout, but the payload area can
  57. * be used freely to extend this.
  58. */
  59. #define VCOS_MSGQ_MAGIC 0x5147534d
  60. /** Map the payload portion of a message to a structure pointer.
  61. */
  62. #define VCOS_MSG_DATA(_msg) (void*)((_msg)->data)
  63. /** Standard message ids - FIXME - these need to be done properly! */
  64. #define VCOS_MSG_N_QUIT 1
  65. #define VCOS_MSG_N_OPEN 2
  66. #define VCOS_MSG_N_CLOSE 3
  67. #define VCOS_MSG_N_PRIVATE (1<<20)
  68. #define VCOS_MSG_REPLY_BIT (1<<31)
  69. /** Make gnuc compiler be happy about pointer punning */
  70. #ifdef __GNUC__
  71. #define __VCOS_MAY_ALIAS __attribute__((__may_alias__))
  72. #else
  73. #define __VCOS_MAY_ALIAS
  74. #endif
  75. struct VCOS_MSG_T;
  76. /* Replies go to one of these objects.
  77. */
  78. typedef struct VCOS_MSG_WAITER_T
  79. {
  80. /* When the reply is sent, this function gets called with the
  81. * address of the waiter.
  82. */
  83. void (*on_reply)(struct VCOS_MSG_WAITER_T *waiter,
  84. struct VCOS_MSG_T *msg);
  85. } VCOS_MSG_WAITER_T;
  86. /** A single message queue.
  87. */
  88. typedef struct VCOS_MSGQUEUE_T
  89. {
  90. VCOS_MSG_WAITER_T waiter; /**< So we can wait on a queue */
  91. struct VCOS_MSG_T *head; /**< head of linked list of messages waiting on this queue */
  92. struct VCOS_MSG_T *tail; /**< tail of message queue */
  93. VCOS_SEMAPHORE_T sem; /**< thread waits on this for new messages */
  94. VCOS_MUTEX_T lock; /**< locks the messages list */
  95. int attached; /**< Is this attached to a thread? */
  96. } VCOS_MSGQUEUE_T;
  97. /** A single message
  98. */
  99. typedef struct VCOS_MSG_T
  100. {
  101. uint32_t magic; /**< Sanity checking */
  102. uint32_t code; /**< message code */
  103. struct VCOS_MSG_T *next; /**< next in queue */
  104. VCOS_THREAD_T *src_thread; /**< for debug */
  105. struct VCOS_MSG_WAITER_T *waiter; /**< client waiter structure */
  106. struct VCOS_MSGQ_POOL_T *pool; /**< Pool allocated from, or NULL */
  107. } VCOS_MSG_T;
  108. #define MSG_REPLY_BIT (1<<31)
  109. /** Initialize a VCOS_MSG_T. Can also use vcos_msg_init().
  110. */
  111. #define VCOS_MSG_INITIALIZER {VCOS_MSGQ_MAGIC, 0, NULL, NULL, NULL, 0}
  112. /** A pool of messages. This contains its own waiter and
  113. * semaphore, as well as a blockpool for the actual memory
  114. * management.
  115. *
  116. * When messages are returned to the waiter, it posts the
  117. * semaphore.
  118. *
  119. * When waiting for a message, we just wait on the semaphore.
  120. * When allocating without waiting, we just try-wait on the
  121. * semaphore.
  122. *
  123. * If we managed to claim the semaphore, then by definition
  124. * there must be at least that many free messages in the
  125. * blockpool.
  126. */
  127. typedef struct VCOS_MSGQ_POOL_T
  128. {
  129. VCOS_MSG_WAITER_T waiter;
  130. VCOS_BLOCKPOOL_T blockpool;
  131. VCOS_SEMAPHORE_T sem;
  132. uint32_t magic;
  133. } VCOS_MSGQ_POOL_T;
  134. /** Initalise the library. Normally called from vcos_init().
  135. */
  136. VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msgq_init(void);
  137. /** De-initialise the library. Normally called from vcos_deinit().
  138. */
  139. VCOSPRE_ void VCOSPOST_ vcos_msgq_deinit(void);
  140. /** Send a message.
  141. *
  142. * @param dest Destination message queue
  143. * @param code Message code.
  144. * @param msg Pointer to message to send. Must not go out of scope before
  145. * message is received (do not declare on the stack).
  146. */
  147. VCOSPRE_ void VCOSPOST_ vcos_msg_send(VCOS_MSGQUEUE_T *dest, uint32_t code, VCOS_MSG_T *msg);
  148. /** Send a message and wait for a reply.
  149. *
  150. * @param dest Destination message queue
  151. * @param code Message code.
  152. * @param msg Pointer to message to send. May be declared on the stack.
  153. */
  154. VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msg_sendwait(VCOS_MSGQUEUE_T *queue, uint32_t code, VCOS_MSG_T *msg);
  155. /** Wait for a message on a queue.
  156. */
  157. VCOSPRE_ VCOS_MSG_T * VCOSPOST_ vcos_msg_wait(VCOS_MSGQUEUE_T *queue);
  158. /** Peek for a message on this thread's endpoint. If a message is not
  159. * available, NULL is returned. If a message is available it will be
  160. * removed from the endpoint and returned.
  161. */
  162. VCOSPRE_ VCOS_MSG_T * VCOSPOST_ vcos_msg_peek(VCOS_MSGQUEUE_T *queue);
  163. /** Send a reply to a message
  164. */
  165. VCOSPRE_ void VCOSPOST_ vcos_msg_reply(VCOS_MSG_T *msg);
  166. /** Set the reply queue for a message. When the message is replied-to, it
  167. * will return to the given queue.
  168. *
  169. * @param msg Message
  170. * @param queue Message queue the message should return to
  171. */
  172. VCOSPRE_ void VCOSPOST_ vcos_msg_set_source(VCOS_MSG_T *msg, VCOS_MSGQUEUE_T *queue);
  173. /** Initialise a newly allocated message. This only needs to be called
  174. * for messages allocated on the stack, heap or statically. It is not
  175. * needed for messages allocated from a pool.
  176. */
  177. VCOSPRE_ void VCOSPOST_ vcos_msg_init(VCOS_MSG_T *msg);
  178. /** Create a message queue to wait on.
  179. */
  180. VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msgq_create(VCOS_MSGQUEUE_T *queue, const char *name);
  181. /** Destroy a queue
  182. */
  183. VCOSPRE_ void VCOSPOST_ vcos_msgq_delete(VCOS_MSGQUEUE_T *queue);
  184. /*
  185. * Message pools
  186. */
  187. /** Create a pool of messages. Messages can be allocated from the pool and
  188. * sent to a message queue. Replying to the message will automatically
  189. * free it back to the pool.
  190. *
  191. * The pool is threadsafe.
  192. *
  193. * @param count number of messages in the pool
  194. * @param payload_size maximum message payload size, not including MSG_T.
  195. */
  196. VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msgq_pool_create(
  197. VCOS_MSGQ_POOL_T *pool,
  198. size_t count,
  199. size_t payload_size,
  200. const char *name);
  201. /** Destroy a message pool.
  202. */
  203. VCOSPRE_ void VCOSPOST_ vcos_msgq_pool_delete(VCOS_MSGQ_POOL_T *pool);
  204. /** Allocate a message from a message pool.
  205. *
  206. * Note:
  207. *
  208. * If the alloc fails (returns NULL) then your worker thread has stopped
  209. * servicing requests or your pool is too small for the latency in
  210. * the system. Your best bet to handle this is to fail the call that
  211. * needs to send the message.
  212. *
  213. * The returned message payload area is initialised to zero.
  214. *
  215. * @param pool Pool to allocate from.
  216. * @return Message or NULL if pool exhausted.
  217. */
  218. VCOSPRE_ VCOS_MSG_T *VCOSPOST_ vcos_msgq_pool_alloc(VCOS_MSGQ_POOL_T *pool);
  219. /** Wait for a message from a message pool. Waits until a
  220. * message is available in the pool and then allocates it. If
  221. * one is already available, returns immediately.
  222. *
  223. * This call can never fail.
  224. *
  225. * The returned message payload area is initialised to zero.
  226. *
  227. * @param pool Pool to allocate from.
  228. * @return Message
  229. */
  230. VCOSPRE_ VCOS_MSG_T *VCOSPOST_ vcos_msgq_pool_wait(VCOS_MSGQ_POOL_T *pool);
  231. /** Explicitly free a message and return it to its pool.
  232. *
  233. * @param msg Message to free. No-op if NULL.
  234. */
  235. VCOSPRE_ void VCOSPOST_ vcos_msgq_pool_free(VCOS_MSG_T *msg);
  236. #ifdef __cplusplus
  237. }
  238. #endif
  239. #endif