Browse Source

[Kernel] Add device_create/destroy api

Bernard Xiong 7 years ago
parent
commit
8ff8436fcd
5 changed files with 112 additions and 46 deletions
  1. 0 18
      include/rtdef.h
  2. 4 0
      include/rtthread.h
  3. 46 3
      src/device.c
  4. 5 19
      src/module.c
  5. 57 6
      src/object.c

+ 0 - 18
include/rtdef.h

@@ -359,34 +359,16 @@ typedef struct rt_object *rt_object_t;                  /**< Type for kernel obj
 enum rt_object_class_type
 {
     RT_Object_Class_Thread = 0,                         /**< The object is a thread. */
-#ifdef RT_USING_SEMAPHORE
     RT_Object_Class_Semaphore,                          /**< The object is a semaphore. */
-#endif
-#ifdef RT_USING_MUTEX
     RT_Object_Class_Mutex,                              /**< The object is a mutex. */
-#endif
-#ifdef RT_USING_EVENT
     RT_Object_Class_Event,                              /**< The object is a event. */
-#endif
-#ifdef RT_USING_MAILBOX
     RT_Object_Class_MailBox,                            /**< The object is a mail box. */
-#endif
-#ifdef RT_USING_MESSAGEQUEUE
     RT_Object_Class_MessageQueue,                       /**< The object is a message queue. */
-#endif
-#ifdef RT_USING_MEMHEAP
     RT_Object_Class_MemHeap,                            /**< The object is a memory heap */
-#endif
-#ifdef RT_USING_MEMPOOL
     RT_Object_Class_MemPool,                            /**< The object is a memory pool. */
-#endif
-#ifdef RT_USING_DEVICE
     RT_Object_Class_Device,                             /**< The object is a device */
-#endif
     RT_Object_Class_Timer,                              /**< The object is a timer. */
-#ifdef RT_USING_MODULE
     RT_Object_Class_Module,                             /**< The object is a module. */
-#endif
     RT_Object_Class_Unknown,                            /**< The object is unknown. */
     RT_Object_Class_Static = 0x80                       /**< The object is a static object. */
 };

+ 4 - 0
include/rtthread.h

@@ -409,6 +409,10 @@ rt_err_t rt_device_register(rt_device_t dev,
                             const char *name,
                             rt_uint16_t flags);
 rt_err_t rt_device_unregister(rt_device_t dev);
+
+rt_device_t rt_device_create(int type, int attach_size);
+void rt_device_destroy(rt_device_t device);
+
 rt_err_t rt_device_init_all(void);
 
 rt_err_t

+ 46 - 3
src/device.c

@@ -108,14 +108,13 @@ rt_device_t rt_device_find(const char *name)
     struct rt_list_node *node;
     struct rt_object_information *information;
 
-    extern struct rt_object_information rt_object_container[];
-
     /* enter critical */
     if (rt_thread_self() != RT_NULL)
         rt_enter_critical();
 
     /* try to find device object */
-    information = &rt_object_container[RT_Object_Class_Device];
+    information = rt_object_get_information(RT_Object_Class_Device);
+    RT_ASSERT(information != RT_NULL);
     for (node  = information->object_list.next;
          node != &(information->object_list);
          node  = node->next)
@@ -140,6 +139,50 @@ rt_device_t rt_device_find(const char *name)
 }
 RTM_EXPORT(rt_device_find);
 
+#ifdef RT_USING_HEAP
+/**
+ * This function creates a device object with user data size.
+ *
+ * @param type, the kind type of this device object.
+ * @param attach_size, the size of user data.
+ *
+ * @return the allocated device object, or RT_NULL when failed.
+ */
+rt_device_t rt_device_create(int type, int attach_size)
+{
+	int size;
+	rt_device_t device;
+
+	size = RT_ALIGN(sizeof(struct rt_device), RT_ALIGN_SIZE);
+	size += attach_size;
+
+	device = (rt_device_t)rt_malloc(size);
+	if (device)
+	{
+		rt_memset(device, 0x0, sizeof(struct rt_device));
+		device->type = type;
+	}
+
+	return device;
+}
+RTM_EXPORT(rt_device_create);
+
+/**
+ * This function destroy the specific device object.
+ *
+ * @param device, the specific device object.
+ */
+void rt_device_destroy(rt_device_t device)
+{
+	/* unregister device firstly */
+	rt_device_unregister(device);
+
+	/* release this device object */
+	rt_free(device);
+}
+RTM_EXPORT(rt_device_destroy);
+#endif
+
 /**
  * This function will initialize the specified device
  *

+ 5 - 19
src/module.c

@@ -299,66 +299,53 @@ void rt_module_init_object_container(struct rt_module *module)
 {
     RT_ASSERT(module != RT_NULL);
 
+    /* clear all of object information */
+    rt_memset(&module->module_object[0], 0x0, sizeof(module->module_object));
+
     /* initialize object container - thread */
     rt_list_init(&(module->module_object[RT_Object_Class_Thread].object_list));
     module->module_object[RT_Object_Class_Thread].object_size = sizeof(struct rt_thread);
     module->module_object[RT_Object_Class_Thread].type = RT_Object_Class_Thread;
 
-#ifdef RT_USING_SEMAPHORE
     /* initialize object container - semaphore */
     rt_list_init(&(module->module_object[RT_Object_Class_Semaphore].object_list));
     module->module_object[RT_Object_Class_Semaphore].object_size = sizeof(struct rt_semaphore);
     module->module_object[RT_Object_Class_Semaphore].type = RT_Object_Class_Semaphore;
-#endif
 
-#ifdef RT_USING_MUTEX
     /* initialize object container - mutex */
     rt_list_init(&(module->module_object[RT_Object_Class_Mutex].object_list));
     module->module_object[RT_Object_Class_Mutex].object_size = sizeof(struct rt_mutex);
     module->module_object[RT_Object_Class_Mutex].type = RT_Object_Class_Mutex;
-#endif
 
-#ifdef RT_USING_EVENT
     /* initialize object container - event */
     rt_list_init(&(module->module_object[RT_Object_Class_Event].object_list));
     module->module_object[RT_Object_Class_Event].object_size = sizeof(struct rt_event);
     module->module_object[RT_Object_Class_Event].type = RT_Object_Class_Event;
-#endif
 
-#ifdef RT_USING_MAILBOX
     /* initialize object container - mailbox */
     rt_list_init(&(module->module_object[RT_Object_Class_MailBox].object_list));
     module->module_object[RT_Object_Class_MailBox].object_size = sizeof(struct rt_mailbox);
     module->module_object[RT_Object_Class_MailBox].type = RT_Object_Class_MailBox;
-#endif
 
-#ifdef RT_USING_MESSAGEQUEUE
     /* initialize object container - message queue */
     rt_list_init(&(module->module_object[RT_Object_Class_MessageQueue].object_list));
     module->module_object[RT_Object_Class_MessageQueue].object_size = sizeof(struct rt_messagequeue);
     module->module_object[RT_Object_Class_MessageQueue].type = RT_Object_Class_MessageQueue;
-#endif
 
-#ifdef RT_USING_MEMHEAP
     /* initialize object container - memory heap */
     rt_list_init(&(module->module_object[RT_Object_Class_MemHeap].object_list));
     module->module_object[RT_Object_Class_MemHeap].object_size = sizeof(struct rt_memheap);
     module->module_object[RT_Object_Class_MemHeap].type = RT_Object_Class_MemHeap;
-#endif
 
-#ifdef RT_USING_MEMPOOL
     /* initialize object container - memory pool */
     rt_list_init(&(module->module_object[RT_Object_Class_MemPool].object_list));
     module->module_object[RT_Object_Class_MemPool].object_size = sizeof(struct rt_mempool);
     module->module_object[RT_Object_Class_MemPool].type = RT_Object_Class_MemPool;
-#endif
 
-#ifdef RT_USING_DEVICE
     /* initialize object container - device */
     rt_list_init(&(module->module_object[RT_Object_Class_Device].object_list));
     module->module_object[RT_Object_Class_Device].object_size = sizeof(struct rt_device);
     module->module_object[RT_Object_Class_Device].type = RT_Object_Class_Device;
-#endif
 
     /* initialize object container - timer */
     rt_list_init(&(module->module_object[RT_Object_Class_Timer].object_list));
@@ -1547,15 +1534,14 @@ rt_module_t rt_module_find(const char *name)
     struct rt_object *object;
     struct rt_list_node *node;
 
-    extern struct rt_object_information rt_object_container[];
-
     RT_DEBUG_NOT_IN_INTERRUPT;
 
     /* enter critical */
     rt_enter_critical();
 
     /* try to find device object */
-    information = &rt_object_container[RT_Object_Class_Module];
+    information = rt_object_get_information(RT_Object_Class_Module);
+    RT_ASSERT(information != RT_NULL);
     for (node = information->object_list.next;
          node != &(information->object_list);
          node = node->next)

+ 57 - 6
src/object.c

@@ -25,14 +25,52 @@
  * 2006-08-03     Bernard      add hook support
  * 2007-01-28     Bernard      rename RT_OBJECT_Class_Static to RT_Object_Class_Static
  * 2010-10-26     yi.qiu       add module support in rt_object_allocate and rt_object_free
+ * 2017-12-10     Bernard      Add object_info enum.
  */
 
 #include <rtthread.h>
 #include <rthw.h>
 
+/*
+ * define object_info for the number of rt_object_container items.
+ */
+enum rt_object_info_type
+{
+    RT_Object_Info_Thread = 0,                         /**< The object is a thread. */
+#ifdef RT_USING_SEMAPHORE
+    RT_Object_Info_Semaphore,                          /**< The object is a semaphore. */
+#endif
+#ifdef RT_USING_MUTEX
+    RT_Object_Info_Mutex,                              /**< The object is a mutex. */
+#endif
+#ifdef RT_USING_EVENT
+    RT_Object_Info_Event,                              /**< The object is a event. */
+#endif
+#ifdef RT_USING_MAILBOX
+    RT_Object_Info_MailBox,                            /**< The object is a mail box. */
+#endif
+#ifdef RT_USING_MESSAGEQUEUE
+    RT_Object_Info_MessageQueue,                       /**< The object is a message queue. */
+#endif
+#ifdef RT_USING_MEMHEAP
+    RT_Object_Info_MemHeap,                            /**< The object is a memory heap */
+#endif
+#ifdef RT_USING_MEMPOOL
+    RT_Object_Info_MemPool,                            /**< The object is a memory pool. */
+#endif
+#ifdef RT_USING_DEVICE
+    RT_Object_Info_Device,                             /**< The object is a device */
+#endif
+    RT_Object_Info_Timer,                              /**< The object is a timer. */
+#ifdef RT_USING_MODULE
+    RT_Object_Info_Module,                             /**< The object is a module. */
+#endif
+    RT_Object_Info_Unknown,                            /**< The object is unknown. */
+};
+
 #define _OBJ_CONTAINER_LIST_INIT(c)     \
     {&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)}
-struct rt_object_information rt_object_container[RT_Object_Class_Unknown] =
+static struct rt_object_information rt_object_container[RT_Object_Info_Unknown] =
 {
     /* initialize object container - thread */
     {RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Thread), sizeof(struct rt_thread)},
@@ -189,7 +227,12 @@ void rt_system_object_init(void)
 struct rt_object_information *
 rt_object_get_information(enum rt_object_class_type type)
 {
-    return &rt_object_container[type];
+    int index;
+    
+    for (index = 0; index < RT_Object_Info_Unknown; index ++)
+        if (rt_object_container[index].type == type) return &rt_object_container[index];
+        
+    return RT_NULL;
 }
 RTM_EXPORT(rt_object_get_information);
 
@@ -214,7 +257,8 @@ void rt_object_init(struct rt_object         *object,
                   &rt_module_self()->module_object[type] : &rt_object_container[type];
 #else
     /* get object information */
-    information = &rt_object_container[type];
+    information = rt_object_get_information(type);
+    RT_ASSERT(information != RT_NULL);
 #endif
 
     /* initialize object's parameters */
@@ -288,7 +332,8 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
                   &rt_module_self()->module_object[type] : &rt_object_container[type];
 #else
     /* get object information */
-    information = &rt_object_container[type];
+    information = rt_object_get_information(type);
+    RT_ASSERT(information != RT_NULL);
 #endif
 
     object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);
@@ -433,7 +478,9 @@ rt_object_t rt_object_find(const char *name, rt_uint8_t type)
             rt_enter_critical();
 
             /* find module */
-            information = &rt_object_container[RT_Object_Class_Module];
+            information = rt_object_get_information(RT_Object_Class_Module);
+            RT_ASSERT(information != RT_NULL);
+
             for (node = information->object_list.next;
                  node != &(information->object_list);
                  node  = node->next)
@@ -473,7 +520,11 @@ rt_object_t rt_object_find(const char *name, rt_uint8_t type)
     rt_enter_critical();
 
     /* try to find object */
-    if (information == RT_NULL) information = &rt_object_container[type];
+    if (information == RT_NULL)
+    {
+        information = rt_object_get_information(type);
+        RT_ASSERT(information != RT_NULL);
+    }
     for (node  = information->object_list.next;
          node != &(information->object_list);
          node  = node->next)