望获实时Linux:亚微秒级时间控制

本期内容是基于飞腾派与望获实时Linux的高精度信号发生器方案。该方案借助望获实时 Linux 的亚微秒级响应能力,实现抖动不超过50纳秒的稳定信号输出,可用于代替FPGA、DSP、ASIC等传统方案。

接下来我们将展示基于飞腾派的信号发生器的亚微秒级时间控制测试全过程以及技术方案解析。

【Linux极限探索之三】亚微秒级时间控制 - 基于飞腾派的信号发生器

技术背景

在工业控制、数据采集、信号处理等领域,往往需要按照固定周期执行任务,这个时间周期的长短以及精确度,会直接影响任务的执行结果。例如,控制周期不稳定等于给系统额外引入了随机延迟,采样周期过长影响采样精度,信号处理周期不稳定会导致输出信号失真。

在Linux系统中,传统的周期性时间控制方法主要包括如下三种:

(1)alarm/timer之类的定时器

(2)select/poll之类的超时机制

(3)sleep/nanosleep之类的休眠机制

这三类方法,都会涉及到进程上下文的切换,切换的过程至少带来微秒级的延迟和抖动。对于一些几十KHz或者几百KHz的场景,往往需要使用FPGA或者DSP等方案来实现。

基于定时器或硬件时钟源的时间控制方法,往往需要中断介入或者外部IO地址的访问,这种方案从硬件架构上就会带来延迟。

Linux内核的一些功能是基于CPU核心内部计数器来实现时间控制的,例如ARM CPU的系统计数器(system counter)以及x86 CPU的时间戳计数器(TSC, Time Stamp Counter),它们集成在CPU内部,具备更高的确定性。

设计与实现方法

在本系列前面的文章中已经提到,基于隔离器技术可以在某个CPU核心上实现没有任何上下文切换的环境,我们可以在这个环境中实现一个精确度更高的时间控制方法。

(1)优先级为99的FIFO线程:核心任务在隔离器环境内运行,避免了上下文切换导致的延迟。

(2)基于CPU 计数器的轮询控制:将时间转换为CPU计数器的count值,然后采用轮询CPU计数器的方式进行周期控制。

(3)以绝对时间为周期:使用绝对时间,能避免其他代码运行带来的相对时间漂移。在周期开始的时候,获取基准的count值,然后根据周期对应的count数进行累加,根据累加后的值进行周期控制。

(4)减少内存访问:周期的起点部分代码使用汇编编写,尽量使用CPU通用寄存器,避免对内存的读写访问,以免带来额外的延迟。

测试程序解析

本次用到的望获实时Linux 隔离器 API:

uint64_t isolator_gettime(void);//获取当前时间(线性增加)

uint64_t isolator_spinto (uint64_t base, uint64_t wait_time);// 循环中阻塞等待至 base+wait_time(ns),返回结束时间

代码解析(gpio_test2.c)

用户加载insmod gpio_test2.ko后会调用ucas_gpio_init(),该函数执行以下步骤:

Step1.调用API在指定CPU上开启隔离器功能

Step2.配置GPIO,包括GPIO复用和方向

Step3.创建内核线程,周期性地翻转GPIO

其中,用户需要自己实现的是Step2中配置GPIO和Step3中定义需要周期执行的函数,该函数要尽量减少访问内存等耗时的操作。

配置GPIO

gpio_config 函数用于配置GPIO引脚和相关寄存器,主要完成I/O映射、复用功能设置、输入输出模式。

  1. 将GPIO0和PAD的基地址映射到内核虚拟空间,并且采用 ioremap_np,即不带缓存的方式。

  2. 配置引脚的复用功能,使得GPIO0_0能够切换到对应的GPIO模式。

  3. 将GPIO0_0设置为输出引脚。

周期性翻转GPIO

gpio_toggle 函数通过隔离器的定时器实现周期性的翻转GPIO0_0的功能。

  1. 使用API isolator_gettime(),获取初始化时间t0。

  2. 进入无限循环。

  3. 在循环体内,首先使用API isolator_spinto()阻塞等待t0+wait_t,并返回t1,接着拉高GPIO0_0,然后再使用API isolator_spinto()阻塞等待t1+wait_t,并返回t2,接着拉低GPIO0_0,最后用t2更新t0,进入下一轮循环。

测试结果

24小时测试结果

望获实时Linux在24小时连续运行中,每1微秒翻转一次GPIO,周期是2微秒,抖动仅为50纳秒,实现了亚微秒级的高精度时间控制。

测试镜像及测试代码下载请点击:https://www.onewos.com/resource-center/iso

后续我们将持续发布"Linux极限探索"内容,敬请关注。更多信息可搜索"望获实时Linux"

相关推荐
ajassi20001 小时前
开源 C++ QT QML 开发(一)基本介绍
linux·qt·开源·qml
tt666qq1 小时前
linux进程与服务
linux·运维·网络
青草地溪水旁1 小时前
从“快递签收规则”看 sigaction:信号处理的“总开关”
linux·信号处理
云泽8081 小时前
Linux 入门指南:从零掌握基础文件与目录操作命令
linux·运维·服务器
Hello_wshuo1 小时前
记一次手机付费充电设备研究
linux·单片机
心灵宝贝2 小时前
unzip-6.0-21.el7.x86_64.rpm怎么安装?CentOS 7手动安装rpm包详细步骤
linux·运维·centos
Lin_Aries_04212 小时前
基于 CI/CD 平台将应用程序自动部署到 Kubernetes 集群
运维·ci/cd·docker·云原生·容器·kubernetes·jenkins
报错小能手3 小时前
linux学习笔记(11)fork详解
linux·笔记·学习
你的人类朋友3 小时前
DevOps是什么?
运维·自动化运维·devops
奶糖 肥晨3 小时前
批量重命名技巧:使用PowerShell一键整理图片文件命名规范
android·服务器·数据库