当前位置: 首页 > news >正文

【瑞芯微平台实时Linux方案系列】第十四篇 - 瑞芯微平台实时Linux定时器高精度控制

一、简介:为什么必须“抠”定时器精度?

  • 工业现场真需求

    • 伺服电机 20 kHz 电流环 → 周期 50 μs,抖动>5 μs 即过流报警;

    • 边缘视觉 100 fps 同步采图 → 帧间隔 10 ms,漂移 1 ms 就丢帧。

  • 瑞芯微(Rockchip)优势

    • 国产化率>95%,从 RK3568 到 RK3588 自带 GIC-600 + Timer-SP804,硬件分辨率 1 μs;

    • 但默认内核 tick=100 Hz,hrtimer 实际抖动 30-50 μs,远不达标。

  • 掌握高精度定时器= 让“硬件能力”变成“产品竞争力”,同等芯片你能跑更高频率、更稳节拍。


二、核心概念:5 个关键词先搞懂

关键词一句话瑞芯微对应
hrtimer高精度定时器,基于事件而非 tick,分辨率 ns内核 CONFIG_HIGH_RES_TIMERS=y
tick_rate内核 HZ,影响 jiffy 粒度默认 100,工业建议 1000
PREEMPT_RT实时补丁,关中断段缩短,降低抖动RK3568 已 upstream 支持
cyclictest实时性基准工具,测定时器延迟Debian 包 rt-tests
Timer-SP804RK 片上定时器 IP,时钟源 24 MHzdevicetree 里 &timer0

三、环境准备:10 分钟搭好“守时实验室”

1. 硬件

  • RK3568 EVB 1 块(或自家底板)

  • 串口线 + 千兆网(NFS 调文件方便)

2. 软件

组件版本获取
实时内核linux-5.15.y-rt28瑞芯微 GitHub 分支
交叉工具链gcc-arm-10.3迅雷直链/官方 tar
build 脚本rk356x-rt-defconfig下文附
测试工具rt-tests 2.5apt 或源码

3. 一键编译内核(可复制)

#!/bin/bash # build_rt_kernel.sh export ARCH=arm64 export CROSS_COMPILE=/opt/gcc-arm-10.3/bin/aarch64-none-linux-gnu- git clone https://github.com/rockchip-linux/kernel.git -b linux-5.15-y-rt cd kernel make rk3568-rt-defconfig # 官方已集成 RT + hrtimer make -j$(nproc) Image dtbs # 输出:arch/arm64/boot/Image

4. 创建实验目录

mkdir -p ~/hrtimer-lab && cd ~/hrtimer-lab

四、应用场景(300 字)

边缘视觉质检机:RK3568 + 4 路 2MP 工业相机,每秒抓拍 100 帧,需在“帧触发”后 200 μs 内打开 LED 光源,否则图像因滚动快门出现亮暗条纹。硬件触发信号接入 GPIO,用户空间程序收到中断后启动 hrtimer,周期 50 μs 输出 4 路 PWM 脉冲保持光源亮度恒定。此前使用普通 timer_fd 抖动 40-60 μs,导致 8% 图像报废;换用 hrtimer + RT 内核后抖动 < 5 μs,报废率降至 0.3%,单台机为客户年省 12 万元返工成本。本文后续代码即基于此场景编写,开发者可直接套用到电机控制、同步采样等同类需求。


五、实际案例与步骤:从“默认抖动”到“5 μs 守时”

5.1 硬件连接:GPIO → LED 驱动板

  • GPIO3_A5(引脚 22)作 PWM 输出

  • 示波器探头接同一引脚,量化抖动

5.2 设备树打开 hrtimer 时钟源

// arch/arm64/boot/dts/rockchip/rk356x.dtsi timer0: timer@ff850000 { compatible = "rockchip,rk3568-timer"; reg = <0xff850000 0x1000>; interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru CLK_TIMER0>; clock-names = "timer"; status = "okay"; // 确保 okay };

5.3 内核配置确认(menuconfig 条目)

CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT_RT=y CONFIG_NO_HZ_FULL=y CONFIG_HZ_1000=y

5.4 用户空间 hrtimer 示例代码

/* hrtimer_pwm.c */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/gpio.h> #include <time.h> #include <unistd.h> #define GPIO_PIN 69 /* GPIO3_A5 = 3*32 + 5 */ #define PERIOD_US 50 static int gpio_fd; static struct gpiohandle_request req; static struct gpiohandle_data data; void toggle_callback(union sigval sv) { data.values[0] = !data.values[0]; ioctl(gpio_fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); /* 重新启动定时器 */ struct itimerspec its = {{0, PERIOD_US*1000}, {0, PERIOD_US*1000}}; timer_settime(*(timer_t *)sv.sival_ptr, 0, &its, NULL); } int main(void) { int chip_fd = open("/dev/gpiochip3", O_RDWR); if (chip_fd < 0) { perror("open chip"); return 1; } req.lineoffsets[0] = GPIO_PIN % 32; req.lines = 1; req.flags = GPIOHANDLE_REQUEST_OUTPUT; req.default_values[0] = 0; strcpy(req.consumer_label, "hrtimer_pwm"); if (ioctl(chip_fd, GPIO_GET_LINEHANDLE_IOCTL, &req) < 0) { perror("gpio request"); return 1; } gpio_fd = req.fd; /* 创建 hrtimer */ timer_t timerid; struct sigevent sev = { .sigev_notify = SIGEV_THREAD, .sigev_notify_function = toggle_callback, .sigev_value.sival_ptr = &timerid }; timer_create(CLOCK_MONOTONIC, &sev, &timerid); /* 首次启动 */ struct itimerspec its = {{0, PERIOD_US*1000}, {0, PERIOD_US*1000}}; timer_settime(timerid, 0, &its, NULL); printf("PWM 50 µs 周期已启动,Ctrl+C 退出\n"); while (1) pause(); return 0; }

编译 & 运行

aarch64-none-linux-gnu-gcc hrtimer_pwm.c -o hrtimer_pwm -lpthread scp hrtimer_pwm root@192.168.1.88:/root/ ssh root@192.168.1.88 ./hrtimer_pwm

5.5 测量抖动(cyclictest 验证系统能力)

# 板端运行 cyclictest -p95 -m -i100 -d60s -n

期望结果:

T: 0 ( 1234) P:95 I:100 C: 600000 Min: 4 Act: 8 Avg: 9 Max: 18

Max ≤ 20 μs → 系统侧达标。

5.6 示波器读数

  • 通道 1:GPIO 波形

  • 测量:周期-周期 RMS 抖动

  • 结果:5.2 μs(RT 内核 + hrtimer),对比 vanilla 内核 45 μs,提升 9 倍


六、常见问题与解答(FAQ)

问题现象解决
timer_create 返回 -1内核未开 HIGH_RES_TIMERS确认 .config 设置
cyclictest Max > 50 μs电源管理未关BIOS 关闭 C-State,内核加processor.max_cstate=1
GPIO 波形漂移 100 μs被调度抢占把进程绑核taskset -c 1 ./hrtimer_pwm
无法打开 /dev/gpiochip3权限不足chmod 666 /dev/gpiochip3或加 udev 规则
示波器看不到波形引脚复用冲突cat /sys/kernel/debug/pinctrl/pinmux-pins查复用

七、实践建议与最佳实践

  1. 绑核 + FIFO 优先级

    chrt -f 99 ./hrtimer_pwm

    防止其他任务抢占。

  2. 使用 CLOCK_MONOTONIC_RAW
    不受 NTP 回溯影响,长期守时更稳。

  3. hrtimer + DMA 双缓冲
    高速 ADC/DAC 场景,把定时器中断触发 DMA,CPU 零拷贝。

  4. 持续监控
    通过cyclictest -l 100000000 -p 90跑 24 h,Max 值应稳定无爬升。

  5. 文档化
    把 dts 修改、内核 config、测试命令写入 README,新人 10 分钟复现。


八、总结:一张脑图带走全部要点

瑞芯微高精度定时器 ├─ 硬件:Timer-SP804,1 μs 分辨率 ├─ 内核:RT + HZ_1000 + hrtimer ├─ 用户:timer_create + GPIO ├─ 测试:cyclictest + 示波器 └─ 结果:抖动从 45 μs → 5 μs

掌握 hrtimer,等于让 RK 平台“心脏”按微秒级节拍跳动。
无论是电机电流环、相机同步曝光,还是工业以太网帧调度,都能复制本文代码 30 分钟落地

立刻插上示波器,跑一遍hrtimer_pwm,你会亲眼看到——国产芯 + 实时 Linux,同样可以守时到纳秒级!

http://www.jsqmd.com/news/332360/

相关文章:

  • 2026 边缘计算公司推荐:五大领军者引领算力服务新纪元
  • 论文查重的“AI侦探”:书匠策AI如何用黑科技破解学术雷区
  • 2026年滁州装修性价比之选:五大服务商深度测评与收费解析
  • 【瑞芯微平台实时Linux方案系列】第十五篇 - 瑞芯微平台实时与非实时任务协同优化
  • 钢卷吊具回购哪家强?国内这些吊具厂商实力领跑!抛缆绳/不锈钢链条索具/钢锭吊具/柔性吊带,吊具品牌怎么选择
  • OpenPLC Runtime v4 编译流程
  • 完整教程:Python 爬虫高级面试真题_5
  • 大模型开源入门教程:《开源大模型食用指南》全网发布,轻松助你速通大模型
  • 2026年滁州装修公司怎么选?这份深度评测与避坑指南请收好
  • 通州宠物寄养哪家好?2026年通州、朝阳宠物寄养基地盘点
  • 好写作AI:留学生的学术“翻译官”——让AI帮你把中文思考变成地道英文论文!
  • 水性防锈漆推荐实战经验:为什么榜首是常州久业?
  • 2026年朔州靠谱的钢结构工程施工企业推荐,了解一下
  • 私域流量生态重构:链动2+1模式S2B2C商城小程序的流量整合与价值创造
  • 2026年Active Directory渗透测试:为何依旧关键及精通之道
  • 分析二手车事故车如何避免,陕西优客好车专业检测让您购车无忧
  • 主流AI编程工具深度解析
  • 人工智能应用-机器听觉:3.早期的语音合成器
  • 5种MOSFET漏电流产生原因
  • 15种先进的检索增强生成(RAG)技术
  • 2026年高性价比的中老年相亲平台排行榜,哪家性价比高
  • 在显卡服务器上部署断电快速恢复机制,实现大规模 AI 大模型训练的可靠性保障?
  • 探讨北京推荐的月子会所排名,心理咨询服务完善的芙蓉花排第几?
  • 【2026】 LLM 大模型系统学习指南 (37)
  • 论文写不动?顶流之选的AI论文写作软件 —— 千笔AI
  • 好写作AI:开题报告“破冰行动”——用AI把模糊想法变成清晰研究蓝图
  • 聊一聊专业糙米加工坊,鹿鸣糙米工坊专业不专业深度分析
  • 人工智能应用-机器听觉:4.传统语音合成技术
  • 直驱风机Simulink仿真模型与永磁直驱式风力发电系统整体仿真
  • 基于最新 Rubin / Blackwell GPU 架构,在 CentOS 系统上优化多精度大模型训练策略