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 指针 |