Sie haben Recht, wenn Sie nicht erwarten, dass Timer früh ausgelöst werden - und das tun sie nicht. Das Scheinbare frühes Auslösen liegt daran, dass Sie nicht die Zeit seit Ablauf des vorherigen Timers messen – Sie messen die Zeit seit dem vorherigen gettimeofday()
Anruf. Wenn zwischen dem Ablauf des Timers und dem eigentlichen Planen des Prozesses eine Verzögerung aufgetreten ist, sehen Sie diesen gettimeofday()
verspätet, und der nächste um den gleichen Betrag verfrüht .
Anstatt den Unterschied zwischen aufeinander folgenden gettimeofday()
zu protokollieren Aufrufen, versuchen Sie, die zurückgegebenen absoluten Zeiten zu protokollieren, und vergleichen Sie dann die zurückgegebenen Zeiten mit N * 100 ms nach der Anfangszeit.
Wenn Sie möchten PREEMPT_RT
Um Ihnen zu helfen, müssen Sie eine Echtzeit-Scheduler-Richtlinie für Ihr Testprogramm festlegen (SCHED_FIFO
oder SCHED_RR
), was root erfordert.
Ich habe einige Änderungen an Ihrem Code vorgenommen und hauptsächlich den timer
ersetzt wie folgt und führen Sie den Prozess als RT-Fortschritt (SCHED_FIFO) aus.
setitimer() -> timer_create()/timer_settime()
gettimeofday() -> clock_gettime()
Mein Testbed ist i9-9900k CPU und PREEMPT-RT gepatchtes Linux mit 5.0.21 Kernel. Das Zeitintervall des Timers beträgt 1 ms und das Programm läuft etwa 10 Stunden, um das folgende Ergebnis zu erzeugen.
Ich verwende auch Cyclictest
(basierend auf nanosleep()
) auf meinem Rechner, und es zeigt eine bessere Latenzkontrolle (maximale Latenz weniger als 15 us). Wenn Sie also selbst einen hochauflösenden Timer realisieren möchten, kann meiner Meinung nach ein eigenständiger RT-Thread, der Nanosleep auf einem isolierten Kern ausführt, hilfreich sein. Ich bin neu im RT-System, Kommentare sind willkommen.