From 9322ec51692581a39cdd19fee107ddec684ad498 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Fri, 9 Jul 2021 10:48:10 +0800 Subject: [PATCH 1/2] =?UTF-8?q?cortex-a=20stack.c=E4=B8=AD=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=E5=AF=B9cpuport.h=E7=9A=84=E5=A4=B4=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=8C=85=E5=90=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/arm/cortex-a/stack.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libcpu/arm/cortex-a/stack.c b/libcpu/arm/cortex-a/stack.c index 24fc521e08..8f73d730dd 100644 --- a/libcpu/arm/cortex-a/stack.c +++ b/libcpu/arm/cortex-a/stack.c @@ -9,6 +9,7 @@ * 2011-10-05 Bernard add thumb mode */ #include +#include #include /** -- Gitee From 7876c20d86d4e593d7b7fdedd931f74d50f078cd Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Fri, 9 Jul 2021 10:50:07 +0800 Subject: [PATCH 2/2] =?UTF-8?q?ptmx/pts=E5=9F=BA=E6=9C=AC=E6=AD=A3?= =?UTF-8?q?=E5=B8=B8=E8=BF=90=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/lwp/unix98pty/lwp_ptmx.c | 425 +++++++++++++++------------- components/lwp/unix98pty/lwp_pts.c | 403 +++++++++++++------------- components/lwp/unix98pty/lwp_pty.h | 81 +++--- 3 files changed, 469 insertions(+), 440 deletions(-) diff --git a/components/lwp/unix98pty/lwp_ptmx.c b/components/lwp/unix98pty/lwp_ptmx.c index 3b9e31ca6d..2a857c204f 100644 --- a/components/lwp/unix98pty/lwp_ptmx.c +++ b/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); diff --git a/components/lwp/unix98pty/lwp_pts.c b/components/lwp/unix98pty/lwp_pts.c index 9b7858270f..fc16d761c4 100644 --- a/components/lwp/unix98pty/lwp_pts.c +++ b/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 #include 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.); diff --git a/components/lwp/unix98pty/lwp_pty.h b/components/lwp/unix98pty/lwp_pty.h index cd6acf6f95..7a78259c47 100644 --- a/components/lwp/unix98pty/lwp_pty.h +++ b/components/lwp/unix98pty/lwp_pty.h @@ -13,44 +13,44 @@ #include #if defined(RT_USING_POSIX_TERMIOS) -#include -#endif +#include +#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 #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__ */ -- Gitee