Czy mogę mieć 1 rdzeń procesora tylko dla mojego programu?

12

Muszę zmierzyć różnicę czasu między wysokim -> niskim a niskim -> wysokim zboczem sygnału na pinach GPIO. Napisałem prosty program, który to robi. Po uruchomieniu przez pewien czas byłem całkiem zadowolony z wyniku (warianty 0,01 s). Ale od czasu do czasu występował błąd 0,5 s. Myślałem, że może to wynikać z jakiegoś innego procesu systemowego działającego w tym czasie. Więc moje pytanie brzmi:

Czy mogę zarezerwować jeden rdzeń procesora tylko dla mojego programu i pozwolić innym 3 rdzeniom na system?

Używam Raspbian Jessie Lite, więc myślę, że 3 rdzenie będą wystarczające, aby go uruchomić.

NonStandardModel
źródło
4
Zakładam, że odpytujesz w pętli o status pinu GPIO. Jest to bardzo podatne na to, w jaki sposób system operacyjny decyduje się na uruchomienie programu, który spędza większość czasu utrzymując procesor zajęty, nie robiąc nic pożytecznego. Możesz zastanowić się nad sposobem ustawienia przerwania na danym pinie GPIO, którego możesz użyć, aby pozwolić programowi spać między krawędziami sygnału na pinach GPIO.
Florian Castellane
4
Nie masz pewności, co to twój projekt, ale czasami mikrokontroler jest lepiej dopasowany, szczególnie gdy potrzebujesz więcej systemu podobnego do czasu rzeczywistego. Arduino oferuje wiele opcji i możesz napisać swój program w C / C ++.
SnakeDoc
@Florian W RPi.GPIO jest funkcja podobna do przerwania. Będzie blokował program do momentu wykrycia krawędzi (źródło: sourceforge.net/p/raspberry-gpio-python/wiki/Inputs ).
NonStandardModel
@ SnakeDoc Wiem, że mikrokontroler jest lepszy. Miałem nadzieję tego uniknąć, ponieważ nie potrzebuję mikrosekundowej precyzji. 1/100 sekundy to więcej niż wystarcza. Potrzebuję też różnicy czasu, więc jeśli było opóźnienie, miałem nadzieję, że będzie to samo dla startu i stopu. Jeśli to nie zadziała, muszę zapisać mikrokontroler podłączony do RPi.
NonStandardModel
1
Lub załóż system operacyjny w czasie rzeczywistym na PI. Problem z konfiguracją polega na tym, że system operacyjny „stara się”. W zależności od tego, co się dzieje w tym samym czasie, gdy program żąda uprzywilejowanego dostępu do GPIO, może stać w kolejce za innymi zadaniami, które system operacyjny wykonuje w tym momencie. Twój program użytkownika otrzyma niższy priorytet niż zadania systemowe. Istnieje również zapobieganie, co oznacza, że ​​podczas działania programu program może zostać „wstrzymany i„ odłożony ”przez system operacyjny na inny proces, co oznacza, że ​​obserwacje dotyczące czasu mogą być zniekształcone.
SnakeDoc

Odpowiedzi:

13

Poświęcenie rdzenia jest prawdopodobnie przesadą.

Proponuję wypróbować moją bibliotekę pigpio . Domyślnie czas zmiany GPIO zmienią się z dokładnością do 10µs.

Jako szybki test proponuję spojrzeć na ten przykład w Pythonie , który wydrukuje dowolne przejście na poziomie GPIO i czas w mikrosekundach od ostatniego przejścia na tym GPIO.

pigpio nie jest domyślnie instalowany w Jessie Lite. Zainstaluj najnowszą wersję z połączonej witryny lub starszą wersję w repozytoriach.

sudo apt-get install pigpio python-pigpio python3-pigpio

pigpio - Library for Raspberry Pi GPIO control
python-pigpio - Python module which talks to the pigpio daemon (Python 2)
python3-pigpio - Python module which talks to the pigpio daemon (Python 3)
joan
źródło
Spróbuję twojej biblioteki pigpio. W tej chwili muszę dokończyć kolejny projekt, ale wrócę do tego. Przekażę za kilka tygodni. Dziękuję Ci!
NonStandardModel
4

Możesz zablokować swój program na jednym rdzeniu, korzystając z schedutilsopisu opisanego w tym artykule Cyberciti :

sudo apt-get install schedutils
sudo taskset -c 3 -p 13545  # Lock PID 13545 to core 3

Inne procesy można jednak nadal planować na tym samym rdzeniu. Drugą rzeczą do zrobienia jest upewnienie się, że twoje polecenie działa z najwyższym priorytetem za pomocą polecenia nice (to poinformuje jądro Linuksa, że ​​inne procesy powinny być w razie potrzeby wyprzedzone ). Uruchom swój program w ten sposób:

nice -n -20 your-program

Istnieje kilka innych możliwych przyczyn problemów z synchronizacją. Nie jest to tak łatwe do zrobienia:

  • Jeśli programujesz w Pythonie, istnieje moduł czyszczenia pamięci, który czasami wstrzymuje program, aby zwolnić nieużywaną pamięć.
  • Przerwania powodują, że CPU obsługuje coś innego niż chcesz. Na przykład pakiety sieciowe lub inne wejścia / wyjścia.
  • Jeśli twój program dużo śpi, mogą istnieć inne procesy, które zapełniają pamięć podręczną procesora (pamięć podręczna L1 / L2). Zmusza to do oczekiwania na dostęp do pamięci RAM.
    • Co gorsza, jeśli pamięć RAM jest pełna, więc proces zostaje zamieniony na dysk, ponieważ karty SD są wolne.

Istnieją sposoby, aby proces był przetwarzany w czasie rzeczywistym , co oznacza, że ​​będzie on przebiegał z pewnymi gwarancjami czasowymi. Problem polega na tym, że wszystko inne może być wolniejsze i jest to złożony temat. Jeśli chcesz pójść w dół tej króliczej nory, sugeruję, abyś zaczął czytać o procesach czasu rzeczywistego w Linuksie .

Emil Vikström
źródło
2
Zamiast miłego byłoby lepiej nadać procesowi priorytet w czasie rzeczywistym, co zapewniłoby jego pierwszeństwo przed procesami niebędącymi w czasie rzeczywistym.
joan
Dobrze, dodam notatkę na ten temat.
Emil Vikström
1
„gc.disable ()” co się stanie, jeśli wyłączysz moduł czyszczenia pamięci?
Keine
@Keine Możesz dostać wyciek pamięci. Powiedzmy, że masz obiekt A, który ma zmienną wskazującą na B. Python będzie śledził to odwołanie jako liczbę, wie, że B ma 1 obiekt skierowany w jego stronę. Usuń A, gdy już go nie potrzebujesz. Liczba referencji dla B zmniejszy się, a jeśli osiągnie 0, Python może również zwolnić B. Nazywa się to zliczaniem referencji. Ale teraz powiedzieć, że B ma odniesienia powrotem do A. Teraz masz skupisko obiektów skierowanymi do siebie. Żaden z nich nie osiągnie 0 i nie zostanie uwolniony. GC może znaleźć takie klastry i usunąć je, gdy główny program nie wskazuje „do” klastra.
Emil Vikström
1
Dodam sugestie, które przedstawiłeś do mojego projektu. Mam jednak nadzieję, że uniknę zbyt skomplikowanych tematów. W takim przypadku lepiej jest zrobić wykrywanie przerwań mikrokontrolera i podłączyć go do RPi tylko w celu zapisania danych. Dziękuję Ci!
NonStandardModel
2

Ponieważ masz wymagania dotyczące czasu, Raspberry Pi nie jest już odpowiednią platformą do tego. To nie jest platforma czasu rzeczywistego, a czas może zostać zepchnięty przez wiele różnych źródeł zakłóceń.

Zamiast tego powinieneś użyć mikrokontrolera, aby zmierzyć ten czas, najlepiej za pomocą przerwań i przekazać informację Pi później.

Maxthon Chan
źródło
1
Czy nie można jednak odbierać przerw na pinach GPIO na Raspberry Pi?
Florian Castellane
Z pewnością zależy to od tego, czy istnieje jakakolwiek inna część wymagań projektowych, która czyni maszynę linux bardziej odpowiednią niż MCU. RPi jest w stanie dobrze poradzić sobie z tym zadaniem, podobnie jak MCU o taktowaniu 10 MHz.
Sean Houlihane
1

Zgodnie z twoimi wymaganiami nie sądzę, że musisz używać procesora jednordzeniowego. Musisz mieć pewność, że Twój program działa cały czas. Aby to osiągnąć, możesz ustawić priorytet swojego programu na bardzo wysokim poziomie, aby nie zakłócał go żaden inny proces.

O ile mi wiadomo, system operacyjny (ogólnego przeznaczenia), którego używamy, nie jest przeznaczony do użytku w systemach czasu rzeczywistego, więc jeśli chcesz uruchomić proces w czasie rzeczywistym, aby żaden inny proces go nie zakłócał, musisz iść dla systemu operacyjnego czasu rzeczywistego (RTOS). Może wymyślą podstawowy wybór. :)

Vishwajeet Vishu
źródło
1
Czy są dostępne dobre darmowe RTOS?
Keine
RTLinux i Vxworks są przykładami RTOS i są również dobre. Ale przed instalacją należy zapoznać się z systemem operacyjnym (na czym polegało jego stworzenie), aby mógł on zaspokoić Twoje potrzeby.
Vishwajeet Vishu