есть одна железка на АРМ с RT_PREEMPT ядром. задача простая: через ethernet отправлять пакеты с заданным интервалом - 250мкс. проблема в том, что интервал плавает. вот тестовый код:
#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
#include <time.h>
#include <sched.h>
#include <stdlib.h>
int main() {
sched_setscheduler(0, SCHED_FIFO, &(struct sched_param) {
.sched_priority = sched_get_priority_max(SCHED_FIFO)
});
for (int n = 10; n--;) {
struct timespec a, b;
clock_gettime(CLOCK_MONOTONIC, &a);
clock_nanosleep(CLOCK_MONOTONIC, 0, &(struct timespec) {
.tv_sec = 0,
.tv_nsec = 250000
}, NULL);
clock_gettime(CLOCK_MONOTONIC, &b);
printf("%ld\n", b.tv_nsec - a.tv_nsec + (b.tv_sec - a.tv_sec) * 1000000000l);
}
return 0;
}
482984
402445
361446
378612
365238
362738
359113
359113
363654
358821
cat /proc/timer_list говорит, что используется hi-res timer. на всякий случай полный вывод:
# cat /proc/timer_list
Timer List Version: v0.5
HRTIMER_MAX_CLOCK_BASES: 2
now at 9784755808068 nsecs
cpu: 0
clock 0:
.base: c03fbfa8
.index: 0
.resolution: 1 nsecs
.get_time: ktime_get_real
.offset: 1330069279622958539 nsecs
active timers:
clock 1:
.base: c03fbfe0
.index: 1
.resolution: 1 nsecs
.get_time: ktime_get
.offset: 0 nsecs
active timers:
#0: <c03fc550>, tick_sched_timer, S:01
# expires at 9784760000000-9784760000000 nsecs [in 4191932 to 4191932 nsecs]
#1: <c0423a10>, sched_rt_period_timer, S:01
# expires at 9785000000000-9785000000000 nsecs [in 244191932 to 244191932 nsecs]
#2: <c1c1da98>, hrtimer_wakeup, S:01
# expires at 9787882326277-9787887326259 nsecs [in 3126518209 to 3131518191 nsecs]
.expires_next : 9784760000000 nsecs
.hres_active : 1
.nr_events : 4303769
.nr_retries : 2718
.nr_hangs : 0
.max_hang_time : 0 nsecs
.nohz_mode : 2
.idle_tick : 9784730000000 nsecs
.tick_stopped : 0
.idle_jiffies : 948472
.idle_calls : 4027935
.idle_sleeps : 3643985
.idle_entrytime : 9784720504270 nsecs
.idle_waketime : 9784735100438 nsecs
.idle_exittime : 9784735153646 nsecs
.idle_sleeptime : 7111169596582 nsecs
.last_jiffies : 948472
.next_jiffies : 948491
.idle_expires : 9784910000000 nsecs
jiffies: 948475
Tick Device: mode: 1
Per CPU device: 0
Clock Event Device: timer0_0
max_delta_ns: 178956970763
min_delta_ns: 50000
mult: 103079215
shift: 32
mode: 3
next_event: 9784760000000 nsecs
set_next_event: davinci_set_next_event
set_mode: davinci_set_mode
event_handler: hrtimer_interrupt
подскажите, как приблизиться к заветным 250мкс? куда копать?