zephyr笔记 2.5.2 LIFOs

xiaoxiao2021-02-28  58

1 前言

lifo是实现传统的后进先出(LIFO)队列的内核对象,允许线程和ISR添加和删除任何大小的数据项。

我正在学习 Zephyr,一个很可能会用到很多物联网设备上的操作系统,如果你也感兴趣,可点此查看帖子zephyr学习笔记汇总。

2 概念

可以定义任何数量的lifo,每个lifo都由其内存地址引用。

lifo具有以下关键属性:

已添加但尚未删除的数据项目队列。队列被实现为一个简单的链表。

在使用之前,lifo必须初始化。这将其队列设置为空。

LIFO数据项必须在4字节的边界上对齐,因为内核保留了项目的前32位,以用作指向队列中下一个数据项的指针。因此,保存N字节应用程序数据的数据项需要N + 4字节的内存。

数据项可以通过线程或ISR添加到lifo,该项目直接提供给等待的线程(如果存在); 否则该项目将被添加到lifo的队列中,可能排队的项目数量没有限制。

数据项可能会被线程从lifo中移除。如果lifo的队列是空的,线程可以选择等待给出数据项。任何数量的线程可能会同时在一个空的lifo上等待。 当数据项被添加时,它被赋予等待时间最长的最高优先级线程。

注意:内核确实允许ISR从lifo中移除一个数据项,但是如果lifo是空的,ISR不能尝试等待。

3 操作

3.1 定义一个LIFO

lifo使用 struct k_lifo 类型的变量来定义。它必须通过调用 k_lifo_init() 来初始化。

以下定义并初始化一个空的lifo。

struct k_lifo my_lifo; k_lifo_init(&my_lifo);

或者,可以通过调用 K_LIFO_DEFINE 在编译时定义并初始化一个空的 lifo。

以下代码与上面的代码段具有相同的效果。

K_LIFO_DEFINE(my_lifo);

3.2 写入 LIFO

通过调用 k_lifo_put() 将数据项添加到 lifo 中。

以下代码构建在上面的示例上,并使用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); ... } }

3.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 */ ... } }

4 建议用法

使用lifo以“后进先出”的方式异步传输任意大小的数据项。

5 配置选项

6 APIs

下列 lifo API,都在 kernel.h 中提供了:

K_LIFO_DEFINE k_lifo_init() k_lifo_put() k_lifo_get()

转载请注明原文地址: https://www.6miu.com/read-2627364.html

最新回复(0)