MS-RTOS 管道

更新时间:
2023-08-09
下载文档

MS-RTOS 管道

本章将介绍 MS-RTOS 管道的使用。

管道介绍

管道是一种半双工的通信方式,数据只能单向流动,MS-RTOS 的管道为命名管道,即在 /dev 目录下存在一个管道设备文件,写端以只写的方式调用 ms_io_open 函数打开该文件,读端以只读的方式打开该文件,返回管道的文件描述符,然后通过 MS-RTOS 的文件读写、操作接口读写、操作管道,完成进程间通信。

注意

进程创建的管道如果已经完全被关闭(即写端、读端都关闭),管道设备文件会被删除。 而内核创建的管道,需要使用 ms_io_unlink 函数删除。

管道相关 API

下表展示了管道相关的 API 在两个权限空间下是否可用:

API用户空间内核空间
ms_pipe_drv_register
ms_pipe_dev_create
ms_pipe_dev_create_ex
ms_pipe_dev_write

ms_pipe_drv_register()

  • 描述 注册管道驱动

  • 函数原型

ms_err_t ms_pipe_drv_register(void);
  • 参数

  • 返回值 MS-RTOS 内核错误码

  • 注意事项

  • 示例

ms_pipe_dev_create()

  • 描述 创建管道设备

  • 函数原型

ms_err_t ms_pipe_dev_create(const char *path, ms_size_t size);
  • 参数
输入/输出参数描述
[in]path管道设备文件的路径
[in]size管道的大小,必须 > 2
  • 返回值 MS-RTOS 内核错误码

  • 注意事项

  • 示例

ms_pipe_dev_create_ex()

  • 描述 创建管道设备,成功输出管道设备上下文供外部调用 ms_pipe_dev_write 函数

  • 函数原型

ms_err_t ms_pipe_dev_create_ex(const char *path, ms_size_t size, ms_ptr_t *ctx);
  • 参数
输入/输出参数描述
[in]path管道设备文件的路径
[in]size管道的大小,必须 > 2
[out]ctx管道设备上下文
  • 返回值 MS-RTOS 内核错误码

  • 注意事项

  • 示例

ms_pipe_dev_write()

  • 描述 写数据到管道设备

  • 函数原型

ms_ssize_t ms_pipe_dev_write(ms_ptr_t ctx, ms_const_ptr_t buf, ms_size_t len);
  • 参数
输入/输出参数描述
[in]ctx管道设备上下文
[in]buf需要写入的数据
[in]len需要写入的数据长度
  • 返回值 成功返回写入的数据长度,失败返回 -1

  • 注意事项

  • 示例

管道通信示例

写端进程创建并以只写方式打开管道设备文件:

#include <ms_rtos.h>
#include <stdlib.h>

int main (int argc, char **argv)
{
    int fd;

    if (ms_pipe_dev_create("/dev/pipe0", 128) < 0) {
        ms_printf("failed to create pipe\n");
        abort();
    }

    fd = ms_io_open("/dev/pipe0", O_WRONLY, 0666);

    while (1) {
        ms_io_write(fd, "hello", sizeof("hello") - 1);

        ms_thread_sleep_s(2);
    }

    ms_io_close(fd);

    return  (0);
}

读端进程以只读方式打开管道设备文件:

#include <ms_rtos.h>
#include <stdlib.h>

int main (int argc, char **argv)
{
    int fd;
    char buf[128];
    ms_ssize_t len;

    fd = ms_io_open("/dev/pipe0", O_RDONLY, 0666);

    while (1) {
        len = ms_io_read(fd, buf, sizeof(buf));

        if ((len < sizeof(buf)) && (len > 0)) {
            buf[len] = 0;
            ms_printf("i recv len %d %s\n", len, buf);
        } else {
            ms_printf("failed to read pipe!\n");
        }
    }

    ms_io_close(fd);

    return  (0);
}

管道支持 select 和 poll 操作:

#include <ms_rtos.h>
#include <stdlib.h>

int main (int argc, char **argv)
{
    int ret;
    int fd;
    char buf[128];
    ms_ssize_t len;
    ms_fd_set_t rfds;
    ms_timeval_t tv;

    fd = ms_io_open("/dev/pipe0", O_RDONLY, 0666);

    while (1) {
        FD_ZERO(&rfds);
        FD_SET(fd, &rfds);

        tv.tv_sec = 1;
        tv.tv_usec = 0;

        ret = ms_io_select(fd + 1, &rfds, NULL, NULL, &tv);
        if (ret > 0 && FD_ISSET(fd, &rfds)) {
            len = ms_io_read(fd, buf, sizeof(buf));
            if ((len < sizeof(buf)) && (len > 0)) {
                buf[len] = 0;
                ms_printf("i recv len %d %s\n", len, buf);
            } else {
                ms_printf("failed to read pipe!\n");
            }
        } else {
            ms_printf("failed to select pipe!\n");
        }
    }

    ms_io_close(fd);

    return  (0);
}

管道支持的 ioctl 命令

命令描述参数
MS_PIPE_CMD_GET_SIZE获得管道的大小ms_size_t 指针
MS_PIPE_CMD_GET_LEN获得管道里的数据的长度ms_size_t 指针
MS_PIPE_CMD_GET_SPACE获得管道的剩余空间长度ms_size_t 指针
MS_PIPE_CMD_FLUSH清空管道数据
MS_PIPE_CMD_WAIT_EMPTY等待管道数据被全部读出等待超时时间(单位 ms),ms_uint32_t 指针
MS_PIPE_CMD_GET_R_TIMEOUT获得读超时时间(单位 ms)ms_uint32_t 指针
MS_PIPE_CMD_SET_R_TIMEOUT设置读超时时间(单位 ms)ms_uint32_t 指针
MS_PIPE_CMD_GET_W_TIMEOUT获得写超时时间(单位 ms)ms_uint32_t 指针
MS_PIPE_CMD_SET_W_TIMEOUT设置写超时时间(单位 ms)ms_uint32_t 指针
文档内容是否对您有所帮助?
有帮助
没帮助