Muszę wykonać dokładny pomiar czasu do poziomu 1 nas, aby zmienić godzinę w cyklu pracy fali pwm.Precyzyjne czasy linuksowe - co decyduje o rozdzielczości clock_gettime()?
Tło
mi stosując Gumstix nad wodą COM (https://www.gumstix.com/store/app.php/products/265/), który ma jeden rdzeń ARM procesor Cortex-A8 pracującego z 499.92 bogomipsy (strona Gumstix podnosi się do 1 GHz z 800MHz zalecane) według/proc/cpuinfo. System operacyjny jest wersją systemu Angstrom Image systemu Linux opartą na jądrze w wersji 2.6.34 i jest dostępny na platformie Gumstix Water COM.
Problem
Zrobiłem sporo czytania o dokładnej synchronizacji w systemie Linux (i próbowałem większość z nich) i konsensus wydaje się, że za pomocą clock_gettime() i przedstawieniu CLOCK_MONOTONIC jest najlepszy sposób na zrobienie tego. (Chciałbym użyć rejestru RDTSC do synchronizacji, ponieważ mam jeden rdzeń z minimalnymi możliwościami oszczędzania energii, ale to nie jest procesor Intela.) A więc tutaj jest część nieparzysta, podczas gdy clock_getres() zwraca 1, sugerując rozdzielczość przy 1 ns , rzeczywiste testy czasowe sugerują minimalną rozdzielczość 30517ns lub (nie może to być zbieg okoliczności) dokładnie czas między tikąpami zegara 32,768 kHz. Oto co mam na myśli:
// Stackoverflow example
#include <stdio.h>
#include <time.h>
#define SEC2NANOSEC 1000000000
int main(int argc, const char* argv[])
{
// //////////////// Min resolution test //////////////////////
struct timespec resStart, resEnd, ts;
ts.tv_sec = 0; // s
ts.tv_nsec = 1; // ns
int iters = 100;
double resTime,sum = 0;
int i;
for (i = 0; i<iters; i++)
{
clock_gettime(CLOCK_MONOTONIC, &resStart); // start timer
// clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
clock_gettime(CLOCK_MONOTONIC, &resEnd); // end timer
resTime = ((double)resEnd.tv_sec*SEC2NANOSEC + (double)resEnd.tv_nsec
- ((double)resStart.tv_sec*SEC2NANOSEC + (double)resStart.tv_nsec);
sum = sum + resTime;
printf("resTime = %f\n",resTime);
}
printf("Average = %f\n",sum/(double)iters);
}
(Nie przejmować podwójnego odlewu, tv_sec w time_t i tv_nsec jest długa.)
skompilować z:
gcc soExample.c -o runSOExample -lrt
biegać z:
./runSOExample
Po skomentowaniu spacji, jak pokazano, wynikiem jest 0ns lub 30517ns, z których większość to 0ns. Prowadzi to mnie do przekonania, że CLOCK_MONOTONIC jest aktualizowana na 32,768 kHz, a większość czasu zegar nie został zaktualizowany przed drugim wywołaniem clock_gettime(), a w przypadkach, gdy wynik jest 30517ns, zegar został zaktualizowany między połączeniami.
Kiedy robię to samo na moim komputerze programistycznym (AMD FX (tm) -6100 sześciordzeniowy procesor pracujący z częstotliwością 1,4 GHz) minimalne opóźnienie jest bardziej stałe 149-151ns bez zer.
Więc porównajmy te wyniki z szybkościami procesora. W przypadku programu Gumstix ten 30517ns (32,768 kHz) oznacza 15298 cykli procesora 499,93 MHz. Dla mojego komputera dev, 150ns odpowiada 210 cyklom procesora 1,4 GHz.
Z clock_nanosleep (wywołania) Odkomentowano średnie wyniki są następujące: Gumstix: Średnia wartość = 213623, a wynik różni się w górę i w dół, o wielokrotność tej rozdzielczości minutowym 30517ns Dev Komputer: 57710-68065 NS z brak wyraźnego trendu. W przypadku komputera dev oczekuję, że rozdzielczość rzeczywiście będzie na poziomie 1 ns, a zmierzone ~ 150ns naprawdę jest czasem, jaki upłynął między dwoma wywołaniami clock_gettime().
Moje pytania są następujące: Co decyduje o minimalnej rozdzielczości? Dlaczego rozdzielczość komputera dev 30000X jest lepsza niż Gumstix, gdy procesor działa tylko ~ 2,6X szybciej? Czy istnieje sposób na zmianę częstotliwości aktualizacji i miejsca CLOCK_MONOTONIC? W jądrze?
Dzięki! Jeśli potrzebujesz więcej informacji lub wyjaśnienia, zapytaj.
Zastanawiam się. Czy jakiś sprzęt nie byłby potrzebny do przechwytywania cykli z zegara procesora? Przynajmniej na tym poziomie precyzji. Być może Gumstix tego nie ma? (Mówię tylko o rejestrze, który może liczyć kleszcze i przytrzymać je przed przetoczeniem). – Jiminion
Po przeczytaniu, które już napisałeś, być może już widziałeś *** [ten link] (http: // gallinazo.flightgear.org/technology/gumstix-overo-rc-servos-and-pwm-signal-generation/)***, ale na wszelki wypadek publikuj. Niektóre materiały są istotne. – ryyker
Mając dokładnie ten sam problem. Wiele wielokrotności 30517ns. Używam Overo Tide. Czy kiedykolwiek rozwiązałeś ten problem? – Ryan