2013-07-01 19 views
6

Szukam prostego sposobu na uruchomienie mojego oprogramowania do akwizycji danych przy użyciu zewnętrznego impulsu TTL. Muszę pobierać dane z wielu źródeł synchronicznie z zegarem referencyjnym o częstotliwości 5 Hz. Przejęcie nie wymaga priorytetu w czasie rzeczywistym, ale chcę zapewnić, że moje oprogramowanie zostanie uruchomione tak szybko, jak to możliwe i dokładnie raz na zewnętrzny cykl zegara. Wolałbym to zrobić przez uzyskanie przerwania od zewnętrznego wyzwalacza bez potrzeby użycia szybkiej pętli odpytywania. O ile mogę powiedzieć, nie można po prostu użyć pin portu równoległego do przerwania w nowoczesnym systemie operacyjnym, takim jak Linux. Jakieś pomysły?Przerwanie sprzętowe synchronicznego zbierania danych

Mam również na myśli generowanie pakietów emisji w mojej sieci, aby powiadomić inne komputery w sieci, że wystąpiło zdarzenie wyzwalające. Ze względu na opóźnienie sieci, może nie być wystarczająco dużo czasu dostępnego w okresie 200ms pomiędzy wyzwalaczami, aby wykonać akwizycję.

Odpowiedz

7

Zamiast używać portu równoległego, czy za pomocą urządzenia seryjny? Ponieważ masz sygnał TTL, prawdopodobnie będziesz potrzebował konwertera poziomów do konwersji poziomów TTL na poziomy RS232 +/- 12V. Gdy używasz urządzenia szeregowego, możesz użyć standardowych wywołań szeregowych ioctl(), aby wykryć zmianę statusu sygnału sterującego.

W szczególności można użyć ioctl TIOCMIWAIT na podłączonym urządzeniu szeregowym, aby poczekać na zmianę, powiedzmy linię DCD, którą podłączysz do źródła zegara.

Twoja aplikacja przestrzeni użytkownika zostanie zablokowana podczas oczekiwania na wywołanie systemowe systemu ioctl TIOCMIWAIT, dopóki nie nastąpi zmiana statusu na linii zegara, w którym to momencie aplikacja może zostać uruchomiona i powrócić z ioctl. Być może będziesz musiał się upewnić, że załatwisz przypadek, w którym zmienisz status przerwań zarówno na wznoszących się jak i opadających zboczach szeregowych sygnałów sterujących. Na niektórych urządzeniach UART (np. TL16C554A UART) możliwe jest, że otrzymasz tylko przerwanie na przejście sygnału w jednym kierunku. Na przykład dla TL16C554A, TIOCMIWAIT będzie tylko spadać na zboczu narastającym dowolnej zmiany sygnału dzwonka.

Korzystanie z seryjnych ioctli w ten sposób ma także tę zaletę, że można użyć klucza USB-Serial, który obsługuje TIOCMIWAIT w razie potrzeby (np. PL2303) i nadal zachowuje kompatybilność oprogramowania na poziomie użytkownika, aczkolwiek kosztem zwiększonego opóźnienia ze względu na na USB.

Jeśli potrzebujesz mniejszego opóźnienia, niż można uzyskać dzięki przestrzeni użytkownika, najlepiej napisać moduł sterownika jądra, który może obsłużyć czas i próbkowanie, ale nie sugerowałbym tej trasy, jeśli nie jest to absolutnie konieczne. Łatwiej jest opracować kod przestrzeni użytkownika.

Oto niektóre niekompletne fragmenty kodu C próbki do korzystania z Ioctl TIOCMIWAIT.

int serial_fd = open(cmdline.device_name, O_RDWR | O_NONBLOCK | O_NOCTTY); 
static const unsigned int ri_flag = TIOCM_RNG; 

/* Set up serial port here using tcsetattr. Set CRTSCTS | CLOCAL to ensure status interrupts 
* are generated. 
*/ 

while (1) { 
     /* Wait for positive RI transition. TIOCMIWAIT takes a mask 
     * as argument, only returning when the appropriate signal has changed. 
     */ 
     if (ioctl(serial_fd, TIOCMIWAIT, ri_flag)) { 
      fprintf(stderr, "ioctl() failed waiting for RI edge [%s]\n", strerror(errno)); 
      break; 
     } 

     /* Do sensor sampling here. You could use TIOCMGET to first verify that 
     * the clock line is in the expected state, eg high, before continuing. 
     */ 
} 
+0

To jest dokładnie to, co chciałbym zrobić. Nie wiedziałem, że nadal mogę używać przerwań RS232 przez adapter USB. To na pewno upraszcza sprawy. Wygląda na to, że mogę to łatwo zaimplementować w Pythonie za pomocą pytania http://stackoverflow.com/questions/5904895/python-monitor-serial-port-rs-232-handshake-signals – Mike

+0

Przykład iokt Pythona działał idealnie z prawdziwym seryjnym Port! ioctl zwrócił błąd "Argument" za każdym razem, gdy próbowałem tego z adapterem USB Keyspan, ale lepiej nie mieć opóźnienia i używać prawdziwego portu COM. Teraz wystarczy zbudować regulator TTL na poziomie +/- 12V. – Mike

+1

@Mike Spojrzałem w źródle, sterownik keyspan nie obsługuje 'TIOCMIWEIT'. Tylko niektóre sterowniki USB-serial obsługują to, szukają '.tiocmiwait' w plikach sterowników w katalogu źródłowym' drivers/usb/serial'. PL2303 jest bardzo popularnym adapterem usb-serial. Możesz znaleźć jedną z nich i zhakować, aby ominąć przedni koniec +/- 12V w kluczu sprzętowym. Alternatywnie, Maxim tworzy serię układów konwerterów poziomów. –

3

Polling to doskonała metoda dla tak niskiej szybkości transmisji danych. Ankieta w 1 ms. Powinno być w porządku. Próba użycia przerwania sprzętowego spowoduje wiele bólu.

Google za "Przerwanie Linux GPIO", jeśli chcesz zrobić to na swój sposób. :)

https://developer.ridgerun.com/wiki/index.php/How_to_use_GPIO_signals

+0

Na razie okazało się, że jeden z moich modułów DAQ USB ma 32-bitowy licznik, który uruchamia się bezpośrednio z mojego sygnału TTL. Jestem w stanie sondować tę wartość w 0,7 ms i szukać zmian. – Mike

2

skończyło się za pomocą portu szeregowego linię CTS na spuście używając TIOCMIWAIT ioctl za Austin Phillips odpowiedź. Ponieważ RS232 wymaga poziomów +/- 12V, udało mi się uzyskać niezbędną moc dla tego przełącznika poziomu z innych szeregowych linii sterujących.

Level shifter schematic

kod

Pythona do wdrożenia tego rozwiązania można znaleźć w pytaniu: Python monitor serial port (RS-232) handshake signals

2

Rozważmy podłączenia zewnętrznego źródła impulsów do ping „cd” z prawdziwym (nie USB do konwertera RS232!) Port szeregowy. Następnie możesz użyć "PPS api", aby uzyskać dokładny znacznik czasu, z którego pin "wyszedł wysoko", jak to możliwe.

Możesz potrzebować przesuwnika sygnału TTL; nie wszystkie porty szeregowe działają poprawnie z poziomami sygnału TTL.

Aplikacja PPS api jest zwykle używana do przechowywania czasu. Na przykład. podłącz pin PPS modułu GPS do komputera i pozwól NTP zsynchronizować się z tym. Daje to dokładność mikrosekundy.

Ten aplet PPS powinien być dokładniejszy niż jakiekolwiek inne rozwiązanie przestrzeni użytkownika (np. TIOCMIWAIT ioctl), ponieważ jest on całkowicie obsługiwany w jądrze, natychmiast po wejściu przerwania (wywołanego przez zmianę sygnału CD). rozwiązanie ioctl masz co najmniej przełącznik kontekstowy. Zrobiłem kilka testów na raspberry pi, a rozwiązanie przestrzeni użytkownika daje przynajmniej 6-jitter.

Aplikacja PPS api podaje znacznik czasu od momentu wykrycia impulsu.

Dlaczego nie używać konwertera USB na RS232: Czytałem gdzieś (w odniesieniu do pomiaru czasu), że urządzenia USB są odpytywane raz na +/- 1ms. Ta częstotliwość odpytywania zależy również od tego, jak bardzo zajęty jest system z innymi urządzeniami USB i myślę, że wewnętrzny zegar urządzenia USB może również wpływać na różne rzeczy. Nigdy tego nie zmierzyłem.

Istotne adresami:

Jeśli chodzi o funkcjonalność sieci: korzystaj z transmisji UDP, nie używaj protokołu TCP.

+0

Zdecydowałem się użyć CTS (patrz moja odpowiedź) bez żadnego konkretnego powodu. Wydawało mi się, że wszystkie linie kontrolne traktowano równoważnie w odniesieniu do przerwań. Z pewnością zajrzę do PPS API i da mi lepsze wyczucie czasu niż mój obecny system oparty na przerwaniach. – Mike

+0

Nie miałem szczęścia przy korzystaniu z konwerterów USB na RS232. – Mike

+0

W pewnym momencie powinienem przechwycić znaczniki czasu dla każdego zdarzenia przerwania, aby zobaczyć, jak bardzo jitter kończę z moim precyzyjnym spustem. – Mike