Z tych trzech czynników, które wymieniono, tylko pierwsza jest prawidłowa. Co do reszty - niezupełnie. Kod przestrzeni użytkownika może wykonywać operacje DMA - nie ma z tym problemu. Istnieje wiele firm produkujących urządzenia, które stosują tę technikę w swoich produktach. Możliwe jest również zastosowanie aplikacji przestrzeni użytkownika sterowanej przerwań, nawet gdy wszystkie operacje wejścia/wyjścia są wykonywane przy pełnym obejściu jądra. Oczywiście nie jest to tak proste, jak po prostu wykonanie mmap()
na.
Musiałbyś mieć minimalną część sterownika w jądrze - jest to konieczne, aby zapewnić przestrzeni użytkownika minimum potrzebnego z jądra (ponieważ jeśli o tym pomyślisz - to jest również /dev/mem
kopia zapasowa przez sterownik urządzenia znaków).
Dla DMA jest to w rzeczywistości zbyt proste - wystarczy, że obsłużysz żądanie mmap
i zamapujesz bufor DMA na przestrzeń użytkownika. W przypadku przerwań - jest to nieco trudniejsze, przerwanie musi być obsługiwane przez jądro, bez względu na wszystko, jednak jądro może nie wykonywać żadnej pracy i po prostu obudzić proces, który wywołuje, powiedzmy, epoll_wait()
. Innym podejściem jest dostarczenie sygnału do procesu wykonanego przez DOSEMU, ale jest to bardzo powolne i nie jest zalecane.
Jeśli chodzi o faktyczne pytanie, jednym z czynników, które należy wziąć pod uwagę, jest podział zasobów. Dopóki nie musisz udostępniać urządzenia w wielu aplikacjach i nie ma nic, czego nie możesz zrobić w przestrzeni użytkownika - przejdź do przestrzeni użytkownika. Prawdopodobnie zaoszczędzisz mnóstwo czasu podczas cyklu programowania, ponieważ pisanie kodu przestrzeni użytkownika jest niezwykle łatwe. Kiedy jednak dwie lub więcej aplikacji wymaga współdzielenia urządzenia (lub jego zasobów), istnieje duże prawdopodobieństwo, że poświęcisz ogromną ilość czasu na jego wykonanie - wyobraź sobie, że wiele procesów rozwidla się, rozbija, mapuje (ta sama?) Pamięć jednocześnie itd. I ostatecznie, IPC jest zwykle wykonywane przez jądro, więc jeśli aplikacja musiałaby zacząć "rozmawiać" ze sobą, wydajność może znacznie się pogorszyć. Wciąż jest to robione w prawdziwym życiu dla pewnych aplikacji o krytycznym znaczeniu dla wydajności, ale nie chcę wchodzić w szczegóły.
Kolejnym czynnikiem jest infrastruktura jądra. Załóżmy, że chcesz napisać sterownik urządzenia sieciowego. To nie jest problem, aby zrobić to w przestrzeni użytkownika. Jeśli jednak to zrobisz, będziesz musiał napisać pełny stos sieciowy, ponieważ nie będzie możliwe korzystanie z domyślnego systemu Linux, który żyje w jądrze.
Powiedziałbym, idź do przestrzeni użytkownika, jeśli to możliwe, a ilość wysiłku, aby wszystko zadziałało, jest mniejsza niż napisanie sterownika jądra i pamiętając, że pewnego dnia może być konieczne przeniesienie kodu do jądra . W rzeczywistości jest to powszechna praktyka polegająca na kompilowaniu tego samego kodu zarówno dla przestrzeni użytkownika, jak i przestrzeni jądra, w zależności od tego, czy zdefiniowano jakieś makro, ponieważ testowanie w przestrzeni użytkownika jest o wiele przyjemniejsze.
Zabezpieczenia: uprawnienia do plików kontrolki węzła urządzenia, które użytkownicy mogą otwierać/czytać/zapisywać na urządzeniu. Operacje na plikach blokują lub zezwalają na współbieżne operacje. – sawdust
Decyzja może w dużym stopniu zależeć od tego, czym jesteś PWM i jakiego sprzętu. –