【原创】不同RTOS中POSIX接口的实现差异

文章目录

  • 前言
  • POSIX简介
  • RTOS对POSIX的实现情况
    • Zephyr
    • FreeRTOS
  • RTOS提供的POSIX接口实时吗?
    • nanosleep
    • Timer-不同linux版本和xenomai的实现差异
      • PREEMPT-RT Timer实现原理
      • Xenomai Timer实现原理
  • 总结
  • 参考

前言

在开发实时应用时,我们希望软件具备良好的跨平台和可移植,既能在实时linux也能在RTOS上工作,为实现这个目的,我们会选择使用POSIX API来设计实时应用,实现在不同的操作系统和平台上的可移植性。这样只要有POSIX支持,应用程序从一个操作系统移植到另一个操作系统,无需对源代码进行较大的修改,可以减少很多重复工作(想象很美好)。

但是,实时应用除关注接口基本功能一致外,还关注接口的实时性(执行时间确定性),那不同的实时操作系统的POSIX底层实现/行为实不实时呢?

以精确定时为例,精确定时是我们常用的操作系统服务之一,比如工业以太网(ECAT、PN…)中的通信周期,通信周期的准确控制离不开精确定时;在无线基站和终端的slot调度中,精确定时确保了数据传输的有序与高效;在实时仿真中,仿真步长的精确控制更是模拟真实场景的关键等等,这些都离不开POSIX定时接口。

本文首先简要概述POSIX标准,随后深入剖析POSIX定时接口在常用开放内核源码的RTOS(实时操作系统)上的上的实现原理做简单介绍。通过本文的介绍,希望能为读者在实际应用中提供有价值的参考,避免在RTOS中使用POSIX遇到不必要的困扰。

POSIX简介

POSIX是 IEEE(Institue of Electrical and Electronics Engineers,电气和电子工程师学会)为了规范各种 UNIX 操作系统提供的 API 接口而定义的一系列互相关联标准的总称,其正式称呼为 IEEE1003,国际标准名称为 ISO / IEC9945。此标准源于一个大约开始于 1985 年的项目。

POSIX 这个名称是由理查德 · 斯托曼(Richard Stallman)应 IEEE 的要求而提议的一个易于记忆的名称。它是 Portable Operating System Interface(可移植操作系统接口)的缩写,而 X 则表明其对 Unix API 的传承。POSIX更能正确表示这一系列相关标准,所以术语POSIX最初被用作IEEE Std 1003.1-1988的同义词,即POSIX.1(n=1)。这保持了符号“POSIX”可读性的优点,而不会与POSIX系列标准产生歧义。

关于有关POSIX. 1的背景、受众和目的的更多信息,参看该链接https://www.opengroup.org/austin/papers/backgrounder.html

https://www.opengroup.org/austin/papers/posix_faq.html

POSIX标准涉及操作系统方方面面,我们主要关注以下两个标准:

  • IEEE Std 1003.1 “便携式操作系统接口 (POSIX™)”–最初主要针对 UNIX 系统,1988 年第一版,2018 年最新版
  • IEEE Std 1003.13 “标准化应用环境配置文件(AEP)–POSIX™ 实时和嵌入式应用支持”

IEEE Std 1003.1标准,最初只用于UNIX系统。POSIX定义了一系列应用程序编程接口(API),用于在源代码级别实现可移植性。POSIX最早发布于1988年,最新版本于2018年发布。它提供了一种标准化的应用程序环境配置文件(AEP),用于实现实时和嵌入式应用程序的支持。通过遵循POSIX标准,开发人员可以编写与POSIX兼容的源代码,从而实现在不同的操作系统和平台上的可移植性。这使得开发人员能够更轻松地将应用程序从一个操作系统移植到另一个操作系统,而无需对源代码进行较大的修改。

POSIX.13(IEEE Std 1003.13)对实时和嵌入式应用程序的支持:IEEE Std 1003.13-2003是一个针对实时系统的标准,提供了对嵌入式应用程序的支持,实时配置文件可总结如下。该标准定义了几个实时系统Profiles,所有Profiles都包括部分或全部POSIX.1、.1b和.1c,以及开发平台的POSIX.2和.2a的部分内容,这些Profiles分别为PSE51、PSE52、PSE53和PSE54。

  • PSE51:最小实时配置文件(Minimal real-time)适用于资源受限的嵌入式系统。它提供了最基本的实时功能,包括任务调度、中断处理和简单的同步机制,这个子集不需要多进程(线程)和文件系统。
  • PSE52:实时控制器配置文件(Realtime controller)适用于需要严格的实时控制和调度的系统。它在PSE51的基础上增加了简单文件系统和消息队列等功能,提供了精确的任务调度、硬实时响应和实时数据处理能力。
  • PSE53:专用实时配置文件(Dedicated real-time)适用于需要高度可预测性和可靠性的实时系统。它提供了多进程、网络支持,更强大的实时功能,包括任务优先级管理、严格的时间限制和实时资源管理。
  • PSE54:多用途实时配置文件(Multi-purpose real-time)适用于需要同时支持多种实时应用的系统。它提供了完整的文件系统、shell,灵活的任务调度、多任务并发和多种实时通信机制。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

综上,PSOXI标准不仅包含应用开发时常说的POSIX API,还包括文件系统、网络、shell等整个应用程序的运行环境。

目前符合 POSIX 标准协议的操作系统有:UNIX、BSD、Linux、iOS、Android、SylixOS、VxWorks、RTEMS、LynxOS 等,由于这些OS对 POSIX 的支持,其他兼容 POSIX 系统上的应用程序可以非常方便地移植到这些系统上。

RTOS对POSIX的实现情况

这里简单介绍几个常用RTOS的POSIX支持情况:

RTOSPOSIX支持情况
PREEMPT-RT完全兼容
Xenomai完全兼容,实时部分xenomai内核和libcobalt提供,非实时部分linux内核和glibc提供
VxWorksUser space(RTP):POSIX.13 PSE52 (少数接口存在限制)Kernel space:POSIX.1部分接口和POSIX.1可选功能中的一些实时接口
RTEMSPOSIX 1003.1b-1993. POSIX 1003.1b-1993。POSIX 1003.1h/D3.Open Group Single UNIX Specification.单进程;
SylixOS兼容IEEE 1003(ISO/IEC 9945)操作系统接口规范兼容POSIX 1003.1b(ISO/IEC 9945-1)实时编程的标准
ZephryPSE54
EcOS 3.0ISO/IEC 9945—1(少部分省略)
FreeRTOS实验性,仅实现了约 20% 的 POSIX API
RT-Thread未找到明确说明,从源码上看兼容大部分POSIX

Zephyr

详见Zephyr开发文档https://docs.zephyrproject.org/latest/samples/posix/philosophers/README.html

Zephyr支持路线图 https://static.sched.com/hosted_files/eoss24/40/ZDS-2024-POSIX-Roadmap-for-Zephyr-LTSv3.pdf

FreeRTOS

FreeRTOS-Plus-POSIX 可实现 POSIX 线程 API 的小子集。借助此子集,熟悉 POSIX API 的应用程序开发者可使用类似线程原语的 POSIX 开发 FreeRTOS 应用程序。FreeRTOS-Plus-POSIX 仅实现了约 20% 的 POSIX API。因此,无法仅使用此包装器将现有的 POSIX 兼容应用程序或 POSIX 兼容库移植到 FreeRTOS 内核上运行。

FreeRTOS-Plus-POSIX 实现了部分 IEEE Std 1003.1-2017 版《开放组技术标准基础规范》,第 7 期。FreeRTOS-Plus-POSIX 包括以下 POSIX 线程标头文件的实现,详细信息请参阅 FreeRTOS-Plus-POSIX API 文档了解。

需要注意的是:FreeRTOS posix接口不支持动态创建任务,即开始调度后不能再创建新的任务。

RTOS提供的POSIX接口实时吗?

在实时应用场景中,精确定时是我们常用的接口,比如工业以太网ECAT、PN中的通信周期,无线基站/终端中的slot调度,实时仿真中的仿真步长等等。

POSIX中常用的定时接口有nanosleep()、clock_nanosleep()、timer_create()/timer_settime()等,但这些RTOS实现的POSIX实时吗?或者说定时精度如何?

nanosleep

在POSIX标准中,对nanosleep()睡眠时间分辨率的定义为1/HZ,即操作系统的Tick周期时间,意味着实际睡眠分辨率与系统时钟滴答周期近似,下表总结了常见RTOS的nanosleep()底层实现及精度,从标准上看,这些RTOS都符合POSIX标准,但HZ不足以支撑很多us级定时应用场景。

RTOS实现原理精度
PREEMPT-RT高精度hrtimer,每次定时最终由硬件timer中断handler中唤醒ns
Xenomai高精度hrtimer,每次定时最终由硬件timer中断handler中唤醒ns
VxWorks睡眠时间转换对齐到TickTick
RTEMS
SylixOS未启用LW_CFG_TIME_HIGH_RESOLUTION_EN时,睡眠时间转换为Tick,每个Tick中统一处理;启用LW_CFG_TIME_HIGH_RESOLUTION_EN后,CPU不足一个Tcik的nanosleep转换为while(1)死等时间到达Tick或ns
Zephry睡眠时间转换为TickTick
EcOS 3.0睡眠时间转换为TickTick
FreeRTOS睡眠时间转换为TickTick
RT-Thread5.x版本虽然实现了hrtimer逻辑,但是你用时会发现是个半成品,可以选择一个硬件Timer来实现hrtimer底层定时,但是这样每次只能有一个任务处于定时状态(用全局变量来维护timer的参数,且ctime层 hrtime、cputime接口职责隔离不清晰,无可扩展性,可以看出"能跑就行",质量堪忧);默认情况下还是基于Tick。Tick或ns

这里不得不提一下,一些操作系统所宣传的ns级延时,基本指的是逻辑如下,对于用惯了xenomai/Peempt-RT的hrtimer来说,不明白CPU死等的方式有什么值得宣传的(这让我想起了郭天祥…)。

udeley(){
  do {
       从硬件读取当前时间;
  } while (当前时间未到达指定时间);
}

Timer-不同linux版本和xenomai的实现差异

计时器管理器提供的服务包括:

  • timer_create - 创建每进程定时器
  • timer_delete - 删除每进程定时器
  • timer_settime - 设置下一个定时器的到期时间
  • timer_gettime - 获取定时器的剩余时间
  • timer_getoverrun - 获取定时器超时计数

在xenomai中,我们通常会通过如下方式来定时触发周期任务:

sev.sigev_notify = SIGEV_THREAD_ID | SIGEV_SIGNAL;
sev.sigev_signo = SIGUSR1;
sev.sigev_value.sival_ptr = &timerid;
sev.sigev_notify_thread_id = get_thread_pid();

/*timer create*/
timer_create(CLOCK_MONOTONIC, &sev, &timerid);

/* Start the timer */
timer_overrun = timer_getoverrun(timerid);

/*get current time*/
err = clock_gettime(CLOCK_MONOTONIC, &now);

tspec.it_value = now;
tspec.it_value.tv_sec += 0;
tspec.it_value.tv_nsec += 2000000;
tsnorm(&tspec.it_value);
tspec.it_interval.tv_sec = 0;
tspec.it_interval.tv_nsec = 1000000;  /**/
timer_settime(timerid, TIMER_ABSTIME, &tspec, NULL);
while (1)
    s = sigwait(&GlobalSignalMaskSet, &sig);
    /*.............*/
}

但是,PREEMPT-RT和xenomai中关于timer的接口底层实现有区别:

PREEMPT-RT Timer实现原理

大家都知道,linux中断分为上半部和下半部,未启用PREEMPT-RT时,上半部表示硬件中断上下文,即响应中断就直接执行中断上半部;

启用PREEMPT-RT后,有所不同,通常上半部由中断线程来处理,即中断产生后,唤醒中断线程来处理中断上半部,此时中断上半部在线程上下文执行。并不是所有中断都是中断线程来执行,比如系统Timer中断就是不能中断线程化的,还是在硬件中断上下执行。对于中断下半部,基本没有变化,还是由softirq、workqueue线程等执行。

linux内核中,进程创建的每个timer都会对应内核中高精度timer的一个对象,这些hrtimer用红黑树组织,所有timer最后由硬件timer中断驱动运行,运行原理如下:

  • 未启用PREEMPT-RT时,hrtimer由Hrtimer softirq驱动,即硬件定时超时,唤醒软中断处理,软中断线程检查hrtimer超时情况,并调用对应的超时处理函数,超时处理函数中会唤醒对应的线程;
  • 启用PREEMPT-RT后,情况有所有不同,在PREEMPT-RT中,hrtimer分为两类,一类是在硬中断上下执行超时回调(HRTIMER_MODE_HARD),一类在软中断上下文执行超时回调(HRTIMER_MODE_SOFT);
    • 对于HRTIMER_MODE_HARD因为在中断上下文执行的超时回调,时延低,任务定时精度高;
    • 对于HRTIMER_MODE_SOFT timer,软中断到期模式的高精度定时器,到期的时候在类型为HRTIMER_SOFTIRQ的软中断里面执行定时器回调函数。在实时内核中,软中断由软中断线程执行,或者在进程开启软中断的时候执行,任务时延高定时不精确。
    • 如果没有指定到期模式,那么在实时内核中默认使用软中断到期模式。

那PREEMPT-RT中,POSIX API底层用的是HRTIMER_MODE_HARD还是HRTIMER_MODE_SOFT?

APItimer类型
nanosleep()clock_nanosleep()HRTIMER_MODE_HARD
timer_create()+timer_settime()4.16版本以前高精度定时器总是在硬中断里面执行定时器回调函数,所以timer相关接口定时精确,详见https://www.spinics.net/lists/kernel/msg3208465.html4.16版本及以后版本增加HRTIMER_MODE_SOFT,timer系列接口定时不再精确(不实时,抖动大)。

Xenomai Timer实现原理

原理,详见本博客博文xenomai时间子系统。

xenomai内核提供的所有POSIX接口都是实时的。

总结

我们仅比较了两个实时应用常见API在不同RTOS中的实现,应该明白,POSIX只是一个API标准,不同的系统底层实现不同,我们在将我们的实时任务移植适配到不同的RTOS的时候,需要事先评估用到的POSIX接口在这些RTOS上的实时行为与我们的期待是否相符。

参考

https://www.baeldung.com/linux/posix

https://unix.stackexchange.com/questions/11983/what-exactly-is-posix

https://static.sched.com/hosted_files/eoss2023/2e/Zephyr%20RTOS%20-%20Posix.pdf

VxWorks_7_programmers_guide.pdf

https://docs.rtems.org/branches/master/posix-users/index.html

https://ecos.sourceware.org/docs-latest/ref/posix-standard-support.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/605603.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用于密集预测任务的通道知识蒸馏——关键字:蒸馏

摘要 https://arxiv.org/pdf/2011.13256 知识蒸馏(KD)已被证明是训练紧凑密集预测模型的简单有效工具。通过从大型教师网络转移而来的额外监督来训练轻量级学生网络。大多数先前的针对密集预测任务的KD变体都在空间域中对学生网络和教师网络的激活图进行对齐,通常是通过在每…

实验9:WLAN配置管理(课内实验)

实验9:WLAN配置管理 实验目的及要求: 掌握无线局域网络无线路由器和无线网络控制器的配置与应用。能够完成配置SSID隐藏、密码认证,远程站点WLAN配置和WLC配置等无线网络配置,完成网络连通性测试。 实验设备: 无线…

吴恩达2022机器学习专项课程C2(高级学习算法)W1(神经网络):2.5 更复杂的神经网络

目录 示例填写第三层的层数1.问题2.答案 公式:计算任意层的激活值激活函数 示例 层数有4层,不包括输入层。 填写第三层的层数 1.问题 你能把第二个神经元的上标和下标填写出来吗? 2.答案 根据公式g(wxb),这里的x对应的是上…

C# IO下的文件和目录详解

文章目录 1、文件和目录的基本概念2、文件的操作方法打开文件:读取文件:写入文件:删除文件:文件权限 3、目录的操作方法创建目录:遍历目录:删除目录目录权限 4、文件和目录的属性与信息5、文件和目录的相对…

钟表——蓝桥杯十三届2022国赛大学B组真题

问题分析 这个问题的关键有两点:1.怎么计算时针,分针,秒针之间的夹角,2.时针,分针,秒针都是匀速运动的,并非跳跃性的。问题1很好解决看下面的代码就能明白,我们先考虑问题2&#xf…

数字图像处理知识点

数字图像处理知识点 一、绪论1、数字图像处理相关概念2、数字图像处理流程1.3 数字图像处理主要研究内容二、视觉与色度基础1、图像传感器与二维成像原理2、三基色2.1 三基色原理2.2 亮度方程3、HSI模型3.1 HSI模型优点3.2 RGB到HSI转换三、数字图像处理基础1、图像的数字化及表…

unreal engine5.3.2 Quixel bridge无法登陆

UE5系列文章目录 文章目录 UE5系列文章目录前言一、问题定位二、解决方法 前言 这几天unreal engine5.3.2 Quixel bridge无法登陆,输入epic 账号和密码,然后在输入epic发送的验证码,总是提示登录失败。就算是使用科学上网依然无法登录。而且…

linux Shell编程之条件语句

条件测试操作 test命令 条件测试操作 Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0(真true)时表示成功,返回值为非0值(假false)时表示失败或异常。 t…

Python深度学习基于Tensorflow(5)机器学习基础

文章目录 监督学习线性回归逻辑回归决策树支持向量机朴素贝叶斯 集成学习BaggingBoosting 无监督学习主成分分析KMeans聚类 缺失值和分类数据处理处理缺失数据分类数据转化为OneHot编码 葡萄酒数据集示例 机器学习的流程如下所示: 具体又可以分为以下五个步骤&#…

转转小程序数据处理

声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!wx a15018601872,x30184483x…

[Cmake Qt]找不到文件ui_xx.h的问题?有关Qt工程的问题,看这篇文章就行了。

前言 最近在开发一个组件,但是这个东西是以dll的形式发布的界面库,所以在开发的时候就需要上层调用。 如果你是很懂CMake的话,ui_xx.h的文件目录在 ${CMAKE_CURRENT_BINARY_DIR} 下 然后除了有关这个ui_xx.h,还有一些别的可以简…

数据分析概念定义和发展前景

数据分析概念定义和发展前景 前言一、数据分析概念二、数据的定义数据的定义数据的分类定性数据定量数据 三、数据的价值数据为什么具有价值 四、数据分析的目的对于企业来说总结 五、数据分析类型的划分描述性统计分析探索性数据分析传统的统计分析方法验证性数据分析 六、 数…

springboot本地文件同步到nacos 本地文件上传到nacos 使用nacos

导入依赖 <!--配置文件使用nacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>nacos版本</version></dependency><dependency…

vscode 实现本地服务器部署小结

在查阅 MDN 网站的时候&#xff0c;偶然发现的原来 vscode 也可以实现本地化服务器部署&#xff0c;来模拟服务器的运行。 安装插件 在VSCode的插件市场搜索并安装以下插件&#xff1a; – Live Server&#xff08;用于开启本地服务器&#xff09; – Debugger for Chrome&a…

nlp课设 - 基于BERT 的情感分类

基于BERT 的情感分类 主要论文&#xff1a; BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding&#xff08;双向Transformer 的预训练&#xff09; 核心技术&#xff1a; Embedding 、Attention --> Transformer 任务简介、拟解决问题…

HTML5 Canvas发光Loading动画特效源码

源码介绍 之前我们分享过很多基于CSS3的Loading动画效果&#xff0c;相信大家都很喜欢。今天我们要来分享一款基于HTML5 Canvas的发光Loading加载动画特效。Loading旋转图标是在canvas画布上绘制的&#xff0c;整个loading动画是发光3D的视觉效果&#xff0c;HTML5非常强大。 …

Leetcode127.单词接龙

https://leetcode.cn/problems/word-ladder/description/?envTypestudy-plan-v2&envIdtop-interview-150 文章目录 题目描述解题思路代码-BFS解题思路二——双向BFS代码 题目描述 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 …

【HTTP下】总结{重定向/cookie/setsockopt/流操作/访问网页/总结}

文章目录 1.请求头2.cookie理解 3.vim跳转/搜索4.setsockopt被重用的意思 5.流操作5.1定位读取指针5.2ifstram::read() 6.总结6.1 百度搜索框搜索功能字符6.2请求uri请求和响应的第一行都有http版本请求内容里有GET /favicon.ico HTTP/1.1 6.3访问网页Fiddler抓包原理&#xff…

Hive SQL-DML-Load加载数据

Hive SQL-DML-Load加载数据 在 Hive 中&#xff0c;可以使用 SQL DML&#xff08;Data Manipulation Language&#xff09;语句中的 LOAD 命令来加载数据到表中。LOAD 命令用于将本地文件系统或 HDFS&#xff08;Hadoop 分布式文件系统&#xff09;中的数据加载到 Hive 表中。 …

0508_IO3

练习1&#xff1a; 1&#xff1a;使用 dup2 实现错误日志功能 使用 write 和 read 实现文件的拷贝功能&#xff0c;注意&#xff0c;代码中所有函数后面&#xff0c;紧跟perror输出错误信息&#xff0c;要求这些错误信息重定向到错误日志 err.txt 中去 1 #include <stdio.h…