Factory enhanced.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10727 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
6568f70bd8
commit
76663a4a79
|
@ -48,11 +48,17 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables factory for generic objects.
|
* @brief Enables the registry of generic objects.
|
||||||
* @note Generic objects require the heap allocator.
|
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_CFG_FACTORY_GENERIC_BUFFER) || defined(__DOXYGEN__)
|
#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) || defined(__DOXYGEN__)
|
||||||
#define CH_CFG_FACTORY_GENERIC_BUFFER TRUE
|
#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables factory for generic buffers.
|
||||||
|
*/
|
||||||
|
#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) || defined(__DOXYGEN__)
|
||||||
|
#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,7 +76,7 @@
|
||||||
((CH_CFG_FACTORY_SEMAPHORES == TRUE))
|
((CH_CFG_FACTORY_SEMAPHORES == TRUE))
|
||||||
|
|
||||||
#define CH_FACTORY_REQUIRES_HEAP \
|
#define CH_FACTORY_REQUIRES_HEAP \
|
||||||
((CH_CFG_FACTORY_GENERIC_BUFFER == TRUE))
|
((CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE))
|
||||||
|
|
||||||
#if (CH_CFG_FACTORY_MAX_NAMES_LENGHT < 0) || \
|
#if (CH_CFG_FACTORY_MAX_NAMES_LENGHT < 0) || \
|
||||||
(CH_CFG_FACTORY_MAX_NAMES_LENGHT > 32)
|
(CH_CFG_FACTORY_MAX_NAMES_LENGHT > 32)
|
||||||
|
@ -123,17 +129,34 @@ typedef struct ch_dyn_list {
|
||||||
dyn_element_t *next;
|
dyn_element_t *next;
|
||||||
} dyn_list_t;
|
} dyn_list_t;
|
||||||
|
|
||||||
#if (CH_CFG_FACTORY_GENERIC_BUFFER == TRUE) || defined(__DOXIGEN__)
|
#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Type of a dynamic semaphore.
|
* @brief Type of a registered object.
|
||||||
*/
|
*/
|
||||||
typedef struct ch_dyn_object {
|
typedef struct ch_registered_static_object {
|
||||||
/**
|
/**
|
||||||
* @brief List element of the dynamic object.
|
* @brief List element of the registered object.
|
||||||
*/
|
*/
|
||||||
dyn_element_t element;
|
dyn_element_t element;
|
||||||
/**
|
/**
|
||||||
* @brief Physical objects.
|
* @brief Pointer to the object.
|
||||||
|
* @note The type of the object is not stored in anyway.
|
||||||
|
*/
|
||||||
|
void *objp;
|
||||||
|
} registered_object_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Type of a dynamic buffer object.
|
||||||
|
*/
|
||||||
|
typedef struct ch_dyn_object {
|
||||||
|
/**
|
||||||
|
* @brief List element of the dynamic buffer object.
|
||||||
|
*/
|
||||||
|
dyn_element_t element;
|
||||||
|
/**
|
||||||
|
* @brief Physical buffer objects.
|
||||||
* @note This requires C99.
|
* @note This requires C99.
|
||||||
*/
|
*/
|
||||||
uint8_t buffer[];
|
uint8_t buffer[];
|
||||||
|
@ -160,12 +183,20 @@ typedef struct ch_dyn_semaphore {
|
||||||
* @brief Type of the factory main object.
|
* @brief Type of the factory main object.
|
||||||
*/
|
*/
|
||||||
typedef struct ch_objects_factory {
|
typedef struct ch_objects_factory {
|
||||||
#if (CH_CFG_FACTORY_GENERIC_BUFFER == TRUE) || defined(__DOXIGEN__)
|
|
||||||
/**
|
/**
|
||||||
* @brief List of the allocated objects.
|
* @brief List of the registered objects.
|
||||||
*/
|
*/
|
||||||
dyn_list_t obj_list;
|
dyn_list_t obj_list;
|
||||||
#endif /* CH_CFG_FACTORY_GENERIC_BUFFER = TRUE */
|
/**
|
||||||
|
* @brief Pool of the available registered objects.
|
||||||
|
*/
|
||||||
|
memory_pool_t obj_pool;
|
||||||
|
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
|
||||||
|
/**
|
||||||
|
* @brief List of the allocated buffer objects.
|
||||||
|
*/
|
||||||
|
dyn_list_t buf_list;
|
||||||
|
#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS = TRUE */
|
||||||
#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
|
#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief List of the allocated semaphores.
|
* @brief List of the allocated semaphores.
|
||||||
|
@ -194,9 +225,13 @@ objects_factory_t ch_factory;
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void _factory_init(void);
|
void _factory_init(void);
|
||||||
// dyn_registered_object_t *chFactoryRegisterObject(const char *name,
|
#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__)
|
||||||
// void *objp);
|
registered_object_t *chFactoryRegisterObject(const char *name,
|
||||||
#if (CH_CFG_FACTORY_GENERIC_BUFFER == TRUE) || defined(__DOXIGEN__)
|
void *objp);
|
||||||
|
registered_object_t *chFactoryFindObject(const char *name);
|
||||||
|
void chFactoryReleaseObject(registered_object_t *rop);
|
||||||
|
#endif
|
||||||
|
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
|
||||||
dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size);
|
dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size);
|
||||||
dyn_buffer_t *chFactoryFindBuffer(const char *name);
|
dyn_buffer_t *chFactoryFindBuffer(const char *name);
|
||||||
void chFactoryReleaseBuffer(dyn_buffer_t *dbp);
|
void chFactoryReleaseBuffer(dyn_buffer_t *dbp);
|
||||||
|
@ -231,7 +266,7 @@ static inline dyn_element_t *chFactoryDuplicateReferenceI(dyn_element_t *dep) {
|
||||||
return dep;
|
return dep;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (CH_CFG_FACTORY_GENERIC_BUFFER == TRUE) || defined(__DOXIGEN__)
|
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Returns the size of a generic dynamic buffer object.
|
* @brief Returns the size of a generic dynamic buffer object.
|
||||||
*
|
*
|
||||||
|
|
|
@ -19,11 +19,12 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file chfactory.c
|
* @file chfactory.c
|
||||||
* @brief ChibiOS objects factory code.
|
* @brief ChibiOS objects factory and registry code.
|
||||||
*
|
*
|
||||||
* @addtogroup objects_factory
|
* @addtogroup objects_factory
|
||||||
* @details The object factory is a subsystem that allows to:
|
* @details The object factory is a subsystem that allows to:
|
||||||
* - Create objects and assign them a name.
|
* - Register static objects by name.
|
||||||
|
* - Dynamically create objects and assign them a name.
|
||||||
* - Retrieve existing objects by name.
|
* - Retrieve existing objects by name.
|
||||||
* - Free objects by reference.
|
* - Free objects by reference.
|
||||||
* .
|
* .
|
||||||
|
@ -77,7 +78,7 @@ static inline void dyn_list_init(dyn_list_t *dlp) {
|
||||||
dlp->next = (dyn_element_t *)dlp;
|
dlp->next = (dyn_element_t *)dlp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dyn_element_t *dyn_list_find(dyn_list_t *dlp, const char *name) {
|
static dyn_element_t *dyn_list_find(const char *name, dyn_list_t *dlp) {
|
||||||
dyn_element_t *p = dlp->next;
|
dyn_element_t *p = dlp->next;
|
||||||
|
|
||||||
while (p != (dyn_element_t *)dlp) {
|
while (p != (dyn_element_t *)dlp) {
|
||||||
|
@ -87,10 +88,13 @@ static dyn_element_t *dyn_list_find(dyn_list_t *dlp, const char *name) {
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chDbgAssert(true, "invalid reference passed");
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dyn_element_t *dyn_list_unlink(dyn_list_t *dlp, dyn_element_t *element) {
|
static dyn_element_t *dyn_list_unlink(dyn_element_t *element,
|
||||||
|
dyn_list_t *dlp) {
|
||||||
dyn_element_t *prev = (dyn_element_t *)dlp;
|
dyn_element_t *prev = (dyn_element_t *)dlp;
|
||||||
|
|
||||||
/* Scanning the list.*/
|
/* Scanning the list.*/
|
||||||
|
@ -108,6 +112,114 @@ static dyn_element_t *dyn_list_unlink(dyn_list_t *dlp, dyn_element_t *element) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (CH_FACTORY_REQUIRES_HEAP == TRUE) || defined(__DOXYGEN__)
|
||||||
|
static dyn_element_t *dyn_create_object_heap(const char *name,
|
||||||
|
dyn_list_t *dlp,
|
||||||
|
size_t size) {
|
||||||
|
dyn_element_t *dep;
|
||||||
|
|
||||||
|
chDbgCheck(name != NULL);
|
||||||
|
|
||||||
|
/* Checking if an object with this name has already been created.*/
|
||||||
|
dep = dyn_list_find(name, dlp);
|
||||||
|
if (dep != NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocating space for the new buffer object.*/
|
||||||
|
dep = (dyn_element_t *)chHeapAlloc(NULL, size);
|
||||||
|
if (dep) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initializing object list element.*/
|
||||||
|
strncpy(dep->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT);
|
||||||
|
dep->refs = 1U;
|
||||||
|
dep->next = dlp->next;
|
||||||
|
|
||||||
|
/* Updating factory list.*/
|
||||||
|
dlp->next = dep;
|
||||||
|
|
||||||
|
return dep;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dyn_release_object_heap(dyn_element_t *dep,
|
||||||
|
dyn_list_t *dlp) {
|
||||||
|
|
||||||
|
chDbgCheck(dep != NULL);
|
||||||
|
chDbgAssert(dep->refs > 0U, "invalid references number");
|
||||||
|
|
||||||
|
dep = dyn_list_unlink(dep, dlp);
|
||||||
|
|
||||||
|
dep->refs--;
|
||||||
|
if (dep->refs == 0U) {
|
||||||
|
chHeapFree((void *)dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CH_FACTORY_REQUIRES_HEAP == TRUE */
|
||||||
|
|
||||||
|
#if (CH_FACTORY_REQUIRES_POOLS == TRUE) || defined(__DOXYGEN__)
|
||||||
|
static dyn_element_t *dyn_create_object_pool(const char *name,
|
||||||
|
dyn_list_t *dlp,
|
||||||
|
memory_pool_t *mp) {
|
||||||
|
dyn_element_t *dep;
|
||||||
|
|
||||||
|
chDbgCheck(name != NULL);
|
||||||
|
|
||||||
|
/* Checking if an object object with this name has already been created.*/
|
||||||
|
dep = dyn_list_find(name, dlp);
|
||||||
|
if (dep != NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocating space for the new object.*/
|
||||||
|
dep = (dyn_element_t *)chPoolAlloc(mp);
|
||||||
|
if (dep == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initializing object list element.*/
|
||||||
|
strncpy(dep->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT);
|
||||||
|
dep->refs = 1U;
|
||||||
|
dep->next = ch_factory.sem_list.next;
|
||||||
|
|
||||||
|
/* Updating factory list.*/
|
||||||
|
dlp->next = (dyn_element_t *)dep;
|
||||||
|
|
||||||
|
return dep;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dyn_release_object_pool(dyn_element_t *dep,
|
||||||
|
dyn_list_t *dlp,
|
||||||
|
memory_pool_t *mp) {
|
||||||
|
|
||||||
|
chDbgCheck(dep != NULL);
|
||||||
|
chDbgAssert(dep->refs > 0U, "invalid references number");
|
||||||
|
|
||||||
|
dep = dyn_list_unlink(dep, dlp);
|
||||||
|
|
||||||
|
dep->refs--;
|
||||||
|
if (dep->refs == 0U) {
|
||||||
|
chPoolFree(mp, (void *)dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CH_FACTORY_REQUIRES_POOLS == TRUE */
|
||||||
|
|
||||||
|
static dyn_element_t *dyn_find_object(const char *name, dyn_list_t *dlp) {
|
||||||
|
dyn_element_t *dep;
|
||||||
|
|
||||||
|
chDbgCheck(name != NULL);
|
||||||
|
|
||||||
|
/* Checking if an object with this name has already been created.*/
|
||||||
|
dep = dyn_list_find(name, dlp);
|
||||||
|
if (dep != NULL) {
|
||||||
|
/* Increasing references counter.*/
|
||||||
|
dep->refs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dep;
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module exported functions. */
|
/* Module exported functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -119,8 +231,14 @@ static dyn_element_t *dyn_list_unlink(dyn_list_t *dlp, dyn_element_t *element) {
|
||||||
*/
|
*/
|
||||||
void _factory_init(void) {
|
void _factory_init(void) {
|
||||||
|
|
||||||
#if CH_CFG_FACTORY_GENERIC_BUFFER == TRUE
|
#if CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE
|
||||||
dyn_list_init(&ch_factory.obj_list);
|
dyn_list_init(&ch_factory.obj_list);
|
||||||
|
chPoolObjectInit(&ch_factory.obj_pool,
|
||||||
|
sizeof (registered_object_t),
|
||||||
|
chCoreAllocAlignedI);
|
||||||
|
#endif
|
||||||
|
#if CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE
|
||||||
|
dyn_list_init(&ch_factory.buf_list);
|
||||||
#endif
|
#endif
|
||||||
#if CH_CFG_FACTORY_SEMAPHORES == TRUE
|
#if CH_CFG_FACTORY_SEMAPHORES == TRUE
|
||||||
dyn_list_init(&ch_factory.sem_list);
|
dyn_list_init(&ch_factory.sem_list);
|
||||||
|
@ -130,88 +248,138 @@ void _factory_init(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (CH_CFG_FACTORY_GENERIC_BUFFER == TRUE) || defined(__DOXIGEN__)
|
#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Registers a generic object.
|
||||||
|
* @post A reference to the registered object is returned and the
|
||||||
|
* reference counter is initialized to one.
|
||||||
|
*
|
||||||
|
* @param[in] name name to be assigned to the registered object
|
||||||
|
* @param[in] objp pointer to the object to be registered
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
registered_object_t *chFactoryRegisterObject(const char *name,
|
||||||
|
void *objp) {
|
||||||
|
registered_object_t *rop;
|
||||||
|
|
||||||
|
chSysLock();
|
||||||
|
|
||||||
|
rop = (registered_object_t *)dyn_create_object_pool(name,
|
||||||
|
&ch_factory.obj_list,
|
||||||
|
&ch_factory.obj_pool);
|
||||||
|
if (rop != NULL) {
|
||||||
|
/* Initializing registered object data.*/
|
||||||
|
rop->objp = objp;
|
||||||
|
}
|
||||||
|
|
||||||
|
chSysUnlock();
|
||||||
|
|
||||||
|
return rop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves a registered object.
|
||||||
|
* @post A reference to the registered object is returned with the
|
||||||
|
* reference counter increased by one.
|
||||||
|
*
|
||||||
|
* @param[in] name name of the registered object
|
||||||
|
*
|
||||||
|
* @return The reference to the found registered object.
|
||||||
|
* @retval NULL if a registered object with the specified name
|
||||||
|
* does not exist.
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
registered_object_t *chFactoryFindObject(const char *name) {
|
||||||
|
registered_object_t *rop;
|
||||||
|
|
||||||
|
chSysLock();
|
||||||
|
|
||||||
|
rop = (registered_object_t *)dyn_find_object(name, &ch_factory.obj_list);
|
||||||
|
|
||||||
|
chSysUnlock();
|
||||||
|
|
||||||
|
return rop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Releases a registered object.
|
||||||
|
* @details The reference counter of the registered object is decreased
|
||||||
|
* by one, if reaches zero then the registered object memory
|
||||||
|
* is freed.
|
||||||
|
* @note The object itself is not freed, it could be static, only the
|
||||||
|
* allocated list element is freed.
|
||||||
|
*
|
||||||
|
* @param[in] rop registered object reference
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
void chFactoryReleaseObject(registered_object_t *rop){
|
||||||
|
|
||||||
|
chSysLock();
|
||||||
|
|
||||||
|
dyn_release_object_pool(&rop->element,
|
||||||
|
&ch_factory.obj_list,
|
||||||
|
&ch_factory.obj_pool);
|
||||||
|
|
||||||
|
chSysUnlock();
|
||||||
|
}
|
||||||
|
#endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
|
||||||
|
|
||||||
|
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Creates a generic dynamic buffer object.
|
* @brief Creates a generic dynamic buffer object.
|
||||||
* @post A reference to the buffer object is returned and the reference
|
* @post A reference to the dynamic buffer object is returned and the
|
||||||
* counter is initialized to one.
|
* reference counter is initialized to one.
|
||||||
* @post The buffer object is zero filled.
|
* @post The dynamic buffer object is filled with zeros.
|
||||||
*
|
*
|
||||||
* @param[in] name name to be assigned to the new buffer object
|
* @param[in] name name to be assigned to the new dynamic buffer object
|
||||||
* @param[in] size payload size of the buffer object to be created
|
* @param[in] size payload size of the dynamic buffer object to be created
|
||||||
*
|
*
|
||||||
* @return The reference to the created buffer object.
|
* @return The reference to the created dynamic buffer object.
|
||||||
* @retval NULL if the buffer object cannot be allocated or a buffer
|
* @retval NULL if the dynamic buffer object cannot be allocated or
|
||||||
* object with the same name exists.
|
* a dynamic buffer object with the same name exists.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size) {
|
dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size) {
|
||||||
dyn_buffer_t *dbp;
|
dyn_buffer_t *dbp;
|
||||||
|
|
||||||
chDbgCheck(name != NULL);
|
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
|
||||||
/* Checking if a buffer object with this name has already been created.*/
|
dbp = (dyn_buffer_t *)dyn_create_object_heap(name,
|
||||||
dbp = (dyn_buffer_t *)dyn_list_find(&ch_factory.obj_list, name);
|
&ch_factory.buf_list,
|
||||||
|
size);
|
||||||
if (dbp != NULL) {
|
if (dbp != NULL) {
|
||||||
/* Object exists, error.*/
|
/* Initializing buffer object data.*/
|
||||||
chSysUnlock();
|
memset((void *)dbp->buffer, 0, size);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocating space for the new buffer object.*/
|
|
||||||
dbp = chHeapAlloc(NULL, size);
|
|
||||||
if (dbp == NULL) {
|
|
||||||
chSysUnlock();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initializing buffer object data and metadata.*/
|
|
||||||
strncpy(dbp->element.name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT);
|
|
||||||
dbp->element.refs = 1;
|
|
||||||
dbp->element.next = ch_factory.obj_list.next;
|
|
||||||
memset((void *)dbp->buffer, 0, size);
|
|
||||||
|
|
||||||
/* Updating factory list.*/
|
|
||||||
ch_factory.obj_list.next = (dyn_element_t *)dbp;
|
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
|
||||||
return dbp;
|
return dbp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retrieves a generic dynamic buffer object.
|
* @brief Retrieves a dynamic buffer object.
|
||||||
* @post A reference to the buffer object is returned with the reference
|
* @post A reference to the dynamic buffer object is returned with the
|
||||||
* counter increased by one.
|
* reference counter increased by one.
|
||||||
*
|
*
|
||||||
* @param[in] name name to be assigned to the new buffer object
|
* @param[in] name name of the dynamic buffer object
|
||||||
*
|
*
|
||||||
* @return The reference to the found buffer object.
|
* @return The reference to the found dynamic buffer object.
|
||||||
* @retval NULL if a buffer object with the specified name name does
|
* @retval NULL if a dynamic buffer object with the specified name
|
||||||
* not exist.
|
* does not exist.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
dyn_buffer_t *chFactoryFindBuffer(const char *name) {
|
dyn_buffer_t *chFactoryFindBuffer(const char *name) {
|
||||||
dyn_buffer_t *dbp;
|
dyn_buffer_t *dbp;
|
||||||
|
|
||||||
chDbgCheck(name != NULL);
|
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
|
||||||
/* Checking if a buffer object with this name has already been created.*/
|
dbp = (dyn_buffer_t *)dyn_find_object(name, &ch_factory.buf_list);
|
||||||
dbp = (dyn_buffer_t *)dyn_list_find(&ch_factory.obj_list, name);
|
|
||||||
if (dbp == NULL) {
|
|
||||||
/* The buffer object does not exists, error.*/
|
|
||||||
chSysUnlock();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increasing references counter.*/
|
|
||||||
dbp->element.refs += 1;
|
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
|
||||||
|
@ -220,117 +388,77 @@ dyn_buffer_t *chFactoryFindBuffer(const char *name) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Releases a generic dynamic buffer object.
|
* @brief Releases a generic dynamic buffer object.
|
||||||
* @details The reference counter of the buffer object is decreased by one, if
|
* @details The reference counter of the dynamic buffer object is decreased
|
||||||
* reaches zero then the buffer object memory is freed.
|
* by one, if reaches zero then the dynamic buffer object memory
|
||||||
|
* is freed.
|
||||||
*
|
*
|
||||||
* @param[in] dbp generic buffer object reference
|
* @param[in] dbp dynamic buffer object reference
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void chFactoryReleaseBuffer(dyn_buffer_t *dbp) {
|
void chFactoryReleaseBuffer(dyn_buffer_t *dbp) {
|
||||||
|
|
||||||
chDbgCheck(dbp != NULL);
|
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
|
||||||
chDbgAssert(dbp->element.refs > 0U, "invalid references number");
|
dyn_release_object_heap(&dbp->element, &ch_factory.buf_list);
|
||||||
|
|
||||||
dbp = (dyn_buffer_t *)dyn_list_unlink(&ch_factory.obj_list,
|
|
||||||
&dbp->element);
|
|
||||||
|
|
||||||
chDbgAssert(dbp != NULL, "invalid reference passed");
|
|
||||||
|
|
||||||
dbp->element.refs--;
|
|
||||||
if (dbp->element.refs == 0) {
|
|
||||||
chHeapFree((void *)dbp);
|
|
||||||
}
|
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
#endif /* CH_CFG_FACTORY_GENERIC_BUFFER = TRUE */
|
#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS = TRUE */
|
||||||
|
|
||||||
#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
|
#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Creates a dynamic semaphore object.
|
* @brief Creates a dynamic semaphore object.
|
||||||
* @post A reference to the semaphore object is returned and the reference
|
* @post A reference to the dynamic semaphore object is returned and the
|
||||||
* counter is initialized to one.
|
* reference counter is initialized to one.
|
||||||
* @post The semaphore object is initialized and ready to use.
|
* @post The dynamic semaphore object is initialized and ready to use.
|
||||||
*
|
*
|
||||||
* @param[in] name name to be assigned to the new semaphore object
|
* @param[in] name name to be assigned to the new dynamic semaphore object
|
||||||
* @param[in] n semaphore object counter initialization value
|
* @param[in] n dynamic semaphore object counter initialization value
|
||||||
*
|
*
|
||||||
* @return The reference to the created semaphore object.
|
* @return The reference to the created dynamic semaphore object.
|
||||||
* @retval NULL if the semaphore object cannot be allocated or a
|
* @retval NULL if the dynamic semaphore object cannot be allocated or
|
||||||
* semaphore with the same name exists.
|
* a dynamic semaphore with the same name exists.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
dyn_semaphore_t *chFactoryCreateSemaphore(const char *name, cnt_t n) {
|
dyn_semaphore_t *chFactoryCreateSemaphore(const char *name, cnt_t n) {
|
||||||
dyn_semaphore_t *dsp;
|
dyn_semaphore_t *dsp;
|
||||||
|
|
||||||
chDbgCheck(name != NULL);
|
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
|
||||||
/* Checking if a semaphore object with this name has already been created.*/
|
dsp = (dyn_semaphore_t *)dyn_create_object_pool(name,
|
||||||
dsp = (dyn_semaphore_t *)dyn_list_find(&ch_factory.sem_list, name);
|
&ch_factory.sem_list,
|
||||||
|
&ch_factory.sem_pool);
|
||||||
if (dsp != NULL) {
|
if (dsp != NULL) {
|
||||||
/* The semaphore object exists, error.*/
|
/* Initializing semaphore object dataa.*/
|
||||||
chSysUnlock();
|
chSemObjectInit(&dsp->sem, n);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocating space for the new semaphore object.*/
|
|
||||||
dsp = chCoreAlloc(sizeof (dyn_semaphore_t));
|
|
||||||
if (dsp == NULL) {
|
|
||||||
chSysUnlock();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initializing semaphore object data and metadata.*/
|
|
||||||
strncpy(dsp->element.name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT);
|
|
||||||
dsp->element.refs = 1;
|
|
||||||
dsp->element.next = ch_factory.obj_list.next;
|
|
||||||
chSemObjectInit(&dsp->sem, n);
|
|
||||||
|
|
||||||
/* Updating factory list.*/
|
|
||||||
ch_factory.obj_list.next = (dyn_element_t *)dsp;
|
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
|
||||||
return dsp;
|
return dsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retrieves a generic dynamic semaphore object.
|
* @brief Retrieves a dynamic semaphore object.
|
||||||
* @post A reference to the semaphore object is returned with the reference
|
* @post A reference to the dynamic semaphore object is returned with the
|
||||||
* counter increased by one.
|
* reference counter increased by one.
|
||||||
*
|
*
|
||||||
* @param[in] name name to be assigned to the new semaphore object
|
* @param[in] name name of the dynamic semaphore object
|
||||||
*
|
*
|
||||||
* @return The reference to the found semaphore object.
|
* @return The reference to the found dynamic semaphore object.
|
||||||
* @retval NULL if a semaphore object with the specified name name does
|
* @retval NULL if a dynamic semaphore object with the specified name
|
||||||
* not exist.
|
* does not exist.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
dyn_semaphore_t *chFactoryFindSemaphore(const char *name) {
|
dyn_semaphore_t *chFactoryFindSemaphore(const char *name) {
|
||||||
dyn_semaphore_t *dsp;
|
dyn_semaphore_t *dsp;
|
||||||
|
|
||||||
chDbgCheck(name != NULL);
|
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
|
||||||
/* Checking if a semaphore object with this name has already been created.*/
|
dsp = (dyn_semaphore_t *)dyn_find_object(name, &ch_factory.sem_list);
|
||||||
dsp = (dyn_semaphore_t *)dyn_list_find(&ch_factory.obj_list, name);
|
|
||||||
if (dsp == NULL) {
|
|
||||||
/* The semaphore object does not exists, error.*/
|
|
||||||
chSysUnlock();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increasing references counter.*/
|
|
||||||
dsp->element.refs += 1;
|
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
|
||||||
|
@ -338,31 +466,22 @@ dyn_semaphore_t *chFactoryFindSemaphore(const char *name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Releases a semaphore dynamic object.
|
* @brief Releases a dynamic semaphore object.
|
||||||
* @details The reference counter of the semaphore object is decreased by one,
|
* @details The reference counter of the dynamic semaphore object is decreased
|
||||||
* if reaches zero then the semaphore object memory is freed.
|
* by one, if reaches zero then the dynamic semaphore object memory
|
||||||
|
* is freed.
|
||||||
*
|
*
|
||||||
* @param[in] dsp semaphore object reference
|
* @param[in] dsp dynamic semaphore object reference
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp) {
|
void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp) {
|
||||||
|
|
||||||
chDbgCheck(dsp != NULL);
|
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
|
||||||
chDbgAssert(dsp->element.refs > 0U, "invalid references number");
|
dyn_release_object_pool(&dsp->element,
|
||||||
|
&ch_factory.sem_list,
|
||||||
dsp = (dyn_semaphore_t *)dyn_list_unlink(&ch_factory.sem_list,
|
&ch_factory.sem_pool);
|
||||||
&dsp->element);
|
|
||||||
|
|
||||||
chDbgAssert(dsp != NULL, "invalid reference passed");
|
|
||||||
|
|
||||||
dsp->element.refs--;
|
|
||||||
if (dsp->element.refs == 0) {
|
|
||||||
chPoolFree(&ch_factory.sem_pool, (void *)dsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,9 @@ endif
|
||||||
ifneq ($(findstring CH_CFG_USE_MEMPOOLS TRUE,$(CHCONF)),)
|
ifneq ($(findstring CH_CFG_USE_MEMPOOLS TRUE,$(CHCONF)),)
|
||||||
KERNSRC += $(CHIBIOS)/os/common/oslib/src/chmempools.c
|
KERNSRC += $(CHIBIOS)/os/common/oslib/src/chmempools.c
|
||||||
endif
|
endif
|
||||||
|
ifneq ($(findstring CH_CFG_USE_FACTORY TRUE,$(CHCONF)),)
|
||||||
|
KERNSRC += $(CHIBIOS)/os/common/oslib/src/chfactory.c
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
KERNSRC := $(CHIBIOS)/os/rt/src/chsys.c \
|
KERNSRC := $(CHIBIOS)/os/rt/src/chsys.c \
|
||||||
$(CHIBIOS)/os/rt/src/chdebug.c \
|
$(CHIBIOS)/os/rt/src/chdebug.c \
|
||||||
|
|
Loading…
Reference in New Issue