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()对其进行初始化。

  1. struct k_lifo my_lifo;
  2. k_lifo_init(&my_lifo);

也可以通过调用K_LIFO_DEFINE在编译时定义和初始化空的LIFO。

  1. K_LIFO_DEFINE(my_lifo);

写入LIFO

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

  1. struct data_item_t {
  2. void *LIFO_reserved; /* 1st word reserved for use by LIFO */
  3. ...
  4. };
  5. struct data_item_t tx data;
  6. void producer_thread(int unused1, int unused2, int unused3)
  7. {
  8. while (1) {
  9. /* create data item to send */
  10. tx_data = ...
  11. /* send data to consumers */
  12. k_lifo_put(&my_lifo, &tx_data);
  13. ...
  14. }
  15. }

可以使用k_lifo_alloc_put()将数据项添加到LIFO。使用此 API,无需为内核在数据项中的使用保留空间,而是从调用线程的资源池中分配额外的内存,直到读取该项。

读取LIFO

通过调用k_lifo_get()从LIFO中读取数据项。

  1. void consumer_thread(int unused1, int unused2, int unused3)
  2. {
  3. struct data_item_t *rx_data;
  4. while (1) {
  5. rx_data = k_lifo_get(&my_lifo, K_FOREVER);
  6. /* process LIFO data item */
  7. ...
  8. }
  9. }