文章目录

  • 前言
  • 1. Queues
  • 2. FIFOs (LIFOs)
    • 2.1 Concepts
    • 2.2 Implementation
      • 2.2.1 Defining a FIFO (LIFO)
      • 2.2.2 Writing to a FIFO (LIFO)
      • 2.2.3 Reading from a FIFO (LIFO)
    • 2.3 Suggested Uses
    • 2.4 Configuration Options
  • 参考链接

本笔记基于 Zephyr 版本 2.6.0-rc2

前言

本人正在学习 Zephyr,一个可移植性较强,可以兼容多种开发板及物联网设备的操作系统,如果你感兴趣,可以点此查看我的 学习笔记总述 进行了解!

1. Queues

Zephyr 中的 Queue 是一个内核对象,它实现了一个传统的队列,允许线程和 ISR 添加和删除任何大小的数据项。队列类似于 FIFO,是 k_fifok_lifo 的底层实现。有关用法的更多信息,请参见 k_fifo (k_lifo)。

2. FIFOs (LIFOs)

2.1 Concepts

可以定义任意数量的 FIFO(LIFO) (仅受可用 RAM 限制)。每个 FIFO(LIFO) 由其内存地址引用。

FIFO(LIFO) 具有以下关键属性:

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

FIFO(LIFO) 数据项必须在字边界上对齐,因为内核保留项的第一个字,用作指向队列中下一个数据项的指针。 因此,包含 N 字节应用程序数据的数据项需要 N+4 (或 N+8)字节的内存。如果使用 k_fifo_alloc_put() (k_lifo_alloc_put()) 添加数据项,则不需要对齐或预留空间,而是从调用线程的资源池中临时分配额外的内存。

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

一个数据项可以由一个线程从 FIFO(LIFO) 中删除。如果 FIFO(LIFO) 的队列是空的,那么线程可以选择等待给定的数据项。任意数量的线程可以同时等待一个空的 FIFO(LIFO)。添加数据项时,会将其分配给等待时间最长的最高优先级线程。

Note:
内核允许 ISR 从 FIFO(LIFO) 中移除一个项目,但是如果 FIFO(LIFO) 是空的,ISR 不能尝试等待。

如果需要,多个数据项可以在单个操作中添加到 FIFO 中,如果它们被链接到一个单链表中。如果多个编写者向 FIFO 添加相关数据项集,则此功能可能非常有用,因为它确保每个数据集中的数据项不与其他数据项交叉。向 FIFO 中添加多个数据项也比一次添加一个数据项更有效,并可用于确保任何删除集合中的第一个数据项的人都能够删除其余的数据项,而无需等待。

2.2 Implementation

2.2.1 Defining a FIFO (LIFO)

FIFO(LIFO) 是使用 k_fifo (k_lifo) 类型的变量定义的。然后必须通过调用 k_fifo_init() (k_lifo_init()) 来初始化它。

以下代码定义并初始化一个空的 FIFO(LIFO)。

struct k_fifo my_fifo;k_fifo_init(&my_fifo);或struct k_lifo my_lifo;k_lifo_init(&my_lifo);

或者,可以在编译时通过调用 K_FIFO_DEFINE (K_LIFO_DEFINE) 来定义和初始化一个空的 FIFO(LIFO)。

下面的代码和上面的代码段效果一样。

K_FIFO_DEFINE(my_fifo);或K_LIFO_DEFINE(my_lifo);

2.2.2 Writing to a FIFO (LIFO)

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

以下代码建立在上述示例的基础上,并使用 FIFO(LIFO) 将数据发送到一个或多个消费者线程。

struct data_item_t {void *fifo_reserved;   /* 1st word reserved for use by FIFO */...
};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_fifo_put(&my_fifo, &tx_data);...}
}
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_fifo_put_list()k_fifo_put_slist() 将数据项的单向链接列表添加到 FIFO。

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

2.2.3 Reading from a FIFO (LIFO)

通过调用 k_fifo_get() 从 FIFO(LIFO) (k_lifo_get()) 中删除数据项。

以下代码建立在上述示例的基础上,并使用 FIFO(LIFO) 从生产者线程获取数据项,然后以某种方式对其进行处理。

void consumer_thread(int unused1, int unused2, int unused3)
{struct data_item_t  *rx_data;while (1) {rx_data = k_fifo_get(&my_fifo, K_FOREVER);/* process FIFO data item */...}
}
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 */...}
}

2.3 Suggested Uses

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

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

2.4 Configuration Options

相关配置选项:

  • None

参考链接

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

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

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

Zephyr RTOS -- FIFO (LIFO)相关推荐

  1. 在Zephyr RTOS上实现一个轮询系统

    近日在设计一个服务系统,使用的是RTOS,因为是实时操作系统,所以有时候需要进行切片,需要跑不同的任务,所以需要让它多线程起来,这里是我实现的一些思路,分享给大家,在实时RTOS上如何设计一款轮询系统 ...

  2. 进销存管理(FIFO,LIFO)

    先进先出法 first-in,firs-tout (FIFO)     是一种存货评价(inventory valuation)方法,所根据的概念是商品是以其进货顺序出售,或是以其进货顺序被用于生产活 ...

  3. Zephyr RTOS -- Threads

    文章目录 前言 Threads - (线程) 1. Lifecycle - (生命周期) 1.1 Thread Creation - (线程创建) 1.2 Thread Termination - ( ...

  4. 桌面版应用_【Nordic博文分享系列】开发你的第一个NCS(Zephyr)应用程序

    Nordic有2套并存的SDK 1.老的nRF5 SDK 2.新的NCS SDK 两套SDK相互独立, 大家选择其中一套进行开发即可. 一般而言,如果你选择的芯片是nRF51或者nRF52系列,那么推 ...

  5. 基于Zephyr在微型MCU上使用Tensor Flow Lite Micro做图像分类

    首先需要保证你已经拥有了一个图像分类的模型. 其次我们需要Zephyr RTOS. 这些可以参考如下文章: 基于Stm32F746g_disg平台下移植zephry使用TinyML预测模型_17岁bo ...

  6. java lifo 队列_java - 如何在LIFO模式下实现链接的阻塞队列 - SO中文参考 - www.soinside.com...

    如何在LIFO模式下实现链接的阻塞队列 问题描述 投票:0回答:1 标题已经说明了一切,在我的代码中,我有一个实现链接阻止队列并提供在队列中插入和获取元素的方法的对象,我希望从队列中进行插入/提取. ...

  7. SQL实现FIFO算法:库龄继承、配额分析

    1.背景 为了保证集团成品/物料的跌价计提统一正确,集团子公司内部交易场景中,由A公司转卖成品/物料到B公司,需要实现账龄继承(即:物料在A公司账龄为36,转卖到B公司后,该物料账龄为36,不能从0开 ...

  8. Zephyr Power Management Subsystem详细介绍

    目录 简介 前景补充 SOC Interface IDLE Thread * Tickless Idle Power Gating Power State Device Runtime Power M ...

  9. 四种Java线程池用法解析

    四种Java线程池用法解析 本文为大家分析四种Java线程池用法,供大家参考,具体内容如下 http://www.jb51.net/article/81843.htm 1.new Thread的弊端 ...

  10. Java多线程的11种创建方式以及纠正网上流传很久的一个谬误

    创建线程比较传统的方式是继承Thread类和实现Runnable,也可以用内部类,Lambda表达式,线程池,FutureTask等. 经常面试会问到继承Thread类和实现Runnable的区别,然 ...

最新文章

  1. Firefox Quantum 向左,Google Chrome 向右
  2. linux truss strace ltrace 对比 诊断调试程序
  3. 原码, 反码, 补码, 移码 详解
  4. 利用Web Services开发分布式应用
  5. JUC系列(五)| Synchonized关键字进一步理解
  6. json类的解析,调试实例
  7. 在linux下dns绑定域名,在Linux系统中,使用Bind搭建DNS域名解析服务
  8. 怎样修改MFC中应用程序标题的图标?
  9. json转excel_如何快速把json数据转到excel表格,方便个人查看
  10. Latex中的常用公式模板
  11. 【Linux_Fedora_应用系列】_1_如何安装音乐播放器和mp3解码
  12. Xgboost通俗理解和总结
  13. 整人电脑BAT小程序源码大全
  14. Django-ftpserver 的两个坑
  15. Vue之解析PSD文件(文字)
  16. 深入理解泊松分布、指数分布、正态分布
  17. Netflix-Eureka服务注册与发现说明文档
  18. sublime去掉空行 sublime批量删除空白行
  19. 计算机英语videos啥意思,video是什么意思_video翻译_读音_用法_翻译
  20. sublime的注册方法 非常好用

热门文章

  1. Mysql按时间区段(每隔30分钟)统计数据并展示
  2. linux下修改tomcat默认访问主页
  3. Excel中Sheet(s)和Worksheet(s)的区别
  4. 显卡的优化以提高计算机性能作用,显卡优化,教您如何设置NVIDIA(英伟达)显卡玩游戏性能更高...
  5. 猫和计算机连接网络,计算机路由器与猫的连接方法步骤
  6. kubernetes in action读书笔记(四)ConfigMap、Secret、滚动升级、downwardAPI、Deployment、Statefulset
  7. 树形数据结构——ClosureTable
  8. js跟php增加删除信息,JavaScript动态增加节点和删除节点
  9. 移动应用跨平台框架江湖将现终结者?速来参拜来自Facebook的React Native
  10. sgm3157功能_SGM3157