chfactory.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. /*
  2. ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio.
  3. This file is part of ChibiOS.
  4. ChibiOS is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. ChibiOS is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. /**
  16. * @file chfactory.h
  17. * @brief ChibiOS objects factory structures and macros.
  18. *
  19. * @addtogroup oslib_objects_factory
  20. * @{
  21. */
  22. #ifndef CHFACTORY_H
  23. #define CHFACTORY_H
  24. #if (CH_CFG_USE_FACTORY == TRUE) || defined(__DOXYGEN__)
  25. /*===========================================================================*/
  26. /* Module constants. */
  27. /*===========================================================================*/
  28. /*===========================================================================*/
  29. /* Module pre-compile time settings. */
  30. /*===========================================================================*/
  31. /**
  32. * @brief Maximum length for object names.
  33. * @details If the specified length is zero then the name is stored by
  34. * pointer but this could have unintended side effects.
  35. */
  36. #if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) || defined(__DOXYGEN__)
  37. #define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8
  38. #endif
  39. /**
  40. * @brief Enables the registry of generic objects.
  41. */
  42. #if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) || defined(__DOXYGEN__)
  43. #define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE
  44. #endif
  45. /**
  46. * @brief Enables factory for generic buffers.
  47. */
  48. #if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) || defined(__DOXYGEN__)
  49. #define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE
  50. #endif
  51. /**
  52. * @brief Enables factory for semaphores.
  53. */
  54. #if !defined(CH_CFG_FACTORY_SEMAPHORES) || defined(__DOXYGEN__)
  55. #define CH_CFG_FACTORY_SEMAPHORES TRUE
  56. #endif
  57. /**
  58. * @brief Enables factory for mailboxes.
  59. */
  60. #if !defined(CH_CFG_FACTORY_MAILBOXES) || defined(__DOXYGEN__)
  61. #define CH_CFG_FACTORY_MAILBOXES TRUE
  62. #endif
  63. /**
  64. * @brief Enables factory for objects FIFOs.
  65. */
  66. #if !defined(CH_CFG_FACTORY_OBJ_FIFOS) || defined(__DOXYGEN__)
  67. #define CH_CFG_FACTORY_OBJ_FIFOS TRUE
  68. #endif
  69. /**
  70. * @brief Enables factory for objects FIFOs.
  71. */
  72. #if !defined(CH_CFG_FACTORY_OBJ_FIFOS) || defined(__DOXYGEN__)
  73. #define CH_CFG_FACTORY_OBJ_FIFOS TRUE
  74. #endif
  75. /**
  76. * @brief Enables factory for Pipes.
  77. */
  78. #if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__)
  79. #define CH_CFG_FACTORY_PIPES TRUE
  80. #endif
  81. /*===========================================================================*/
  82. /* Derived constants and error checks. */
  83. /*===========================================================================*/
  84. #if (CH_CFG_FACTORY_SEMAPHORES == TRUE) && (CH_CFG_USE_SEMAPHORES == FALSE)
  85. /*lint -save -e767 [20.5] Valid because the #undef.*/
  86. #undef CH_CFG_FACTORY_SEMAPHORES
  87. #define CH_CFG_FACTORY_SEMAPHORES FALSE
  88. /*lint restore*/
  89. #endif
  90. #if (CH_CFG_FACTORY_MAILBOXES == TRUE) && (CH_CFG_USE_MAILBOXES == FALSE)
  91. /*lint -save -e767 [20.5] Valid because the #undef.*/
  92. #undef CH_CFG_FACTORY_MAILBOXES
  93. #define CH_CFG_FACTORY_MAILBOXES FALSE
  94. /*lint restore*/
  95. #endif
  96. #if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) && (CH_CFG_USE_OBJ_FIFOS == FALSE)
  97. /*lint -save -e767 [20.5] Valid because the #undef.*/
  98. #undef CH_CFG_FACTORY_OBJ_FIFOS
  99. #define CH_CFG_FACTORY_OBJ_FIFOS FALSE
  100. /*lint restore*/
  101. #endif
  102. #if (CH_CFG_FACTORY_PIPES == TRUE) && (CH_CFG_USE_PIPES == FALSE)
  103. /*lint -save -e767 [20.5] Valid because the #undef.*/
  104. #undef CH_CFG_FACTORY_PIPES
  105. #define CH_CFG_FACTORY_PIPES FALSE
  106. /*lint restore*/
  107. #endif
  108. #define CH_FACTORY_REQUIRES_POOLS \
  109. ((CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || \
  110. (CH_CFG_FACTORY_SEMAPHORES == TRUE))
  111. #define CH_FACTORY_REQUIRES_HEAP \
  112. ((CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || \
  113. (CH_CFG_FACTORY_MAILBOXES == TRUE) || \
  114. (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || \
  115. (CH_CFG_FACTORY_PIPES == TRUE))
  116. #if (CH_CFG_FACTORY_MAX_NAMES_LENGTH < 0) || \
  117. (CH_CFG_FACTORY_MAX_NAMES_LENGTH > 32)
  118. #error "invalid CH_CFG_FACTORY_MAX_NAMES_LENGTH value"
  119. #endif
  120. #if (CH_CFG_USE_MUTEXES == FALSE) && (CH_CFG_USE_SEMAPHORES == FALSE)
  121. #error "CH_CFG_USE_FACTORY requires CH_CFG_USE_MUTEXES and/or CH_CFG_USE_SEMAPHORES"
  122. #endif
  123. #if CH_CFG_USE_MEMCORE == FALSE
  124. #error "CH_CFG_USE_FACTORY requires CH_CFG_USE_MEMCORE"
  125. #endif
  126. #if CH_FACTORY_REQUIRES_POOLS && (CH_CFG_USE_MEMPOOLS == FALSE)
  127. #error "CH_CFG_USE_MEMPOOLS is required"
  128. #endif
  129. #if CH_FACTORY_REQUIRES_HEAP && (CH_CFG_USE_HEAP == FALSE)
  130. #error "CH_CFG_USE_HEAP is required"
  131. #endif
  132. /*===========================================================================*/
  133. /* Module data structures and types. */
  134. /*===========================================================================*/
  135. /**
  136. * @brief Type of a dynamic object list element.
  137. */
  138. typedef struct ch_dyn_element {
  139. /**
  140. * @brief Next dynamic object in the list.
  141. */
  142. struct ch_dyn_element *next;
  143. /**
  144. * @brief Number of references to this object.
  145. */
  146. ucnt_t refs;
  147. #if (CH_CFG_FACTORY_MAX_NAMES_LENGTH > 0) || defined(__DOXYGEN__)
  148. char name[CH_CFG_FACTORY_MAX_NAMES_LENGTH];
  149. #else
  150. const char *name;
  151. #endif
  152. } dyn_element_t;
  153. /**
  154. * @brief Type of a dynamic object list.
  155. */
  156. typedef struct ch_dyn_list {
  157. dyn_element_t *next;
  158. } dyn_list_t;
  159. #if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
  160. /**
  161. * @brief Type of a registered object.
  162. */
  163. typedef struct ch_registered_static_object {
  164. /**
  165. * @brief List element of the registered object.
  166. */
  167. dyn_element_t element;
  168. /**
  169. * @brief Pointer to the object.
  170. * @note The type of the object is not stored in anyway.
  171. */
  172. void *objp;
  173. } registered_object_t;
  174. #endif
  175. #if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
  176. /**
  177. * @brief Type of a dynamic buffer object.
  178. */
  179. typedef struct ch_dyn_object {
  180. /**
  181. * @brief List element of the dynamic buffer object.
  182. */
  183. dyn_element_t element;
  184. /*lint -save -e9038 [18.7] Required by design.*/
  185. /**
  186. * @brief The buffer.
  187. * @note This requires C99.
  188. */
  189. uint8_t buffer[];
  190. /*lint restore*/
  191. } dyn_buffer_t;
  192. #endif
  193. #if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
  194. /**
  195. * @brief Type of a dynamic semaphore.
  196. */
  197. typedef struct ch_dyn_semaphore {
  198. /**
  199. * @brief List element of the dynamic semaphore.
  200. */
  201. dyn_element_t element;
  202. /**
  203. * @brief The semaphore.
  204. */
  205. semaphore_t sem;
  206. } dyn_semaphore_t;
  207. #endif
  208. #if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
  209. /**
  210. * @brief Type of a dynamic buffer object.
  211. */
  212. typedef struct ch_dyn_mailbox {
  213. /**
  214. * @brief List element of the dynamic buffer object.
  215. */
  216. dyn_element_t element;
  217. /**
  218. * @brief The mailbox.
  219. */
  220. mailbox_t mbx;
  221. /*lint -save -e9038 [18.7] Required by design.*/
  222. /**
  223. * @brief Messages buffer.
  224. * @note This requires C99.
  225. */
  226. msg_t msgbuf[];
  227. /*lint restore*/
  228. } dyn_mailbox_t;
  229. #endif
  230. #if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
  231. /**
  232. * @brief Type of a dynamic buffer object.
  233. */
  234. typedef struct ch_dyn_objects_fifo {
  235. /**
  236. * @brief List element of the dynamic buffer object.
  237. */
  238. dyn_element_t element;
  239. /**
  240. * @brief The objects FIFO.
  241. */
  242. objects_fifo_t fifo;
  243. /*lint -save -e9038 [18.7] Required by design.*/
  244. /**
  245. * @brief Messages buffer.
  246. * @note This open array is followed by another area containing the
  247. * objects, this area is not represented in this structure.
  248. * @note This requires C99.
  249. */
  250. msg_t msgbuf[];
  251. /*lint restore*/
  252. } dyn_objects_fifo_t;
  253. #endif
  254. #if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
  255. /**
  256. * @brief Type of a dynamic pipe object.
  257. */
  258. typedef struct ch_dyn_pipe {
  259. /**
  260. * @brief List element of the dynamic pipe object.
  261. */
  262. dyn_element_t element;
  263. /**
  264. * @brief The pipe.
  265. */
  266. pipe_t pipe;
  267. /*lint -save -e9038 [18.7] Required by design.*/
  268. /**
  269. * @brief Messages buffer.
  270. * @note This requires C99.
  271. */
  272. uint8_t buffer[];
  273. /*lint restore*/
  274. } dyn_pipe_t;
  275. #endif
  276. /**
  277. * @brief Type of the factory main object.
  278. */
  279. typedef struct ch_objects_factory {
  280. /**
  281. * @brief Factory access mutex or semaphore.
  282. */
  283. #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
  284. mutex_t mtx;
  285. #else
  286. semaphore_t sem;
  287. #endif
  288. /**
  289. * @brief List of the registered objects.
  290. */
  291. dyn_list_t obj_list;
  292. /**
  293. * @brief Pool of the available registered objects.
  294. */
  295. memory_pool_t obj_pool;
  296. #if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
  297. /**
  298. * @brief List of the allocated buffer objects.
  299. */
  300. dyn_list_t buf_list;
  301. #endif /* CH_CFG_FACTORY_GENERIC_BUFFERS = TRUE */
  302. #if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
  303. /**
  304. * @brief List of the allocated semaphores.
  305. */
  306. dyn_list_t sem_list;
  307. /**
  308. * @brief Pool of the available semaphores.
  309. */
  310. memory_pool_t sem_pool;
  311. #endif /* CH_CFG_FACTORY_SEMAPHORES = TRUE */
  312. #if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
  313. /**
  314. * @brief List of the allocated buffer objects.
  315. */
  316. dyn_list_t mbx_list;
  317. #endif /* CH_CFG_FACTORY_MAILBOXES = TRUE */
  318. #if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
  319. /**
  320. * @brief List of the allocated "objects FIFO" objects.
  321. */
  322. dyn_list_t fifo_list;
  323. #endif /* CH_CFG_FACTORY_OBJ_FIFOS = TRUE */
  324. #if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
  325. /**
  326. * @brief List of the allocated pipe objects.
  327. */
  328. dyn_list_t pipe_list;
  329. #endif /* CH_CFG_FACTORY_PIPES = TRUE */
  330. } objects_factory_t;
  331. /*===========================================================================*/
  332. /* Module macros. */
  333. /*===========================================================================*/
  334. /*===========================================================================*/
  335. /* External declarations. */
  336. /*===========================================================================*/
  337. #if !defined(__DOXYGEN__)
  338. extern objects_factory_t ch_factory;
  339. #endif
  340. #ifdef __cplusplus
  341. extern "C" {
  342. #endif
  343. void _factory_init(void);
  344. #if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
  345. registered_object_t *chFactoryRegisterObject(const char *name,
  346. void *objp);
  347. registered_object_t *chFactoryFindObject(const char *name);
  348. registered_object_t *chFactoryFindObjectByPointer(void *objp);
  349. void chFactoryReleaseObject(registered_object_t *rop);
  350. #endif
  351. #if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
  352. dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size);
  353. dyn_buffer_t *chFactoryFindBuffer(const char *name);
  354. void chFactoryReleaseBuffer(dyn_buffer_t *dbp);
  355. #endif
  356. #if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
  357. dyn_semaphore_t *chFactoryCreateSemaphore(const char *name, cnt_t n);
  358. dyn_semaphore_t *chFactoryFindSemaphore(const char *name);
  359. void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp);
  360. #endif
  361. #if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
  362. dyn_mailbox_t *chFactoryCreateMailbox(const char *name, size_t n);
  363. dyn_mailbox_t *chFactoryFindMailbox(const char *name);
  364. void chFactoryReleaseMailbox(dyn_mailbox_t *dmp);
  365. #endif
  366. #if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
  367. dyn_objects_fifo_t *chFactoryCreateObjectsFIFO(const char *name,
  368. size_t objsize,
  369. size_t objn,
  370. unsigned objalign);
  371. dyn_objects_fifo_t *chFactoryFindObjectsFIFO(const char *name);
  372. void chFactoryReleaseObjectsFIFO(dyn_objects_fifo_t *dofp);
  373. #endif
  374. #if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
  375. dyn_pipe_t *chFactoryCreatePipe(const char *name, size_t size);
  376. dyn_pipe_t *chFactoryFindPipe(const char *name);
  377. void chFactoryReleasePipe(dyn_pipe_t *dpp);
  378. #endif
  379. #ifdef __cplusplus
  380. }
  381. #endif
  382. /*===========================================================================*/
  383. /* Module inline functions. */
  384. /*===========================================================================*/
  385. /**
  386. * @brief Duplicates an object reference.
  387. * @note This function can be used on any kind of dynamic object.
  388. *
  389. * @param[in] dep pointer to the element field of the object
  390. * @return The duplicated object reference.
  391. *
  392. * @api
  393. */
  394. static inline dyn_element_t *chFactoryDuplicateReference(dyn_element_t *dep) {
  395. dep->refs++;
  396. return dep;
  397. }
  398. #if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
  399. /**
  400. * @brief Returns the pointer to the inner registered object.
  401. *
  402. * @param[in] rop registered object reference
  403. * @return The pointer to the registered object.
  404. *
  405. * @api
  406. */
  407. static inline void *chFactoryGetObject(registered_object_t *rop) {
  408. return rop->objp;
  409. }
  410. #endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
  411. #if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
  412. /**
  413. * @brief Returns the size of a generic dynamic buffer object.
  414. *
  415. * @param[in] dbp dynamic buffer object reference
  416. * @return The size of the buffer object in bytes.
  417. *
  418. * @api
  419. */
  420. static inline size_t chFactoryGetBufferSize(dyn_buffer_t *dbp) {
  421. return chHeapGetSize(dbp) - sizeof (dyn_element_t);
  422. }
  423. /**
  424. * @brief Returns the pointer to the inner buffer.
  425. *
  426. * @param[in] dbp dynamic buffer object reference
  427. * @return The pointer to the dynamic buffer.
  428. *
  429. * @api
  430. */
  431. static inline uint8_t *chFactoryGetBuffer(dyn_buffer_t *dbp) {
  432. return dbp->buffer;
  433. }
  434. #endif /* CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE */
  435. #if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
  436. /**
  437. * @brief Returns the pointer to the inner semaphore.
  438. *
  439. * @param[in] dsp dynamic semaphore object reference
  440. * @return The pointer to the semaphore.
  441. *
  442. * @api
  443. */
  444. static inline semaphore_t *chFactoryGetSemaphore(dyn_semaphore_t *dsp) {
  445. return &dsp->sem;
  446. }
  447. #endif /* CH_CFG_FACTORY_SEMAPHORES == TRUE */
  448. #if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
  449. /**
  450. * @brief Returns the pointer to the inner mailbox.
  451. *
  452. * @param[in] dmp dynamic mailbox object reference
  453. * @return The pointer to the mailbox.
  454. *
  455. * @api
  456. */
  457. static inline mailbox_t *chFactoryGetMailbox(dyn_mailbox_t *dmp) {
  458. return &dmp->mbx;
  459. }
  460. #endif /* CH_CFG_FACTORY_MAILBOXES == TRUE */
  461. #if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
  462. /**
  463. * @brief Returns the pointer to the inner objects FIFO.
  464. *
  465. * @param[in] dofp dynamic "objects FIFO" object reference
  466. * @return The pointer to the objects FIFO.
  467. *
  468. * @api
  469. */
  470. static inline objects_fifo_t *chFactoryGetObjectsFIFO(dyn_objects_fifo_t *dofp) {
  471. return &dofp->fifo;
  472. }
  473. #endif /* CH_CFG_FACTORY_OBJ_FIFOS == TRUE */
  474. #if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
  475. /**
  476. * @brief Returns the pointer to the inner pipe.
  477. *
  478. * @param[in] dpp dynamic pipe object reference
  479. * @return The pointer to the pipe.
  480. *
  481. * @api
  482. */
  483. static inline pipe_t *chFactoryGetPipe(dyn_pipe_t *dpp) {
  484. return &dpp->pipe;
  485. }
  486. #endif /* CH_CFG_FACTORY_PIPES == TRUE */
  487. #endif /* CH_CFG_USE_FACTORY == TRUE */
  488. #endif /* CHFACTORY_H */
  489. /** @} */