Raspberry Pi i przerwania

Pytanie zapewne z kategorii banalnych, ale nie mogę na szybko doszukać się odpowiedzi, a nie jestem pewien, czy w tym przypadku powinienem trzymać się przyzwyczajeń z mikrokontrolerów, czy jednak nie.

Jak wiadomo jedną z najważniejszych zasad przy programowaniu na MCU jest jak najszybsze wychodzenie z funkcji obsługującej przerwanie - jeśli trzeba wykonać dłuższą partię kodu albo coś przeczekać, ustawia się flagę i robi to w pętli głównej programu.

Czy ta zasada ciągle obowiązuje na Raspberry Pi? Mam kawałek kodu, który ma m.in. sprawdzać stan kilku przycisków i obsługiwać enkoder obrotowy. Po wykryciu naciśnięcia przycisku albo przekręcenia pokrętła zajdzie konieczność wysłania polecenia do zewnętrznego procesu, za pośrednictwem potoku nazwanego albo gniazda uniksowego. Mogę sobie pozwolić na umieszczenie tych operacji w kodzie obsługi przerwania? Jądro sobie poradzi z taką sytuacją, czy będę miał do czynienia z blokadą, jak na mikrokontrolerze?

Jeśli takie rozwiązanie jest niedopuszczalne, w jaki sposób mogę wybudzić pętle główną uśpioną poleceniem sleep()? Bo z tego co widzę, nie dzieje się to automatycznie po wyjściu z przerwania. Mógłbym co prawda usypiać program na krótko i periodycznie sprawdzać stan flag, aby użytkownik nie zauważył opóźnień. Jednak trochę szkoda cykli procesora, jeśli da się to zrobić lepiej.

Reply to
Atlantis
Loading thread data ...

Cos mi to wyglada niespojne: przerwania to obsluguje jadro, a twoj program ma z nimi do czynienia tylko wtedy gdy jest jadrem (czyli chodzi na golym krzemie) lub jego czescia. Jak masz w miare typowa instalacje to jest sobie jadro Linuxa ktore sie zajmuje przerwaniami. Na poziomie usera sa sygnaly. Roznice sa istotne. Raz skala: procesow usera mozesz miec cala mase i te procesy nie musza sie spieszyc. W jadrze trzeba obsluzyc wiele roznych przerwan i tak jak na MCU trzeba unikac dlugiego czasu z zablokowanymi przerwaniami. Procedura obslugi przerwania moze wykonac wiele roznych operacji, o ile zmiesci sie w czasie i unika blokad. Co do syganlow, to trudno je poprawnie uzyc bo rozne biblioteki (zaczynac od libc) moga zglupiec jesli zrobisz cos innego niz ustawienie flagi w procedurze obslugi sygnalu. Tzn. mozesz dostac program ktory losowo nie dziala. Jak to nie dzialanie jest dostatecznie czeste to wykryjesz to testowaniem. Ale moze tez przejsc testy a sprawiac problemy dopiero w eksploatacji.

Co do wybudzania na poziomie usera: normalne API jadra jest takie ze jesli na cos czekasz to robisz wywolanie funkcji systemowej ktora blokuje twoj proces i budzi go kiedy nalezy. W szczegolnosci normalne operacje wejscia/wyjscia blokuja sie do momentu nadejscia danych. Jesli potrzebujesz synchronizowac watki procesu to sa semafory do synchronizacji. Miedzy procesami standartowa metoda to gniazdka. Jak nie ma odpowiedniego API to zwykla sztuczka to nieskonczona petla ktora cos sprawdza a potem przez chwile spi. Jesli to chcesz lepiej do modul jadra z driverem ktory wybudzi twoj proces (mam wrazenie ze wybudzanie po zmianie na GPIO jest dostepne w standartowym driverze).

Reply to
antispam

To nie przerwanie tylko zdarzenie - jak najbardziej możesz to umieścić w kodzie obsługi zdarzenia.

Natomiast podobna zasada, co przerwań na MCU, dotyczy obsługi sygnałów.

Ogólnie to pause() jest wybudzane z sygnału, ale czuję że select() jest tym czego szukasz...

Reply to
Adam Wysocki

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.