第15篇 zephyr 数据传递之Pipes

目录

摘要

1 概念

2 实现

2.1 定义一个PIPE

2.2 写数据到PIPE

2.3 从PIPE读数据

3 参考链接


本学笔记基于zephyr 工程版本 2.2.99,主机环境为ubuntu18.04,开发平台 nrf52840dk_nrf52840

摘要

PIPE(管道)是一个内核对象,可以用于发送数据流到另一个线程。管道用于同步或者异步传输一整块数据,或者一部分数据。

1 概念

管道可以被配置使用一个ring buffer,去存储那些已经被发送,但是没有被接收的数据。也可以不是使用ring buffer。

任意数量的管道可以被定义。引用管道时,使用的是管道的地址。

管道的关键属性:

size:表示管道的ring buffer的大小。如果这值是0,那么代表不使用 ring buffer。

管道使用之前必须被初始化。初始化后管道被设置成空。

2 实现

2.1 定义一个PIPE

可以使用struct k_pipe类型定义一个管道变量,定义一个可选的unsigned char 类型的buffer。它必须使用k_pipe_init()去初始化。

下面示例代码,定义并初始化一个包含100字节(4字节对齐)buffer的管道。

unsigned char __aligned(4) my_ring_buffer[100];
struct k_pipe my_pipe;

k_pipe_init(&my_pipe, my_ring_buffer, sizeof(my_ring_buffer));

或者,在编译时使用K_PIPE_DEFINE宏去定义和初始化一个PIPE。

下面代码与上面的功能相同:

K_PIPE_DEFINE(my_pipe, 100, 4);

2.2 写数据到PIPE

可以使用k_pipe_put()写数据到管道。

下面的示例代码,使用一个管道传输数据,数据从一个"生产"线程到一个或多个“消费”线程。如果由于消费线程没有及时读取数据,那个这个管道会被填满。生产线程将等待一段时间。

struct message_header {
    ...
};

void producer_thread(void)
{
    unsigned char *data;
    size_t total_size;
    size_t bytes_written;
    int    rc;
    ...

    while (1) {
        /* Craft message to send in the pipe */
        data = ...;
        total_size = ...;

        /* send data to the consumers */
        rc = k_pipe_put(&my_pipe, data, total_size, &bytes_written,
                        sizeof(struct message_header), K_NO_WAIT);

        if (rc < 0) {
            /* Incomplete message header sent */
            ...
        } else if (bytes_written < total_size) {
            /* Some of the data was sent */
            ...
        } else {
            /* All data sent */
            ...
        }
    }
}

2.3 从PIPE读数据

可以使用k_pipe_get()读取管道数据。

下面的示例使用管道处理“生产”线程的数据:

void consumer_thread(void)
{
    unsigned char buffer[120];
    size_t   bytes_read;
    struct message_header  *header = (struct message_header *)buffer;

    while (1) {
        rc = k_pipe_get(&my_pipe, buffer, sizeof(buffer), &bytes_read,
                        sizeof(header), K_MSEC(100));

        if ((rc < 0) || (bytes_read < sizeof (header))) {
            /* Incomplete message header received */
            ...
        } else if (header->num_data_bytes + sizeof(header) > bytes_read) {
            /* Only some data was received */
            ...
        } else {
            /* All data was received */
            ...
        }
    }
}

3 参考链接

https://docs.zephyrproject.org/latest/reference/kernel/data_passing/pipes.html

发布了51 篇原创文章 · 获赞 55 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/huohongpeng/article/details/105694438