瀏覽代碼

ptmx/pts基本正常运行

shaojinchun 4 年之前
父節點
當前提交
7876c20d86
共有 3 個文件被更改,包括 469 次插入440 次删除
  1. 223 202
      components/lwp/unix98pty/lwp_ptmx.c
  2. 204 199
      components/lwp/unix98pty/lwp_pts.c
  3. 42 39
      components/lwp/unix98pty/lwp_pty.h

+ 223 - 202
components/lwp/unix98pty/lwp_ptmx.c

@@ -5,7 +5,7 @@
 */
 #include "lwp_pty.h"
 
-static struct rt_ptmx_device ptmx, *_ptmx = &ptmx; 
+static struct rt_ptmx_device ptmx, *_ptmx = &ptmx;
 
 rt_inline struct rt_wqueue *ptmx_get_wq(struct rt_lwp *lwp)
 {
@@ -16,144 +16,195 @@ rt_inline struct rt_wqueue *ptmx_get_wq(struct rt_lwp *lwp)
     return &lwp->wait_queue;
 }
 
-/* 查找空闲 pts 设备 */ 
+/* 查找空闲 pts 设备 */
 static struct rt_pts_device *find_freepts(void)
 {
-    struct rt_pts_device *pts = RT_NULL; 
     for(int i = 0; i < LWP_PTY_PTS_SIZE; i++)
     {
-        struct rt_pts_device *_pts = RT_NULL; 
-        _pts = &_ptmx->pts[i]; 
-        if(_pts->flags == PTY_INIT_FLAG_NONE)
+        if (_ptmx->pts[i].flags == PTY_INIT_FLAG_NONE)
         {
-            pts = _pts; 
+            _ptmx->pts[i].flags = PTY_INIT_FLAG_ALLOCED;
+            return &_ptmx->pts[i];
         }
     }
-
-    return pts; 
+    return RT_NULL;
 }
 
-/* 通过 fd(ptmx) 获取 pts 设备句柄 */  
+/* 通过 fd(ptmx) 获取 pts 设备句柄 */
 static struct rt_pts_device *ptmxfd2pts(struct dfs_fd *fd)
 {
-    int ptmx_fd = -1; 
-    struct rt_pts_device *pts = RT_NULL; 
+    int ptmx_fd;
 
-    ptmx_fd = fd_get_fd_index(fd); 
+    ptmx_fd = fd_get_fd_index(fd);
     for(int i = 0; i < LWP_PTY_PTS_SIZE; i++)
     {
-        struct rt_pts_device *_pts = RT_NULL; 
-        _pts = &_ptmx->pts[i]; 
-        if(_pts->ptmx_fd == ptmx_fd)
+        if (_ptmx->pts[i].flags != PTY_INIT_FLAG_NONE)
         {
-            pts = _pts; 
+            if (_ptmx->pts[i].ptmx_fd == ptmx_fd)
+            {
+                return &_ptmx->pts[i];
+            }
         }
     }
+    return RT_NULL;
+}
+
+static rt_size_t ptmx_read(struct rt_pts_device *pts, rt_off_t pos, void *buffer, rt_size_t size)
+{
+    rt_base_t level = 0;
+    rt_size_t len = 0;
+
+    level = rt_hw_interrupt_disable();
+    if (size)
+    {
+        len = rt_ringbuffer_data_len(&pts->srb);
+        if (len > size)
+        {
+            len = size;
+        }
+        if (len)
+        {
+            len = rt_ringbuffer_get(&pts->srb, buffer, len);
+        }
+    }
+    rt_hw_interrupt_enable(level);
+
+    return len;
+}
+
+static rt_size_t ptmx_write(struct rt_pts_device *pts, rt_off_t pos, const void *buffer, rt_size_t count)
+{
+    rt_base_t level = 0;
+    rt_size_t size = 0;
+
+    if (*(char *)buffer == '\r')
+    {
+        *(char *)buffer = '\n';
+    }
+
+    level = rt_hw_interrupt_disable();
+    size = lwp_pts_push_mrb(pts, (void *)buffer, count);
+    rt_hw_interrupt_enable(level);
 
-    return pts; 
+    return size;
 }
 
 static int ptmx_file_open(struct dfs_fd *fd)
 {
     rt_base_t level = 0;
-    int ret = 0; 
-    struct rt_ptmx_device *ptmx = LWP_PTY_GET_PTMX(fd); 
-    struct rt_pts_device *pts = RT_NULL; 
-    int ptmx_fd = -1; 
+    int ret = -1;
+    struct rt_ptmx_device *ptmx = LWP_PTY_GET_PTMX(fd);
+    struct rt_pts_device *pts = RT_NULL;
+    int ptmx_fd = -1;
     struct rt_device *device = RT_NULL;
+    struct rt_lwp *lwp = RT_NULL;
+    struct rt_wqueue *wq = RT_NULL;
 
-    level = rt_hw_interrupt_disable(); 
+    level = rt_hw_interrupt_disable();
 
-    pts = find_freepts(); 
-    if(pts == RT_NULL)
+    pts = find_freepts();
+    if (pts == RT_NULL)
     {
-        LOG_E("no pts device, maximum number is %d", LWP_PTY_PTS_SIZE); 
-        ret = (-ENODEV); 
-        goto _exit; 
+        LOG_E("no pts device, maximum number is %d", LWP_PTY_PTS_SIZE);
+        ret = (-ENODEV);
+        goto _exit;
     }
 
-    /* 注册 pts 设备 */ 
-    ptmx_fd = fd_get_fd_index(fd); 
-    ret = lwp_pts_register(pts, ptmx_fd, ptmx->pts_index); 
-    if(ret != RT_EOK)
+    /* 注册 pts 设备 */
+    ptmx_fd = fd_get_fd_index(fd);
+    if (ptmx_fd < 0)
     {
-        LOG_E("register pts%d fail", ptmx->pts_index); 
-        ret = (-EIO); 
-        goto _exit; 
+        pts->flags = PTY_INIT_FLAG_NONE; /* free pts */
+    }
+    ret = lwp_pts_register(pts, ptmx_fd, ptmx->pts_index);
+    if (ret != RT_EOK)
+    {
+        fd_release(ptmx_fd);
+        pts->flags = PTY_INIT_FLAG_NONE; /* free pts */
+        LOG_E("register pts%d fail", ptmx->pts_index);
+        ret = (-EIO);
+        goto _exit;
     }
 
-    /* 打开设备 */ 
-    device = (struct rt_device *)fd->fnode->data; 
+    /* 打开设备 */
+    device = (struct rt_device *)fd->fnode->data;
     if (fd->fnode->ref_count == 1)
     {
         ret = rt_device_open(device, fd->flags);
+        RT_ASSERT(ret == 0);
     }
 
-    pts->ptmx_fd = ptmx_fd; 
-    ptmx->pts_index++; 
+    lwp = (struct rt_lwp *)(rt_thread_self()->lwp);
+    wq = ptmx_get_wq(lwp);
+    pts->swq = wq; /* 将当前等待队列设置到 pts 中,用于 ptmx 写数据后唤醒 lwp 读数据 */
+    pts->ptmx_fd = ptmx_fd;
+    ptmx->pts_index++;
+
+    ret = 0;
 
-_exit: 
-    rt_hw_interrupt_enable(level); 
-    return 0; 
+_exit:
+    rt_hw_interrupt_enable(level);
+    return ret;
 }
 
 static int ptmx_file_close(struct dfs_fd *fd)
 {
     rt_base_t level = 0;
-    int ret = 0; 
+    int ret = 0;
     struct rt_device *device = RT_NULL;
-    
-    level = rt_hw_interrupt_disable(); 
-    if(fd->fnode->ref_count == 1)
-    { 
+    struct rt_pts_device *pts = RT_NULL;
+
+    level = rt_hw_interrupt_disable();
+    if (fd->fnode->ref_count == 1)
+    {
+        pts = ptmxfd2pts(fd);
+        if (pts && pts->mwq)
+        {
+            pts->ptmx_fd = RT_NULL;
+            rt_wqueue_wakeup(pts->mwq, (void*)POLLIN);
+        }
         device = (struct rt_device *)fd->fnode->data;
         ret = rt_device_close(device);
     }
-    rt_hw_interrupt_enable(level); 
+    rt_hw_interrupt_enable(level);
 
-    return ret; 
+    return ret;
 }
 
 static int ptmx_file_read(struct dfs_fd *fd, void *buf, size_t count)
 {
     rt_base_t level = 0;
     size_t size = 0;
-    struct rt_ptmx_device *ptmx = LWP_PTY_GET_PTMX(fd); 
-    struct rt_pts_device *pts = ptmxfd2pts(fd); 
-    struct rt_lwp *lwp = RT_NULL;
-    struct rt_wqueue *wq = RT_NULL;
+    struct rt_pts_device *pts = RT_NULL;
     int wait_ret = 0;
 
     level = rt_hw_interrupt_disable();
 
-    lwp = (struct rt_lwp *)(rt_thread_self()->lwp);
-    wq = ptmx_get_wq(lwp); 
-
-    while(count)
+    pts = ptmxfd2pts(fd);
+    if (pts)
     {
-        ptmx->parent.user_data = (void *)pts; 
-        size = rt_device_read(&ptmx->parent, -1, buf, count);
-        ptmx->parent.user_data = RT_NULL; 
-        if (size > 0)
+        while (count)
         {
-            break;
+            size = ptmx_read(pts, -1, buf, count);
+            if (size > 0)
+            {
+                break;
+            }
+
+            if (fd->flags & O_NONBLOCK)
+            {
+                break;
+            }
+
+            /* 当直接读的时候,没有数据就挂起,等待 ptmx 写入数据后唤醒 */
+            wait_ret = rt_wqueue_wait_interruptible(pts->swq, 0, RT_WAITING_FOREVER);
+            if (wait_ret != 0)
+            {
+                break;
+            }
         }
 
-        if (fd->flags & O_NONBLOCK)
-        {
-            break;
-        }
-
-        /* 当直接读的时候,没有数据就挂起,等待 ptmx 写入数据后唤醒 */ 
-        pts->swq = wq; /* 将当前lwp的等待队列设置到 pts 中,用于 ptmx 写数据后唤醒 lwp 读数据 */ 
-        wait_ret = rt_wqueue_wait_interruptible(wq, 0, RT_WAITING_FOREVER);
-        pts->swq = RT_NULL; /* 清空 */  
-        if (wait_ret != 0)
-        {
-            break;
-        }
     }
-
     rt_hw_interrupt_enable(level);
 
     if (size < 0)
@@ -161,205 +212,175 @@ static int ptmx_file_read(struct dfs_fd *fd, void *buf, size_t count)
         size = 0;
     }
 
-    return size; 
+    return size;
 }
 
 static int ptmx_file_write(struct dfs_fd *fd, const void *buf, size_t count)
 {
     int size = 0;
-    struct rt_device *device = RT_NULL;
-    struct rt_pts_device *pts = RT_NULL; 
+    struct rt_pts_device *pts = RT_NULL;
     rt_base_t level = 0;
-    level = rt_hw_interrupt_disable(); 
-    device = (struct rt_device *)fd->fnode->data;
-    RT_ASSERT(device != RT_NULL);
-    pts = ptmxfd2pts(fd); 
-    RT_ASSERT(pts != RT_NULL);
-    device->user_data = (void *)pts; 
-    size = rt_device_write(device, -1, buf, count);
-    device->user_data = RT_NULL; 
-    rt_hw_interrupt_enable(level); 
+
+    level = rt_hw_interrupt_disable();
+
+    pts = ptmxfd2pts(fd);
+    if (pts)
+    {
+        size = ptmx_write(pts, -1, buf, count);
+    }
+
+    rt_hw_interrupt_enable(level);
+
     return size;
 }
 
 static int ptmx_file_ioctl(struct dfs_fd *fd, int cmd, void *args)
 {
     rt_base_t level = 0;
-    // struct rt_pts_device *pts = RT_NULL; 
 
-    level = rt_hw_interrupt_disable(); 
+    level = rt_hw_interrupt_disable();
 
     switch (cmd) {
     case TIOCSPTLCK:    /* Set PT Lock (disallow slave open) */
     {
-        struct rt_pts_device *pts = ptmxfd2pts(fd); 
-        if(pts != RT_NULL)
+        struct rt_pts_device *pts = ptmxfd2pts(fd);
+        if (pts)
         {
-            pts->pts_lock = *(int *)args; 
-            rt_hw_interrupt_enable(level); 
-            return 0; 
+            pts->pts_lock = *(int *)args;
+            rt_hw_interrupt_enable(level);
+            return 0;
         }
         else
         {
-            rt_hw_interrupt_enable(level); 
-            return (-EIO); 
+            rt_hw_interrupt_enable(level);
+            return (-EIO);
         }
     }
     case TIOCGPTLCK:    /* Get PT Lock status */
     {
-        struct rt_pts_device *pts = ptmxfd2pts(fd); 
-        if(pts != RT_NULL)
+        struct rt_pts_device *pts = ptmxfd2pts(fd);
+        if (pts)
         {
-            *(int *)args = pts->pts_lock; 
-            rt_hw_interrupt_enable(level); 
-            return 0; 
+            *(int *)args = pts->pts_lock;
+            rt_hw_interrupt_enable(level);
+            return 0;
         }
         else
         {
-            rt_hw_interrupt_enable(level); 
-            return (-EIO); 
+            rt_hw_interrupt_enable(level);
+            return (-EIO);
         }
     }
     case TIOCPKT:       /* Set PT packet mode */
         // return pty_set_pktmode(tty, (int __user *)arg);
-        rt_hw_interrupt_enable(level); 
-        return 0; 
+        rt_hw_interrupt_enable(level);
+        return 0;
     case TIOCGPKT:      /* Get PT packet mode */
         // return pty_get_pktmode(tty, (int __user *)arg);
-        rt_hw_interrupt_enable(level); 
-        return 0; 
+        rt_hw_interrupt_enable(level);
+        return 0;
     case TIOCGPTN:      /* Get PT Number */
     {
-        struct rt_pts_device *pts = ptmxfd2pts(fd); 
-        if(pts != RT_NULL)
+        struct rt_pts_device *pts = ptmxfd2pts(fd);
+        if (pts)
         {
-            /* 获取 ptmx 对应的 pts 的编号 */ 
-            *(int *)args = pts->pts_index; 
-            rt_hw_interrupt_enable(level); 
-            return 0; 
+            /* 获取 ptmx 对应的 pts 的编号 */
+            *(int *)args = pts->pts_index;
+            rt_hw_interrupt_enable(level);
+            return 0;
         }
         else
         {
-            rt_hw_interrupt_enable(level); 
-            return (-EIO); 
+            rt_hw_interrupt_enable(level);
+            return (-EIO);
         }
     }
     case TIOCSIG:       /* Send signal to other side of pty */
         // return pty_signal(tty, (int) arg);
-        rt_hw_interrupt_enable(level); 
-        return 0; 
+        rt_hw_interrupt_enable(level);
+        return 0;
 
-#if defined(RT_USING_POSIX_TERMIOS) 
-    case TCSETS: 
+#if defined(RT_USING_POSIX_TERMIOS)
+    case TCSETS:
     {
         // pts = ptmxfd2pts(fd);
-        // rt_memcpy(&pts->tio, args, sizeof(struct termios)); 
-        rt_hw_interrupt_enable(level); 
-        return (-EINVAL); 
+        // rt_memcpy(&pts->tio, args, sizeof(struct termios));
+        rt_hw_interrupt_enable(level);
+        return (-EINVAL);
     }
     case TCGETS:
     {
         // pts = ptmxfd2pts(fd);
-        // rt_memcpy(args, &pts->tio, sizeof(struct termios)); 
-        rt_hw_interrupt_enable(level); 
-        return (-EINVAL); 
+        // rt_memcpy(args, &pts->tio, sizeof(struct termios));
+        rt_hw_interrupt_enable(level);
+        return (-EINVAL);
     }
-#endif /* RT_USING_POSIX_TERMIOS */ 
+#endif /* RT_USING_POSIX_TERMIOS */
     }
 
-    rt_hw_interrupt_enable(level); 
+    rt_hw_interrupt_enable(level);
     return (-EINVAL);
 }
 
 static int ptmx_file_poll(struct dfs_fd *fd, struct rt_pollreq *req)
 {
     rt_base_t level = 0;
-    int mask = POLLOUT; 
+    int mask = POLLOUT;
     rt_size_t len;
-    struct rt_pts_device *pts = ptmxfd2pts(fd); 
-    struct rt_wqueue *wq = RT_NULL;
-    struct rt_lwp *lwp = RT_NULL;
+    struct rt_pts_device *pts = RT_NULL;
 
     level = rt_hw_interrupt_disable();
 
-    lwp = (struct rt_lwp *)(rt_thread_self()->lwp);
-    wq = ptmx_get_wq(lwp);
-    rt_poll_add(wq, req);
-    pts->swq = wq; 
+    pts = ptmxfd2pts(fd);
+    if (!pts)
+    {
+        mask |= POLLIN;
+        goto _exit;
+    }
+
+    rt_poll_add(pts->swq, req);
 
-    /* 判断是否有数据可以 read 设备 */ 
-    len = rt_ringbuffer_data_len(pts->srb);
-    if(len)
+    /* 判断是否有数据可以 read 设备 */
+    len = rt_ringbuffer_data_len(&pts->srb);
+    if (len)
     {
         mask |= POLLIN;
     }
 
+_exit:
     rt_hw_interrupt_enable(level);
 
-    return mask; 
+    return mask;
 }
 
 static rt_err_t ptmx_device_init(struct rt_device *dev)
 {
-    return RT_EOK; 
+    return RT_EOK;
 }
 
 static rt_err_t ptmx_device_open(struct rt_device *dev, rt_uint16_t oflag)
 {
-    return RT_EOK; 
+    return RT_EOK;
 }
 
 static rt_err_t ptmx_device_close(struct rt_device *dev)
 {
-    return RT_EOK; 
+    return RT_EOK;
 }
 
 static rt_size_t ptmx_device_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size)
 {
-    rt_base_t level = 0;
-    rt_size_t len = 0;
-    struct rt_pts_device *pts = (struct rt_pts_device *)(dev->user_data); 
-
-    level = rt_hw_interrupt_disable();
-    if (size)
-    {
-        len = rt_ringbuffer_data_len(pts->srb); 
-        if (len > size)
-        {
-            len = size;
-        }
-        if (len)
-        {
-            len = rt_ringbuffer_get(pts->srb, buffer, len);
-        }
-    }
-    rt_hw_interrupt_enable(level); 
-
-    return len; 
+    return size;
 }
 
-static rt_size_t ptmx_device_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t count)
+static rt_size_t ptmx_device_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size)
 {
-    rt_base_t level = 0;
-    rt_size_t size = 0;
-    struct rt_pts_device *pts = RT_NULL; 
-
-    if(*(char *)buffer == '\r')
-    {
-        *(char *)buffer = '\n'; 
-    }
-
-    level = rt_hw_interrupt_disable(); 
-    pts = (struct rt_pts_device *)(dev->user_data); 
-    size = lwp_pts_push_mrb(pts, (void *)buffer, count); 
-    rt_hw_interrupt_enable(level);
-
-    return size; 
+    return size;
 }
 
 static rt_err_t ptmx_device_control(rt_device_t dev, int cmd, void *args)
 {
-    return RT_EOK; 
+    return RT_EOK;
 }
 
 #ifdef RT_USING_POSIX
@@ -373,9 +394,9 @@ const static struct dfs_file_ops ptmx_file_ops =
     RT_NULL, /* flush */
     RT_NULL, /* lseek */
     RT_NULL, /* getdents */
-    ptmx_file_poll, 
+    ptmx_file_poll,
 };
-#endif /* RT_USING_POSIX */ 
+#endif /* RT_USING_POSIX */
 
 #ifdef RT_USING_DEVICE_OPS
 const static struct rt_device_ops ptmx_device_ops =
@@ -387,24 +408,24 @@ const static struct rt_device_ops ptmx_device_ops =
     ptmx_device_write,
     ptmx_device_control,
 };
-#endif /* RT_USING_DEVICE_OPS */ 
+#endif /* RT_USING_DEVICE_OPS */
 
-static int lwp_ptmx_register(void) 
+static int lwp_ptmx_register(void)
 {
     rt_err_t ret = RT_EOK;
     rt_base_t level = 0;
-    struct rt_device *device = RT_NULL; 
+    struct rt_device *device = RT_NULL;
 
-    level = rt_hw_interrupt_disable(); 
+    level = rt_hw_interrupt_disable();
 
-    if(_ptmx->flags != PTY_INIT_FLAG_NONE)
+    if (_ptmx->flags != PTY_INIT_FLAG_NONE)
     {
-        ret = (-RT_EBUSY); 
-        goto _exit; 
+        ret = (-RT_EBUSY);
+        goto _exit;
     }
 
-    device = &(_ptmx->parent); 
-    device->type    = RT_Device_Class_Char; 
+    device = &_ptmx->parent;
+    device->type    = RT_Device_Class_Char;
 #ifdef RT_USING_DEVICE_OPS
     device->ops     = &ptmx_device_ops;
 #else
@@ -414,9 +435,9 @@ static int lwp_ptmx_register(void)
     device->read    = ptmx_device_read;
     device->write   = ptmx_device_write;
     device->control = ptmx_device_control;
-#endif /* RT_USING_DEVICE_OPS */ 
+#endif /* RT_USING_DEVICE_OPS */
 
-    ret = rt_device_register(device, "ptmx", RT_DEVICE_FLAG_RDWR); 
+    ret = rt_device_register(device, "ptmx", RT_DEVICE_FLAG_RDWR);
     if (ret != RT_EOK)
     {
         ret = -RT_EIO;
@@ -425,18 +446,18 @@ static int lwp_ptmx_register(void)
 
 #ifdef RT_USING_POSIX
     /* set fops */
-    device->fops = &ptmx_file_ops; 
+    device->fops = &ptmx_file_ops;
 #endif
 
-    rt_wqueue_init(&(_ptmx->wq));
-    rt_mutex_init(&_ptmx->mutex, "ptmx", RT_IPC_FLAG_FIFO); 
-    rt_memset(_ptmx->pts, 0x00, sizeof(struct rt_pts_device)*LWP_PTY_PTS_SIZE); 
-    _ptmx->pts_index = 0; 
-    _ptmx->flags = PTY_INIT_FLAG_REGED; 
+    rt_wqueue_init(&_ptmx->wq);
+    rt_mutex_init(&_ptmx->mutex, "ptmx", RT_IPC_FLAG_FIFO);
+    rt_memset(_ptmx->pts, 0x00, sizeof(struct rt_pts_device)*LWP_PTY_PTS_SIZE);
+    _ptmx->pts_index = 0;
+    _ptmx->flags = PTY_INIT_FLAG_REGED;
 
-_exit: 
-    rt_hw_interrupt_enable(level); 
+_exit:
+    rt_hw_interrupt_enable(level);
 
     return ret;
 }
-INIT_DEVICE_EXPORT(lwp_ptmx_register); 
+INIT_DEVICE_EXPORT(lwp_ptmx_register);

+ 204 - 199
components/lwp/unix98pty/lwp_pts.c

@@ -5,8 +5,12 @@
  */
 #include "lwp_pty.h"
 
-rt_inline struct rt_wqueue *pts_get_wq(struct rt_lwp *lwp)
+rt_inline struct rt_wqueue *pts_get_wq(struct rt_pts_device *pts, struct rt_lwp *lwp)
 {
+    if (lwp == RT_NULL)
+    {
+        return &pts->wq;
+    }
     return &lwp->wait_queue;
 }
 
@@ -15,13 +19,21 @@ static int pts_file_open(struct dfs_fd *fd)
     int ret = 0;
     struct rt_device *device = RT_NULL;
     rt_base_t level = 0;
+    struct rt_lwp *lwp = RT_NULL;
+    struct rt_wqueue *wq = RT_NULL;
 
     level = rt_hw_interrupt_disable();
-    device = (struct rt_device *)fd->fnode->data; 
+    device = (struct rt_device *)fd->fnode->data;
     RT_ASSERT(device != RT_NULL);
 
     if (fd->fnode->ref_count == 1)
     {
+        struct rt_pts_device *pts = LWP_PTY_GET_PTS(fd);
+
+        lwp = (struct rt_lwp *)(rt_thread_self()->lwp);
+        wq = pts_get_wq(pts, lwp);
+        pts->mwq = wq;
+
         ret = rt_device_open(device, fd->flags);
     }
     rt_hw_interrupt_enable(level);
@@ -32,7 +44,7 @@ static int pts_file_close(struct dfs_fd *fd)
 {
     int ret = 0;
     struct rt_device *device = RT_NULL;
-    struct rt_pts_device *pts = LWP_PTY_GET_PTS(fd); 
+    struct rt_pts_device *pts = LWP_PTY_GET_PTS(fd);
     rt_base_t level = 0;
 
     level = rt_hw_interrupt_disable();
@@ -43,11 +55,11 @@ static int pts_file_close(struct dfs_fd *fd)
     if (fd->fnode->ref_count == 1)
     {
         ret = rt_device_close(device);
-        lwp_pts_unregister(pts); 
+        lwp_pts_unregister(pts);
     }
 
     rt_hw_interrupt_enable(level);
-    
+
     return ret;
 }
 
@@ -55,17 +67,12 @@ static int pts_file_read(struct dfs_fd *fd, void *buf, size_t count)
 {
     rt_base_t level = 0;
     size_t size = 0;
-    struct rt_pts_device *pts = LWP_PTY_GET_PTS(fd); 
-    struct rt_lwp *lwp = RT_NULL;
-    struct rt_wqueue *wq = RT_NULL;
+    struct rt_pts_device *pts = LWP_PTY_GET_PTS(fd);
     int wait_ret = 0;
 
     level = rt_hw_interrupt_disable();
 
-    lwp = (struct rt_lwp *)(rt_thread_self()->lwp);
-    wq = pts_get_wq(lwp);
-
-    while(count)
+    while (count)
     {
         size = rt_device_read(&pts->parent, -1, buf, count);
         if (size > 0)
@@ -78,10 +85,13 @@ static int pts_file_read(struct dfs_fd *fd, void *buf, size_t count)
             break;
         }
 
-        /* 当直接读的时候,没有数据就挂起,等待 ptmx 写入数据后唤醒 */ 
-        pts->mwq = wq; /* 将当前lwp的等待队列设置到 pts 中,用于 ptmx 写数据后唤醒 lwp 读数据 */  
-        wait_ret = rt_wqueue_wait_interruptible(wq, 0, RT_WAITING_FOREVER);
-        pts->mwq = RT_NULL; /* 清空 */ 
+        if (!pts->ptmx_fd) /* ptmux closed */
+        {
+            break;
+        }
+
+        /* 当直接读的时候,没有数据就挂起,等待 ptmx 写入数据后唤醒 */
+        wait_ret = rt_wqueue_wait_interruptible(pts->mwq, 0, RT_WAITING_FOREVER);
         if (wait_ret != 0)
         {
             break;
@@ -95,7 +105,7 @@ static int pts_file_read(struct dfs_fd *fd, void *buf, size_t count)
         size = 0;
     }
 
-    return size; 
+    return size;
 }
 
 static int pts_file_write(struct dfs_fd *fd, const void *buf, size_t count)
@@ -104,8 +114,8 @@ static int pts_file_write(struct dfs_fd *fd, const void *buf, size_t count)
     rt_base_t level = 0;
 
     level = rt_hw_interrupt_disable();
-    
-    struct rt_pts_device *pts = LWP_PTY_GET_PTS(fd); 
+
+    struct rt_pts_device *pts = LWP_PTY_GET_PTS(fd);
     RT_ASSERT(pts != RT_NULL);
     size = rt_device_write((struct rt_device *)pts, -1, buf, count);
 
@@ -117,39 +127,39 @@ static int pts_file_write(struct dfs_fd *fd, const void *buf, size_t count)
 static int pts_file_ioctl(struct dfs_fd *fd, int cmd, void *args)
 {
     rt_base_t level = 0;
-    struct rt_pts_device *pts = LWP_PTY_GET_PTS(fd); 
+    struct rt_pts_device *pts = LWP_PTY_GET_PTS(fd);
 
     level = rt_hw_interrupt_disable();
 
     switch (cmd) {
     case TIOCSWINSZ:
-        rt_memcpy(&pts->winsize, args, sizeof(struct winsize)); 
-        LOG_D("set /dev/pts/%d winsize: %d %d %d %d", 
-            pts->pts_index, 
-            pts->winsize.ws_row, pts->winsize.ws_col, 
-            pts->winsize.ws_xpixel, pts->winsize.ws_ypixel); 
+        rt_memcpy(&pts->winsize, args, sizeof(struct winsize));
+        LOG_D("set /dev/pts/%d winsize: %d %d %d %d",
+            pts->pts_index,
+            pts->winsize.ws_row, pts->winsize.ws_col,
+            pts->winsize.ws_xpixel, pts->winsize.ws_ypixel);
         rt_hw_interrupt_enable(level);
-        return 0; 
+        return 0;
     case TIOCGWINSZ:
-        rt_memcpy(args, &pts->winsize, sizeof(struct winsize)); 
+        rt_memcpy(args, &pts->winsize, sizeof(struct winsize));
         rt_hw_interrupt_enable(level);
-        return 0; 
+        return 0;
 
-    case TIOCSCTTY: 
+    case TIOCSCTTY:
         LOG_D("TODO PTS TIOCSCTTY CMD");
-        rt_hw_interrupt_enable(level); 
-        return 0; 
+        rt_hw_interrupt_enable(level);
+        return 0;
 
-#if defined(RT_USING_POSIX_TERMIOS) 
+#if defined(RT_USING_POSIX_TERMIOS)
     case TCSETS:
-        rt_memcpy(&pts->tio, args, sizeof(struct termios)); 
+        rt_memcpy(&pts->tio, args, sizeof(struct termios));
         rt_hw_interrupt_enable(level);
-        return 0; 
+        return 0;
     case TCGETS:
-        rt_memcpy(args, &pts->tio, sizeof(struct termios)); 
+        rt_memcpy(args, &pts->tio, sizeof(struct termios));
         rt_hw_interrupt_enable(level);
-        return 0; 
-#endif /* RT_USING_POSIX_TERMIOS */ 
+        return 0;
+#endif /* RT_USING_POSIX_TERMIOS */
     }
 
     rt_hw_interrupt_enable(level);
@@ -159,45 +169,40 @@ static int pts_file_ioctl(struct dfs_fd *fd, int cmd, void *args)
 static int pts_file_poll(struct dfs_fd *fd, struct rt_pollreq *req)
 {
     rt_base_t level = 0;
-    int mask = POLLOUT; 
+    int mask = POLLOUT;
     rt_size_t len;
-    struct rt_pts_device *pts = LWP_PTY_GET_PTS(fd); 
-    struct rt_wqueue *wq = RT_NULL;
-    struct rt_lwp *lwp = RT_NULL;
+    struct rt_pts_device *pts = LWP_PTY_GET_PTS(fd);
 
     level = rt_hw_interrupt_disable();
 
-    lwp = (struct rt_lwp *)(rt_thread_self()->lwp);
-    wq = pts_get_wq(lwp);
-    rt_poll_add(wq, req);
-    pts->mwq = wq; 
+    rt_poll_add(pts->mwq, req);
 
-    /* 判断是否有数据可以 read 设备 */ 
-    len = rt_ringbuffer_data_len(pts->mrb);
-    if(len)
+    /* 判断是否有数据可以 read 设备 */
+    len = rt_ringbuffer_data_len(&pts->mrb);
+    if (len)
     {
         mask |= POLLIN;
     }
 
     rt_hw_interrupt_enable(level);
 
-    return mask; 
+    return mask;
 }
 
 static rt_err_t pts_device_init(struct rt_device *dev)
 {
-    return RT_EOK; 
+    return RT_EOK;
 }
 
 static rt_err_t pts_device_open(struct rt_device *dev, rt_uint16_t oflag)
 {
-    // TODO: oflag = O_NOCTTY 
-    return RT_EOK; 
+    // TODO: oflag = O_NOCTTY
+    return RT_EOK;
 }
 
 static rt_err_t pts_device_close(struct rt_device *dev)
 {
-    return RT_EOK; 
+    return RT_EOK;
 }
 
 static rt_size_t pts_device_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size)
@@ -209,38 +214,38 @@ static rt_size_t pts_device_read(struct rt_device *dev, rt_off_t pos, void *buff
     level = rt_hw_interrupt_disable();
     if (size)
     {
-        len = rt_ringbuffer_data_len(pts->mrb); 
+        len = rt_ringbuffer_data_len(&pts->mrb);
         if (len > size)
         {
             len = size;
         }
         if (len)
         {
-            len = rt_ringbuffer_get(pts->mrb, buffer, len);
+            len = rt_ringbuffer_get(&pts->mrb, buffer, len);
         }
     }
-    rt_hw_interrupt_enable(level); 
+    rt_hw_interrupt_enable(level);
 
-    return len; 
+    return len;
 }
 
 static rt_size_t pts_device_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t count)
 {
     rt_base_t level = 0;
     rt_size_t size = 0;
-    struct rt_pts_device *pts = RT_NULL; 
+    struct rt_pts_device *pts = RT_NULL;
 
-    level = rt_hw_interrupt_disable(); 
-    pts = (struct rt_pts_device *)dev; 
-    size = lwp_pts_push_srb(pts, (void *)buffer, count); 
+    level = rt_hw_interrupt_disable();
+    pts = (struct rt_pts_device *)dev;
+    size = lwp_pts_push_srb(pts, (void *)buffer, count);
     rt_hw_interrupt_enable(level);
 
-    return size; 
+    return size;
 }
 
 static rt_err_t pts_device_control(rt_device_t dev, int cmd, void *args)
 {
-    return RT_EOK; 
+    return RT_EOK;
 }
 
 #ifdef RT_USING_POSIX
@@ -254,9 +259,9 @@ const static struct dfs_file_ops pts_file_ops =
     RT_NULL, /* flush */
     RT_NULL, /* lseek */
     RT_NULL, /* getdents */
-    pts_file_poll, 
+    pts_file_poll,
 };
-#endif /* RT_USING_POSIX */ 
+#endif /* RT_USING_POSIX */
 
 #ifdef RT_USING_DEVICE_OPS
 const static struct rt_device_ops pts_device_ops =
@@ -268,222 +273,224 @@ const static struct rt_device_ops pts_device_ops =
     pts_device_write,
     pts_device_control,
 };
-#endif /* RT_USING_DEVICE_OPS */ 
+#endif /* RT_USING_DEVICE_OPS */
 
 int lwp_pts_isbusy(struct rt_pts_device *pts)
 {
-    RT_ASSERT(pts != RT_NULL); 
-    return (pts->parent.ref_count > 0) ? 1 : 0;  
+    RT_ASSERT(pts != RT_NULL);
+    return (pts->parent.ref_count > 0) ? 1 : 0;
 }
 
 static rt_size_t dispose_char(struct rt_pts_device *pts, char ch)
 {
-    rt_uint8_t is_lfcr = 0; 
+    rt_uint8_t is_lfcr = 0;
 
     if (ch < 0)
     {
-        return 0; 
+        return 0;
     }
 
-    /* 判断输入是否超过了缓存, 截断超出部分 */ 
+    /* 判断输入是否超过了缓存, 截断超出部分 */
     if (pts->line_position >= LWP_PTY_INPUT_BFSZ && ch != '\r' && ch != '\n')
     {
-        return 0; 
+        return 0;
     }
 
-    /* handle control key: 
+    /* handle control key:
      * up key  : 0x1b 0x5b 0x41
      * down key: 0x1b 0x5b 0x42
      * right key:0x1b 0x5b 0x43
      * left key: 0x1b 0x5b 0x44
      */
-    if(ch == 0x1b)
+    if (ch == 0x1b)
     {
-        pts->stat = LWP_PTS_INPUT_WAIT_SPEC_KEY; 
-        return 0; 
+        pts->stat = LWP_PTS_INPUT_WAIT_SPEC_KEY;
+        return 0;
     }
     else if (pts->stat == LWP_PTS_INPUT_WAIT_SPEC_KEY)
     {
-        if(ch == 0x5b)
+        if (ch == 0x5b)
         {
             pts->stat = LWP_PTS_INPUT_WAIT_FUNC_KEY;
-            return 0; 
+            return 0;
         }
 
-        pts->stat = LWP_PTS_INPUT_WAIT_NORMAL; 
+        pts->stat = LWP_PTS_INPUT_WAIT_NORMAL;
     }
     else if (pts->stat == LWP_PTS_INPUT_WAIT_FUNC_KEY)
     {
-        pts->stat = LWP_PTS_INPUT_WAIT_NORMAL; 
+        pts->stat = LWP_PTS_INPUT_WAIT_NORMAL;
 
         if (ch == 0x41) /* up key */
         {
-            LOG_D("find input UP key"); 
-            char buff[] = "^[[A"; 
-            rt_ringbuffer_put_force(pts->srb, (void *)buff, rt_strlen(buff)); /* 回显 */ 
-            return 0; 
+            LOG_D("find input UP key");
+            char buff[] = "^[[A";
+            rt_ringbuffer_put_force(&pts->srb, (void *)buff, rt_strlen(buff)); /* 回显 */
+            return 0;
         }
         else if (ch == 0x42) /* down key */
         {
-            LOG_D("find input DOWN key"); 
-            char buff[] = "^[[B"; 
-            rt_ringbuffer_put_force(pts->srb, (void *)buff, rt_strlen(buff)); /* 回显 */ 
-            return 0; 
+            LOG_D("find input DOWN key");
+            char buff[] = "^[[B";
+            rt_ringbuffer_put_force(&pts->srb, (void *)buff, rt_strlen(buff)); /* 回显 */
+            return 0;
         }
         else if (ch == 0x44) /* left key */
         {
-            LOG_D("find input RIGHT key"); 
-            char buff[] = "^[[C"; 
-            rt_ringbuffer_put_force(pts->srb, (void *)buff, rt_strlen(buff)); /* 回显 */ 
-            return 0; 
+            LOG_D("find input RIGHT key");
+            char buff[] = "^[[C";
+            rt_ringbuffer_put_force(&pts->srb, (void *)buff, rt_strlen(buff)); /* 回显 */
+            return 0;
         }
         else if (ch == 0x43) /* right key */
         {
-            LOG_D("find input LEFT key"); 
-            char buff[] = "^[[D"; 
-            rt_ringbuffer_put_force(pts->srb, (void *)buff, rt_strlen(buff)); /* 回显 */ 
-            return 0; 
+            LOG_D("find input LEFT key");
+            char buff[] = "^[[D";
+            rt_ringbuffer_put_force(&pts->srb, (void *)buff, rt_strlen(buff)); /* 回显 */
+            return 0;
         }
     }
 
     /* received null or error */
-    if (ch == '\0' || ch == 0xFF) return 0; 
-    else if (ch == '\t') 
+    if (ch == '\0' || ch == 0xFF) return 0;
+    else if (ch == '\t')
     {
-        /* 补全不回显, 但是由会传递给 sh 处理 */ 
-        pts->line[pts->line_position] = ch; 
-        pts->line_position++; 
-        return 0; 
+        /* 补全不回显, 但是由会传递给 sh 处理 */
+        pts->line[pts->line_position] = ch;
+        pts->line_position++;
+        return 0;
     }
     else if (ch == 0x7f || ch == 0x08) /* handle backspace key */
     {
-        LOG_D("find input backspace key"); 
+        LOG_D("find input backspace key");
 
-        char buff[] = "\b \b"; 
-        rt_ringbuffer_put_force(pts->srb, (void *)buff, rt_strlen(buff)); /* 回显 */ 
-        pts->line_position--; 
-        return 0; 
+        char buff[] = "\b \b";
+        rt_ringbuffer_put_force(&pts->srb, (void *)buff, rt_strlen(buff)); /* 回显 */
+        pts->line_position--;
+        return 0;
     }
 
     /* handle end of line, break */
     else if (ch == '\r' || ch == '\n')
     {
-        is_lfcr = 1; 
+        is_lfcr = 1;
     }
 
-    rt_ringbuffer_put_force(pts->srb, (void *)&ch, 1); /* 回显 */ 
+    rt_ringbuffer_put_force(&pts->srb, (void *)&ch, 1); /* 回显 */
 
     /* 将没有回车的一行输入缓存到 line 中, 当发现回车换行后再统一输出到 ptmx 处理 */
-    // LOG_D("%d", ch); 
-    pts->line[pts->line_position] = ch; 
-    pts->line_position++; 
+    // LOG_D("%d", ch);
+    pts->line[pts->line_position] = ch;
+    pts->line_position++;
 
-    return is_lfcr; 
+    return is_lfcr;
 }
 
 rt_size_t lwp_pts_push_mrb(struct rt_pts_device *pts, void *buffer, rt_size_t size)
 {
     rt_size_t len = 0;
-    rt_uint8_t is_lfcr = 0; 
-    RT_ASSERT(pts != RT_NULL); 
+    rt_uint8_t is_lfcr = 0;
+    RT_ASSERT(pts != RT_NULL);
 
-    if(pts->echo)
+    if (pts->echo)
     {
-        /* 按照字符处理 */ 
+        /* 按照字符处理 */
         for(int index = 0; index < size; index++)
         {
-            char *ptr = (char *)buffer; 
-            is_lfcr = dispose_char(pts, *(ptr + index)); 
+            char *ptr = (char *)buffer;
+            is_lfcr = dispose_char(pts, *(ptr + index));
         }
 
         /* 判断是否发现回车换行了 */
-        if(is_lfcr)
+        if (is_lfcr)
         {
-            // LOG_D("pts->line_position = %d", pts->line_position); 
-            rt_ringbuffer_put_force(pts->mrb, (void *)pts->line, pts->line_position);  
-            pts->line_position = 0; 
-            rt_memset(pts->line, 0x00, LWP_PTY_INPUT_BFSZ+1); 
+            // LOG_D("pts->line_position = %d", pts->line_position);
+            rt_ringbuffer_put_force(&pts->mrb, (void *)pts->line, pts->line_position);
+            pts->line_position = 0;
+            rt_memset(pts->line, 0x00, LWP_PTY_INPUT_BFSZ+1);
         }
     }
-    else /* 不处理直接传递给 sh 处理回显和字符 */ 
+    else /* 不处理直接传递给 sh 处理回显和字符 */
     {
-        rt_ringbuffer_put_force(pts->mrb, buffer, size); 
+        rt_ringbuffer_put_force(&pts->mrb, buffer, size);
     }
 
-    len = rt_ringbuffer_data_len(pts->mrb); 
-    if(len && pts->mwq) 
+    len = rt_ringbuffer_data_len(&pts->mrb);
+    if (len && pts->mwq)
     {
         // 先读阻塞,用于唤醒阻塞的 lwp 进程
-        rt_wqueue_wakeup(pts->mwq, (void*)POLLIN); 
-    } 
+        rt_wqueue_wakeup(pts->mwq, (void*)POLLIN);
+    }
 
-    return len; 
+    return len;
 }
 
 rt_size_t lwp_pts_push_srb(struct rt_pts_device *pts, void *buffer, rt_size_t size)
 {
     rt_size_t len = 0;
-    RT_ASSERT(pts != RT_NULL); 
-    rt_ringbuffer_put_force(pts->srb, buffer, size); 
-    len = rt_ringbuffer_data_len(pts->srb); 
+    RT_ASSERT(pts != RT_NULL);
+    rt_ringbuffer_put_force(&pts->srb, buffer, size);
+    len = rt_ringbuffer_data_len(&pts->srb);
 
-    if(len && pts->swq) 
+    if (len && pts->swq)
     {
         // 先读阻塞,用于唤醒阻塞的 lwp 进程
-        rt_wqueue_wakeup(pts->swq, (void*)POLLIN); 
-    } 
-    return len; 
+        rt_wqueue_wakeup(pts->swq, (void*)POLLIN);
+    }
+    return len;
 }
 
 int lwp_pts_unregister(struct rt_pts_device *pts)
 {
-    rt_err_t ret = RT_EOK; 
+    rt_err_t ret = RT_EOK;
     rt_base_t level = 0;
+    struct rt_wqueue *wq = RT_NULL;
 
-    level = rt_hw_interrupt_disable(); 
-    if(pts->parent.ref_count > 0)
+    level = rt_hw_interrupt_disable();
+    if (pts->parent.ref_count > 0)
     {
         ret = (-RT_EBUSY);
-        goto _exit;  
+        goto _exit;
+    }
+
+    wq = pts->swq;
+    rt_mutex_detach(&pts->mutex);
+    rt_memset(&pts->winsize, 0x00, sizeof(struct winsize));
+    pts->pts_lock = 0;
+    pts->ptmx_fd = 0;
+    pts->pts_index = 0;
+    pts->flags = PTY_INIT_FLAG_NONE;
+    if (wq)
+    {
+        rt_wqueue_wakeup(wq, (void*)POLLIN);
     }
+    rt_hw_interrupt_enable(level);
+    ret = rt_device_unregister(&pts->parent);
 
-    rt_ringbuffer_destroy(pts->mrb); 
-    rt_ringbuffer_destroy(pts->srb); 
-
-    pts->mrb = RT_NULL;
-    pts->srb = RT_NULL;
-    
-    rt_memset(&pts->winsize, 0x00, sizeof(struct winsize)); 
-    pts->pts_lock = 0; 
-    pts->ptmx_fd = 0; 
-    pts->pts_index = 0; 
-    pts->flags = PTY_INIT_FLAG_NONE; 
-    ret = rt_device_unregister(&(pts->parent)); 
-    
-_exit: 
-    rt_hw_interrupt_enable(level); 
-
-    return ret; 
+_exit:
+    rt_hw_interrupt_enable(level);
+
+    return ret;
 }
 
-int lwp_pts_register(struct rt_pts_device *pts, int ptmx_fd, int pts_index) 
+int lwp_pts_register(struct rt_pts_device *pts, int ptmx_fd, int pts_index)
 {
     rt_err_t ret = RT_EOK;
     rt_base_t level = 0;
-    struct rt_device *device = RT_NULL; 
+    struct rt_device *device = RT_NULL;
     char name[20];
 
-    level = rt_hw_interrupt_disable(); 
+    level = rt_hw_interrupt_disable();
 
-    if(pts->flags != PTY_INIT_FLAG_NONE)
+    if (pts->flags != PTY_INIT_FLAG_ALLOCED)
     {
-        LOG_E("pts%d has been registered", pts_index); 
-        ret = (-RT_EBUSY); 
-        goto _exit; 
+        LOG_E("pts%d has been registered", pts_index);
+        ret = (-RT_EBUSY);
+        goto _exit;
     }
 
-    device = &(pts->parent); 
-    device->type    = RT_Device_Class_Char; 
+    device = &pts->parent;
+    device->type    = RT_Device_Class_Char;
 #ifdef RT_USING_DEVICE_OPS
     device->ops     = &pts_device_ops;
 #else
@@ -493,60 +500,58 @@ int lwp_pts_register(struct rt_pts_device *pts, int ptmx_fd, int pts_index)
     device->read    = pts_device_read;
     device->write   = pts_device_write;
     device->control = pts_device_control;
-#endif /* RT_USING_DEVICE_OPS */ 
+#endif /* RT_USING_DEVICE_OPS */
 
     rt_snprintf(name, sizeof(name), "pts%d", pts_index);
-    ret = rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); 
+    ret = rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
     if (ret != RT_EOK)
     {
-        LOG_E("pts%d register failed", pts_index); 
+        LOG_E("pts%d register failed", pts_index);
         ret = -RT_EIO;
         goto _exit;
     }
 
 #ifdef RT_USING_POSIX
     /* set fops */
-    device->fops = &pts_file_ops; 
+    device->fops = &pts_file_ops;
 #endif
 
-    pts->mrb = rt_ringbuffer_create(LWP_PTY_INPUT_BFSZ);
-    pts->srb = rt_ringbuffer_create(LWP_PTY_INPUT_BFSZ);
-
-    RT_ASSERT(pts->mrb != RT_NULL); 
-    RT_ASSERT(pts->srb != RT_NULL); 
+    rt_wqueue_init(&pts->wq);
+    rt_ringbuffer_init(&pts->mrb, pts->mbuf, LWP_PTY_INPUT_BFSZ);
+    rt_ringbuffer_init(&pts->srb, pts->sbuf, LWP_PTY_INPUT_BFSZ);
 
-    pts->echo = 1; 
+    pts->echo = 1;
     pts->stat = LWP_PTS_INPUT_WAIT_NORMAL;
-    pts->line_position = 0; 
-    rt_memset(pts->line, 0x00, sizeof(pts->line)); 
+    pts->line_position = 0;
+    rt_memset(pts->line, 0x00, sizeof(pts->line));
 
-    rt_mutex_init(&pts->mutex, name, RT_IPC_FLAG_FIFO); 
+    rt_mutex_init(&pts->mutex, name, RT_IPC_FLAG_FIFO);
     pts->mwq = RT_NULL;
-    rt_memset(&pts->winsize, 0x00, sizeof(struct winsize)); 
-    pts->pts_lock = 1; 
-    pts->ptmx_fd = ptmx_fd; 
-    pts->pts_index = pts_index; 
-    pts->flags = PTY_INIT_FLAG_REGED; 
+    rt_memset(&pts->winsize, 0x00, sizeof(struct winsize));
+    pts->pts_lock = 1;
+    pts->ptmx_fd = ptmx_fd;
+    pts->pts_index = pts_index;
+    pts->flags = PTY_INIT_FLAG_REGED;
 
-_exit: 
-    rt_hw_interrupt_enable(level); 
+_exit:
+    rt_hw_interrupt_enable(level);
 
-    return ret; 
+    return ret;
 }
 
 #include <rtthread.h>
 #include <rtdevice.h>
 int pts_dump(int argc, char *argv[])
 {
-    struct rt_pts_device *pts = RT_NULL; 
-    int mrblen = 0, srblen = 0; 
-    rt_device_t dev = rt_device_find(argv[1]); 
-    
-    pts = (struct rt_pts_device *)dev; 
-    mrblen = rt_ringbuffer_data_len(pts->mrb);
-    srblen = rt_ringbuffer_data_len(pts->srb);
-
-    LOG_I("dev %s mrblen = %d srblen = %d", argv[1], mrblen, srblen); 
-    return 0; 
+    struct rt_pts_device *pts = RT_NULL;
+    int mrblen = 0, srblen = 0;
+    rt_device_t dev = rt_device_find(argv[1]);
+
+    pts = (struct rt_pts_device *)dev;
+    mrblen = rt_ringbuffer_data_len(&pts->mrb);
+    srblen = rt_ringbuffer_data_len(&pts->srb);
+
+    LOG_I("dev %s mrblen = %d srblen = %d", argv[1], mrblen, srblen);
+    return 0;
 }
 MSH_CMD_EXPORT(pts_dump, dump /dev/pts/%d device ringbuffer info.);

+ 42 - 39
components/lwp/unix98pty/lwp_pty.h

@@ -13,44 +13,44 @@
 #include <lwp_user_mm.h>
 
 #if defined(RT_USING_POSIX_TERMIOS)
-#include <posix_termios.h> 
-#endif 
+#include <posix_termios.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #define DBG_ENABLE
-#if defined(LWP_PTY_USING_DEBUG) 
+#if defined(LWP_PTY_USING_DEBUG)
 #define DBG_LEVEL DBG_LOG
 #else
 #define DBG_LEVEL DBG_INFO
-#endif 
+#endif
 #define DBG_COLOR
 #include <rtdbg.h>
 
 #ifndef LWP_PTY_INPUT_BFSZ
-#define LWP_PTY_INPUT_BFSZ 1024 
-#endif /* LWP_PTY_INPUT_BFSZ */ 
+#define LWP_PTY_INPUT_BFSZ 1024
+#endif /* LWP_PTY_INPUT_BFSZ */
 
 #ifndef LWP_PTY_PTS_SIZE
-#define LWP_PTY_PTS_SIZE 3 
-#endif /* LWP_PTY_PTS_SIZE */ 
+#define LWP_PTY_PTS_SIZE 3
+#endif /* LWP_PTY_PTS_SIZE */
 
 #ifndef LWP_PTY_HISTORY_LINE_SIZE
-#define LWP_PTY_HISTORY_LINE_SIZE 5 
-#endif /* LWP_PTY_HISTORY_LINE_SIZE */ 
+#define LWP_PTY_HISTORY_LINE_SIZE 5
+#endif /* LWP_PTY_HISTORY_LINE_SIZE */
 
-#define LWP_PTY_GET_PTMX(fd) ((struct rt_ptmx_device *)(fd->fnode->data)) 
-#define LWP_PTY_GET_PTS(fd)  ((struct rt_pts_device *)(fd->fnode->data)) 
+#define LWP_PTY_GET_PTMX(fd) ((struct rt_ptmx_device *)(fd->fnode->data))
+#define LWP_PTY_GET_PTS(fd)  ((struct rt_pts_device *)(fd->fnode->data))
 
 enum lwp_pty_init_flag
 {
     PTY_INIT_FLAG_NONE = 0,
+    PTY_INIT_FLAG_ALLOCED,
     PTY_INIT_FLAG_REGED,
-    PTY_INIT_FLAG_INITED,
-}; 
-typedef enum lwp_pty_init_flag lwp_pty_init_flag_t; 
+};
+typedef enum lwp_pty_init_flag lwp_pty_init_flag_t;
 
 enum lwp_pts_input_stat
 {
@@ -58,26 +58,26 @@ enum lwp_pts_input_stat
     LWP_PTS_INPUT_WAIT_SPEC_KEY,
     LWP_PTS_INPUT_WAIT_FUNC_KEY,
 };
-typedef enum lwp_pts_input_stat lwp_pts_input_stat_t; 
+typedef enum lwp_pts_input_stat lwp_pts_input_stat_t;
 
 struct rt_pts_device
 {
     struct rt_device parent;
-    int flags; 
-    int pts_lock; 
-    int pts_index; /* index = /dev/pts/%d */ 
-    struct rt_mutex mutex; 
+    int flags;
+    int pts_lock;
+    int pts_index; /* index = /dev/pts/%d */
+    struct rt_mutex mutex;
 
     // ptmx
-    struct rt_ptmx_device *ptmx; 
+    struct rt_ptmx_device *ptmx;
     int ptmx_fd;
 
     // win attribute
-    struct winsize winsize; 
-    
+    struct winsize winsize;
+
 #if defined(RT_USING_POSIX_TERMIOS)
-    struct termios tio; 
-#endif /* RT_USING_POSIX_TERMIOS */ 
+    struct termios tio;
+#endif /* RT_USING_POSIX_TERMIOS */
 
     /* console echo */
     lwp_pts_input_stat_t stat;
@@ -85,32 +85,35 @@ struct rt_pts_device
     char line[LWP_PTY_INPUT_BFSZ+1];
     rt_uint16_t line_position;
 
-    struct rt_wqueue *mwq; 
-    struct rt_wqueue *swq; 
-    struct rt_ringbuffer *mrb; // ptmx w(master) ==> pts r(slave)
-    struct rt_ringbuffer *srb; // pts w(slave) ==> ptmx r(master)
+    struct rt_wqueue *mwq;
+    struct rt_wqueue *swq;
+    struct rt_wqueue wq;      /* for kernel */
+    struct rt_ringbuffer mrb; /* ptmx w(master) ==> pts r(slave) */
+    struct rt_ringbuffer srb; /* pts w(slave) ==> ptmx r(master) */
+    rt_uint8_t mbuf[LWP_PTY_INPUT_BFSZ];
+    rt_uint8_t sbuf[LWP_PTY_INPUT_BFSZ];
 };
 
 struct rt_ptmx_device
 {
     struct rt_device parent;
     int flags;
-    struct rt_mutex mutex; 
+    struct rt_mutex mutex;
     struct rt_wqueue wq;
-    
-    int pts_index; 
-    struct rt_pts_device pts[LWP_PTY_PTS_SIZE]; 
+
+    int pts_index;
+    struct rt_pts_device pts[LWP_PTY_PTS_SIZE];
 };
 
 /* pty */
-extern int lwp_pts_isbusy(struct rt_pts_device *pts); 
-extern rt_size_t lwp_pts_push_mrb(struct rt_pts_device *pts, void *buffer, rt_size_t size); 
-extern rt_size_t lwp_pts_push_srb(struct rt_pts_device *pts, void *buffer, rt_size_t size); 
-extern int lwp_pts_unregister(struct rt_pts_device *pts); 
-extern int lwp_pts_register(struct rt_pts_device *pts, int ptmx_fd, int pts_index);   
+extern int lwp_pts_isbusy(struct rt_pts_device *pts);
+extern rt_size_t lwp_pts_push_mrb(struct rt_pts_device *pts, void *buffer, rt_size_t size);
+extern rt_size_t lwp_pts_push_srb(struct rt_pts_device *pts, void *buffer, rt_size_t size);
+extern int lwp_pts_unregister(struct rt_pts_device *pts);
+extern int lwp_pts_register(struct rt_pts_device *pts, int ptmx_fd, int pts_index);
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* __LWP_PTY_H__ */ 
+#endif /* __LWP_PTY_H__ */