aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2017-09-25 15:11:41 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2017-09-25 15:11:41 +0000
commit590df48760ecc9e9a146c5bd52b91c47489d4e99 (patch)
tree535f51b32abda69a03dfc87cf0f545a20fcf1bed
parenteae327a32e0512f35c15933753f4e65e6b7c4d9f (diff)
downloadChibiOS-590df48760ecc9e9a146c5bd52b91c47489d4e99.tar.gz
ChibiOS-590df48760ecc9e9a146c5bd52b91c47489d4e99.tar.bz2
ChibiOS-590df48760ecc9e9a146c5bd52b91c47489d4e99.zip
OS objects factory, work in progress.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10711 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--os/common/oslib/include/chfactory.h220
-rw-r--r--os/common/oslib/src/chfactory.c192
2 files changed, 412 insertions, 0 deletions
diff --git a/os/common/oslib/include/chfactory.h b/os/common/oslib/include/chfactory.h
new file mode 100644
index 000000000..d8cd20a22
--- /dev/null
+++ b/os/common/oslib/include/chfactory.h
@@ -0,0 +1,220 @@
+/*
+ ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio.
+
+ This file is part of ChibiOS.
+
+ ChibiOS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chfactory.h
+ * @brief ChibiOS objects factory structures and macros.
+ *
+ * @addtogroup objects_factory
+ * @{
+ */
+
+#ifndef CHFACTORY_H
+#define CHFACTORY_H
+
+#if (CH_CFG_USE_FACTORY == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Maximum length for object names.
+ * @details If the specified length is zero then the name is stored by
+ * pointer but this could have unintended side effects.
+ */
+#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGHT) || defined(__DOXYGEN__)
+#define CH_CFG_FACTORY_MAX_NAMES_LENGHT 8
+#endif
+
+/**
+ * @brief Enables factory for generic objects.
+ * @note Generic objects require the heap allocator.
+ */
+#if !defined(CH_CFG_FACTORY_GENERIC) || defined(__DOXYGEN__)
+#define CH_CFG_FACTORY_GENERIC TRUE
+#endif
+
+/**
+ * @brief Enables factory for semaphores.
+ */
+#if !defined(CH_CFG_FACTORY_SEMAPHORES) || defined(__DOXYGEN__)
+#define CH_CFG_FACTORY_SEMAPHORES TRUE
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#define CH_FACTORY_REQUIRES_POOLS \
+ ((CH_CFG_FACTORY_SEMAPHORES == TRUE))
+
+#define CH_FACTORY_REQUIRES_HEAP \
+ ((CH_CFG_FACTORY_GENERIC == TRUE))
+
+#if (CH_CFG_FACTORY_MAX_NAMES_LENGHT < 0) || \
+ (CH_CFG_FACTORY_MAX_NAMES_LENGHT > 32)
+#error "invalid CH_CFG_FACTORY_MAX_NAMES_LENGHT value"
+#endif
+
+#if CH_CFG_USE_MEMCORE == FALSE
+#error "CH_CFG_USE_FACTORY requires CH_CFG_USE_MEMCORE"
+#endif
+
+#if (CH_FACTORY_REQUIRES_POOLS == TRUE) && (CH_CFG_USE_MEMPOOLS == FALSE)
+#error "CH_CFG_USE_MEMPOOLS is required"
+#endif
+
+#if (CH_FACTORY_REQUIRES_HEAP == TRUE) && (CH_CFG_USE_HEAP == FALSE)
+#error "CH_CFG_USE_HEAP is required"
+#endif
+
+#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) && (CH_CFG_USE_SEMAPHORES == FALSE)
+#error "CH_CFG_FACTORY_SEMAPHORES requires CH_CFG_USE_SEMAPHORES"
+#endif
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a dynamic object list element.
+ */
+typedef struct ch_dyn_element {
+ /**
+ * @brief Next dynamic object in the list.
+ */
+ struct ch_dyn_element *next;
+ /**
+ * @brief Number of references to this object.
+ */
+ ucnt_t refs;
+#if (CH_CFG_FACTORY_MAX_NAMES_LENGHT > 0) || defined(__DOXIGEN__)
+ char name[CH_CFG_FACTORY_MAX_NAMES_LENGHT];
+#else
+ const char *name;
+#endif
+} dyn_element_t;
+
+/**
+ * @brief Type of a dynamic object list.
+ */
+typedef struct ch_dyn_list {
+ dyn_element_t *next;
+} dyn_list_t;
+
+#if (CH_CFG_FACTORY_GENERIC == TRUE) || defined(__DOXIGEN__)
+/**
+ * @brief Type of a dynamic semaphore.
+ */
+typedef struct ch_dyn_object {
+ /**
+ * @brief List element of the dynamic object.
+ */
+ dyn_element_t list;
+ /**
+ * @brief Physical objects.
+ * @note This requires C99.
+ */
+ uint8_t obj[];
+} dyn_object_t;
+#endif
+
+#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
+/**
+ * @brief Type of a dynamic semaphore.
+ */
+typedef struct ch_dyn_semaphore {
+ /**
+ * @brief List element of the dynamic semaphore.
+ */
+ dyn_element_t list;
+ /**
+ * @brief Physical semaphore.
+ */
+ semaphore_t sem;
+} dyn_semaphore_t;
+#endif
+
+/**
+ * @brief Type of the factory main object.
+ */
+typedef struct ch_objects_factory {
+#if (CH_CFG_FACTORY_GENERIC == TRUE) || defined(__DOXIGEN__)
+ /**
+ * @brief List of the allocated objects.
+ */
+ dyn_list_t obj_list;
+#endif /* CH_CFG_FACTORY_GENERIC = TRUE */
+#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
+ /**
+ * @brief List of the allocated semaphores.
+ */
+ dyn_list_t sem_list;
+ /**
+ * @brief Pool of the available semaphores.
+ */
+ memory_pool_t sem_pool;
+#endif /* CH_CFG_FACTORY_SEMAPHORES = TRUE */
+} objects_factory_t;
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+objects_factory_t ch_factory;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _factory_init(void);
+#if (CH_CFG_FACTORY_GENERIC == TRUE) || defined(__DOXIGEN__)
+ dyn_object_t *chFactoryCreateObject(const char *name, size_t size);
+ dyn_object_t *chFactoryFindObject(const char *name);
+ void chFactoryReleaseObject(dyn_object_t *dop);
+ size_t chFactoryGetObjectSize(dyn_object_t *dop);
+#endif
+#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
+ dyn_semaphore_t *chFactoryCreateSemaphore(const char *name, cnt_t n);
+ dyn_semaphore_t *chFactoryFindSemaphore(const char *name);
+ void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+#endif /* CH_CFG_USE_FACTORY == TRUE */
+
+#endif /* CHFACTORY_H */
+
+/** @} */
diff --git a/os/common/oslib/src/chfactory.c b/os/common/oslib/src/chfactory.c
new file mode 100644
index 000000000..7e8d3a273
--- /dev/null
+++ b/os/common/oslib/src/chfactory.c
@@ -0,0 +1,192 @@
+/*
+ ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio.
+
+ This file is part of ChibiOS.
+
+ ChibiOS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chfactory.c
+ * @brief ChibiOS objects factory code.
+ *
+ * @addtogroup objects_factory
+ * @details The object factory is a subsystem that allows to:
+ * - Create objects and assign them a name.
+ * - Retrieve existing objects by name.
+ * - Free objects by reference.
+ * .
+ * Allocated OS objects are handled using a reference counter, only
+ * when all references have been released then the object memory is
+ * freed in a pool.<br>
+ * @pre This subsystem requires the @p CH_CFG_USE_MEMCORE and
+ * @p CH_CFG_USE_MEMPOOLS options to be set to @p TRUE. The
+ * option @p CH_CFG_USE_HEAP is also required if the support
+ * for variable length objects is enabled.
+ * @note Compatible with RT and NIL.
+ * @{
+ */
+
+#include <string.h>
+
+#include "ch.h"
+#include "chfactory.h"
+
+#if (CH_CFG_USE_FACTORY == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief Factory object static instance.
+ * @note It is a global object because it could be accessed through
+ * a specific debugger plugin.
+ */
+objects_factory_t ch_factory;
+
+/*===========================================================================*/
+/* Module local types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local functions. */
+/*===========================================================================*/
+
+static inline void dyn_list_init(dyn_list_t *dlp) {
+
+ dlp->next = (dyn_element_t *)dlp;
+}
+
+static dyn_element_t *dyn_list_find(dyn_list_t *dlp, const char *name) {
+ dyn_element_t *p = dlp->next;
+
+ while (p != (dyn_element_t *)dlp) {
+ if (strncmp(p->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT) == 0) {
+ return p;
+ }
+ p = p->next;
+ }
+
+ return NULL;
+}
+
+/*===========================================================================*/
+/* Module exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Initializes the objects factory.
+ *
+ * @init
+ */
+void _factory_init(void) {
+
+#if CH_CFG_FACTORY_GENERIC == TRUE
+ dyn_list_init(&ch_factory.obj_list);
+#endif
+#if CH_CFG_FACTORY_SEMAPHORES == TRUE
+ dyn_list_init(&ch_factory.sem_list);
+ chPoolObjectInit(&ch_factory.sem_pool,
+ sizeof (dyn_semaphore_t),
+ chCoreAllocAlignedI);
+#endif
+}
+
+#if (CH_CFG_FACTORY_GENERIC == TRUE) || defined(__DOXIGEN__)
+/**
+ * @brief Allocates a generic dynamic object.
+ * @post A reference to the object is returned and the reference counter
+ * is initialized to one.
+ * @post The object is zero filled.
+ *
+ * @param[in] name name to be assigned to the new object
+ * @param[in] size payload size of the object to be created
+ *
+ * @return The reference to the created object.
+ * @retval NULL if the object cannot be allocated or an object with
+ * the same name exists.
+ */
+dyn_object_t *chFactoryCreateObject(const char *name, size_t size) {
+ dyn_object_t *dop;
+
+ chSysLock();
+
+ /* Checking if an object with this name has already been created.*/
+ dop = (dyn_object_t *)dyn_list_find(&ch_factory.obj_list, name);
+ if (dop != NULL) {
+ /* Object exists, error.*/
+ chSysUnlock();
+ return NULL;
+ }
+
+ dop = chHeapAlloc(NULL, size);
+ if (dop == NULL) {
+ chSysUnlock();
+ return NULL;
+ }
+
+ /* Initializing object data and metadata.*/
+ strncpy(&dop->list.name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT);
+ dop->list.refs = 1;
+ dop->list.next = ch_factory.obj_list.next;
+ memset((void *)dop->obj, 0, size);
+
+ /* Updating factory list.*/
+ ch_factory.obj_list.next = dop;
+
+ chSysUnlock();
+
+ return dop;
+}
+
+dyn_object_t *chFactoryFindObject(const char *name) {
+
+}
+
+void chFactoryReleaseObject(dyn_object_t *dop) {
+
+}
+
+size_t chFactoryGetObjectSize(dyn_object_t *dop) {
+
+ return chHeapGetSize((void *)dop);
+}
+#endif /* CH_CFG_FACTORY_GENERIC = TRUE */
+
+#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
+dyn_semaphore_t *chFactoryCreateSemaphore(const char *name, cnt_t n) {
+
+}
+
+dyn_semaphore_t *chFactoryFindSemaphore(const char *name) {
+
+}
+
+void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp) {
+
+}
+#endif /* CH_CFG_FACTORY_SEMAPHORES = TRUE */
+
+#endif /* CH_CFG_USE_FACTORY == TRUE */
+
+/** @} */