ARM架构Linux下GNU C如何实现2us级硬件寄存器读写短延迟
ARM架构Linux下微秒级短延迟解决方案
问题根因
你当前使用的nanosleep、usleep都属于睡眠类延时函数,调用后内核会将当前进程挂起让出CPU,等待超时后再重新调度执行。Linux系统默认的进程调度粒度通常在100us~1ms区间,因此即使你设置1ns的延时,实际也会等待至少一个调度时间片,这是出现100us额外延时的根本原因,这类函数本身就不适合微秒级的短延时场景。
可行方案
方案1:用户态高精度时间戳忙等待(通用性最强,无需内核态权限)
直接通过高精度时钟接口获取时间戳循环判断,直到达到目标延时,完全规避调度开销,2us级的延时精度完全可以满足要求。
示例代码:
#include <time.h> void busy_wait_us(unsigned long us) { struct timespec start, now; // 使用单调时钟,不受系统时间修改、NTP调整影响 clock_gettime(CLOCK_MONOTONIC, &start); unsigned long target_nsec = us * 1000UL; while (1) { clock_gettime(CLOCK_MONOTONIC, &now); unsigned long delta_nsec = (now.tv_sec - start.tv_sec) * 1000000000UL + (now.tv_nsec - start.tv_nsec); if (delta_nsec >= target_nsec) { break; } } }
使用注意:
- 如内核支持,可将
CLOCK_MONOTONIC替换为CLOCK_MONOTONIC_RAW,完全避开NTP时间调整,精度更高。 - 忙等待会占用当前CPU核心,若需更高稳定性可将进程绑定到固定CPU核心,避免进程迁移带来的误差:可通过
sched_setaffinity系统调用实现。 - 如果是ARMv8架构,还可以直接读取架构计时器寄存器
cntvct_el0做循环判断,比clock_gettime开销更小、精度更高,仅需提前读取cntfrq_el0寄存器获取计时器频率即可,示例如下:
// 读取ARMv8架构计时器计数 static inline unsigned long long get_arch_timer_cnt() { unsigned long long val; asm volatile("mrs %0, cntvct_el0" : "=r" (val)); return val; } // 读取ARMv8架构计时器频率,单位Hz static inline unsigned long get_arch_timer_freq() { unsigned long val; asm volatile("mrs %0, cntfrq_el0" : "=r" (val)); return val; } void busy_wait_us_armv8(unsigned long us) { static unsigned long timer_freq = 0; if (timer_freq == 0) { timer_freq = get_arch_timer_freq(); } unsigned long long start = get_arch_timer_cnt(); unsigned long long wait_cnt = (unsigned long long)us * timer_freq / 1000000UL; while (get_arch_timer_cnt() - start < wait_cnt); }
方案2:内核态驱动场景直接使用内核内置延时函数
如果你是在内核态开发驱动操作硬件寄存器,直接调用内核提供的udelay(2)即可,该函数是内核基于平台定时器实现的忙等延时,原生支持微秒级精度,完全满足你的需求。
注意:udelay的入参建议不要超过1000,更长的延时请使用mdelay或睡眠类延时函数。
方案3:提升调度优先级降低干扰
如果需要进一步降低延时被中断拉长的概率,可以将进程设置为实时调度优先级,仅需root权限即可:
#include <sched.h> struct sched_param sp = {.sched_priority = 99 }; // 设置为SCHED_FIFO实时调度策略,优先级最高 sched_setscheduler(0, SCHED_FIFO, &sp);
设置后进程调度优先级远高于普通进程,忙等过程被其他进程抢占的概率大幅降低,延时稳定性更好。
内容的提问来源于stack exchange,提问作者Martin Vana
相关产品推荐
相关产品推荐

