第11篇 zephyr 数据传递之LIFO

目录

摘要

1 概念

2 实现

2.1 定义LIFO

2.2 写数据项到LIFO

2.3 从LIFO中读数据

3 参考链接


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

摘要

LIFO是一个内核对象,实现了传统的后进先出(last in, first out)队列,允许线程和ISR添加或者移除任意大小的数据项。

1 概念

任意数量的LIFO可以被定义。引用lifo时,使用的是LIFO定义的内存地址,同样只要你的内存允许,就可以随便定义。

LIFO有如下关键属性:

一个queue,他存储已经被添加但是还没有被移除的数据项。这个queue是用简单的链表实现的(实际上就是一个由链表实现的队列)。LIFO的功能是基于这个后进先出的queue实现的,LIFO就相当于queue的head。

一个LIFO必须先初始化在使用,初始化设置这个队列为空。

LIFO的数据项对必须保持字(word,cortext-M是4字节)对齐,这个数据项的第一个字节被内核使用,用于存储在queue中下一个数据项的内存地址。因此,一个有N字节应用数据的数据项,需要占用N+4(or N+8, 64位系统中word是8字节)内存空间。如果使用k_lifo_alloc_put()个函数添加一个数据项到一个队列,就不需要指向下一个地址的保留word。因为这个函数会从线程的资源池中分配临时的内存用于存储下一个数据项的地址。

一个数据项可以被ISR或者线程添加,如果有正在等待数据项的线程(就是读取队列,队列中没有数据项,线程休眠了),那么添加一个数据项之后,数据项不被添加到LIFO的quue中,而是直接给等待的线程。也就是数据项不是由发送线程存储到LIFO的queue中,然后再由等在线程从queue中取出。而是直接从发送线程传给因为接收而等待的线程,不会经过queue的。相反,如果没有等待的接收线程,那么才会添加数据项到LIFO的queue。

一个数据可以被一个线程移除(也就是取出),如果LIFO中没有数据元素,那么线程可以选择等待LIFO不为空(就是说线程获取不到LIFO进入睡眠,当LIFO不为空的时候再唤醒)。可以有多个线程同时等待一个空的LIFO。当有数据项添加到LIFO中,那个优先级最高等待时间最长的线程,会优先唤醒去读取数据。

2 实现

2.1 定义LIFO

使用struct k_lifo类型定义一个LIFO变量。使用之前必须用k_lifo_init()进行初始化:

struct k_lifo my_lifo;

k_lifo_init(&my_lifo);

或者,在编译时使用K_LIFO_DEFINE宏定义和初始化一个LIFO:

K_LIFO_DEFINE(my_lifo);

2.2 写数据项到LIFO

可以调用k_lifo_put()函数,向LIFO中添加一个数据项。

下面的示例发送数据到一个或多个用户线程:

struct data_item_t {
    void *lifo_reserved;   /* 1st word reserved for use by lifo */
    ...
};

struct data_item_t tx_data;

void producer_thread(int unused1, int unused2, int unused3)
{
    while (1) {
        /* create data item to send */
        tx_data = ...

        /* send data to consumers */
        k_lifo_put(&my_lifo, &tx_data);

        ...
    }
}

也可以使用k_lifo_alloc_put()函数添加,那么添加的数据项内存中第一个word也是有效的,不会被内核占中。

2.3 从LIFO中读数据

可以调用k_lifo_get()从LIFO中读取一个数据项:

void consumer_thread(int unused1, int unused2, int unused3)
{
    struct data_item_t  *rx_data;

    while (1) {
        rx_data = k_lifo_get(&my_lifo, K_FOREVER);

        /* process lifo data item */
        ...
    }
}

3 参考链接

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值