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

相关推荐
A小辣椒3 小时前
TShark:基础知识
linux
AlfredZhao5 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao20 小时前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334661 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪1 天前
linux 拷贝文件或目录到指定的位置
linux
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5202 天前
Linux 11 动态监控指令top
linux