LIFO实现了传统的后进先出队列,允许线程和ISR添加和删除任何大小的数据项。
概念
可以定义任意数量的 LIFO(仅受可用 RAM 的限制)。每个后进先出都由其存储器地址引用。
后进先出具有以下主要特性:
- 已添加但尚未删除的数据项。队列作为简单的链表实现。
必须先初始化,然后才能使用。这会将其队列设置为空。
LIFO数据项必须在字边界上对齐
,因为内核保留的第一个字,用作指向队列中下一个数据项的指针。因此,保存N个字节的应用程序数据的数据项需要N+4或 N+8字节的内存。
如果使用k_lifo_alloc_put()
添加数据项,则数据项没有对齐或保留空间要求,而是从调用线程的资源池中临时分配额外的内存。
数据项可以通过线程或 ISR 添加到LIFO。如果等待线程存在,该项目直接提供给等待线程;否则,该项目将添加到LIFO的队列中。可以排队的项目数没有限制。
可以从线程中获取LIFO的数据项。如果LIFO的队列为空,则线程可以选择等待数据项。任意数量的线程可以同时等待空的LIFO。添加数据项时,会将其提供给等待时间最长的优先级最高的线程。
定义LIFO
LIFO是使用k_lifo
类型定义的变量。然后必须通过调用k_lifo_init()
对其进行初始化。
struct k_lifo my_lifo;
k_lifo_init(&my_lifo);
也可以通过调用K_LIFO_DEFINE
在编译时定义和初始化空的LIFO。
K_LIFO_DEFINE(my_lifo);
写入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()
将数据项添加到LIFO。使用此 API,无需为内核在数据项中的使用保留空间,而是从调用线程的资源池中分配额外的内存,直到读取该项。
读取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 */
...
}
}