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