Explorar o código

device/pipe: add rt_pipe_{init,detach}

This provide the possibility that allocate the buffer of the ringbuffer
on a specific region, instead of always mallocing it. It also bring us
the benefit of using pipe device on the systems without heap.
Grissiom %!s(int64=11) %!d(string=hai) anos
pai
achega
38ce3879d8
Modificáronse 2 ficheiros con 71 adicións e 38 borrados
  1. 7 0
      components/drivers/include/rtdevice.h
  2. 64 38
      components/drivers/src/pipe.c

+ 7 - 0
components/drivers/include/rtdevice.h

@@ -172,8 +172,15 @@ rt_inline rt_uint16_t rt_ringbuffer_get_size(struct rt_ringbuffer *rb)
 /**
  * Pipe Device
  */
+rt_err_t rt_pipe_init(struct rt_pipe_device *pipe,
+                      const char *name,
+                      rt_uint8_t *buf,
+                      rt_size_t size);
+rt_err_t rt_pipe_detach(struct rt_pipe_device *pipe);
+#ifdef RT_USING_HEAP
 rt_err_t rt_pipe_create(const char *name, rt_size_t size);
 void rt_pipe_destroy(struct rt_pipe_device *pipe);
+#endif
 
 /**
  * DataQueue for DeviceDriver

+ 64 - 38
components/drivers/src/pipe.c

@@ -151,54 +151,79 @@ static rt_err_t rt_pipe_control(rt_device_t dev, rt_uint8_t cmd, void *args)
     return RT_EOK;
 }
 
+/**
+ * This function will initialize a pipe device and put it under control of
+ * resource management.
+ *
+ * @param pipe the pipe device
+ * @param name the name of pipe device
+ * @param buf  the buffer of pipe device
+ * @param size the size of pipe device buffer
+ *
+ * @return the operation status, RT_EOK on successful
+ */
+rt_err_t rt_pipe_init(struct rt_pipe_device *pipe,
+                      const char *name,
+                      rt_uint8_t *buf,
+                      rt_size_t size)
+{
+    RT_ASSERT(pipe);
+    RT_ASSERT(buf);
+
+    /* initialize suspended list */
+    rt_list_init(&pipe->suspended_read_list);
+    rt_list_init(&pipe->suspended_write_list);
+
+    /* initialize ring buffer */
+    rt_ringbuffer_init(&pipe->ringbuffer, buf, size);
+
+    /* create pipe */
+    pipe->parent.type    = RT_Device_Class_Char;
+    pipe->parent.init    = RT_NULL;
+    pipe->parent.open    = RT_NULL;
+    pipe->parent.close   = RT_NULL;
+    pipe->parent.read    = rt_pipe_read;
+    pipe->parent.write   = rt_pipe_write;
+    pipe->parent.control = rt_pipe_control;
+
+    return rt_device_register(&(pipe->parent), name, RT_DEVICE_FLAG_RDWR);
+}
+RTM_EXPORT(rt_pipe_init);
+
+/**
+ * This function will detach a pipe device from resource management
+ *
+ * @param pipe the pipe device
+ *
+ * @return the operation status, RT_EOK on successful
+ */
+rt_err_t rt_pipe_detach(struct rt_pipe_device *pipe)
+{
+    return rt_device_unregister(&pipe->parent);
+}
+RTM_EXPORT(rt_pipe_detach);
+
+#ifdef RT_USING_HEAP
 rt_err_t rt_pipe_create(const char *name, rt_size_t size)
 {
-    rt_err_t result = RT_EOK;
     rt_uint8_t *rb_memptr = RT_NULL;
     struct rt_pipe_device *pipe = RT_NULL;
 
     /* get aligned size */
     size = RT_ALIGN(size, RT_ALIGN_SIZE);
     pipe = (struct rt_pipe_device *)rt_calloc(1, sizeof(struct rt_pipe_device));
-    if (pipe != RT_NULL)
-    {
-        /* create ring buffer of pipe */
-        rb_memptr = rt_malloc(size);
-        if (rb_memptr == RT_NULL)
-        {
-            result = -RT_ENOMEM;
-            goto __exit;
-        }
-        /* initialize suspended list */
-        rt_list_init(&pipe->suspended_read_list);
-        rt_list_init(&pipe->suspended_write_list);
-
-        /* initialize ring buffer */
-        rt_ringbuffer_init(&pipe->ringbuffer, rb_memptr, size);
-
-        /* create device */
-        pipe->parent.type    = RT_Device_Class_Char;
-        pipe->parent.init    = RT_NULL;
-        pipe->parent.open    = RT_NULL;
-        pipe->parent.close   = RT_NULL;
-        pipe->parent.read    = rt_pipe_read;
-        pipe->parent.write   = rt_pipe_write;
-        pipe->parent.control = rt_pipe_control;
-
-        return rt_device_register(&(pipe->parent), name, RT_DEVICE_FLAG_RDWR);
-    }
-    else
-    {
-        result = -RT_ENOMEM;
-    }
+    if (pipe == RT_NULL)
+        return -RT_ENOMEM;
 
-__exit:
-    if (pipe != RT_NULL)
+    /* create ring buffer of pipe */
+    rb_memptr = rt_malloc(size);
+    if (rb_memptr == RT_NULL)
+    {
         rt_free(pipe);
-    if (rb_memptr != RT_NULL)
-        rt_free(rb_memptr);
+        return -RT_ENOMEM;
+    }
 
-    return result;
+    return rt_pipe_init(pipe, name, rb_memptr, size);
 }
 RTM_EXPORT(rt_pipe_create);
 
@@ -208,7 +233,7 @@ void rt_pipe_destroy(struct rt_pipe_device *pipe)
         return;
 
     /* un-register pipe device */
-    rt_device_unregister(&(pipe->parent));
+    rt_pipe_detach(pipe);
 
     /* release memory */
     rt_free(pipe->ringbuffer.buffer_ptr);
@@ -217,3 +242,4 @@ void rt_pipe_destroy(struct rt_pipe_device *pipe)
     return;
 }
 RTM_EXPORT(rt_pipe_destroy);
+#endif /* RT_USING_HEAP */