望获实时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"

相关推荐
Lester_110112 小时前
STM32 高级定时器PWM互补输出模式--如果没有死区,突然关闭PWM有产生瞬间导通的可能吗
stm32·单片机·嵌入式硬件·嵌入式软件
天才奇男子13 小时前
HAProxy高级功能全解析
linux·运维·服务器·微服务·云原生
ALINX技术博客14 小时前
【202601芯动态】全球 FPGA 异构热潮,ALINX 高性能异构新品预告
人工智能·fpga开发·gpu算力·fpga
小李独爱秋14 小时前
“bootmgr is compressed”错误:根源、笔记本与台式机差异化解决方案深度指南
运维·stm32·单片机·嵌入式硬件·文件系统·电脑故障
学嵌入式的小杨同学14 小时前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
酥暮沐14 小时前
iscsi部署网络存储
linux·网络·存储·iscsi
❀͜͡傀儡师15 小时前
centos 7部署dns服务器
linux·服务器·centos·dns
Dying.Light15 小时前
Linux部署问题
linux·运维·服务器
S190115 小时前
Linux的常用指令
linux·运维·服务器
萤丰信息15 小时前
AI 筑基・生态共荣:智慧园区的价值重构与未来新途
大数据·运维·人工智能·科技·智慧城市·智慧园区