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