Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[RTOS] - Co przemawia za RTOS?

kiclaw 02 Dec 2015 18:38 5628 56
IGE-XAO
  • #1
    kiclaw
    Level 16  
    Witam!

    Ostatnio zacząłem zajmować się RTOSami dla układów embedded, ogólnie tak dla rozwinięcia umiejętności bo na co dzień zajmuje się również systemami czasu rzeczywistego ale programuje je "bare matal". Czyli programowanie np. ARMa bez jakiegoś OSa.
    Ogólnie punktem zapalnym dla rozpoczęcia nauki była pewna dyskusja z osobą która na co dzień bawi się RTOSami i mi zachwalała, jaki to RTOS nie jest wspaniały uniwersalny i prosty.

    No i właśnie, po paru godzinach przesiedzianych nad artykułami z EP oraz nad tutkiem od FreeRTOS (klik), stwierdzam: że RTOS to w sumie nie jest takim super narzędziem (z tym, że mogę się strasznie mylić bo temat znam jak pisałem od kilku godzin :) ).
    Ale do rzeczy, moje główne pytanie brzmi: Jaki uzysk daje używanie RTOS zamiast programowania "bare metal" pod C.

    No i właśnie, teraz postaram się zaargumentować dlaczego tak sądzę.
    No bo popatrzcie, wszyscy się cieszą że RTOS taki super, bo mamy wywłaszczenia, i się przerywają wątki i w ogóle możemy upakować procesy a scheduler sam się zajmie tym co i kiedy wywołać.
    Tylko kurczę, przecież normalnie też możemy sobie takie coś zrobić ustawiając np. dla timerów (czy innych przerwań) konkretne priorytety i mieć ich nawet 30. I mieć taki 30 poziomowy program, a proces szumnie nazwany Idle Task to przecież nic innego jak program wykonywany w pętli gdzie jest najniższy poziom przerwań.
    Więc ja osobiście, wolę sobie wywołać timer z jakąś częstotliwością (i odpowiednim priorytetem) i mieć to czarno na białym(oczywiście wykonywać jakiś kod w tym timerze). Nie widzę tutaj jakiegoś uzysku. Pracy jest więcej o może kilka linijek kodu (jednokrotny init timera).

    Następna sprawa, tak szumnie nazywanie normalnych flag synchronizacyjnych muteksami i semaforami. No przecież to się w "tradycyjnych" systemach rozwiązuje zwyczajną flagą (tudzież kilkoma flagami) synchronizacyjną.

    Dalej:
    Kolega ten argumentował mi, że kompletnie olewam warstwę sprzętową bo do tego są już biblioteki, ja piszę tylko warstwę aplikacyjną. No i właśnie nie do końca. Bo w RTOSach dla jakichś konkretnych uC to znalazłem jedynie jakieś najprostsze API jak np. ustawienie pinów 1/0. O czymś takim jak np. proste funkcje (ale sprawdzone na 100%, najlepiej od producenta) do przesyłania po SPI to można zapomnieć. A więc skoro trzeba je pisać samemu, to argument o pisaniu samej aplikacji odpada.

    A więc co tak ludzi i cały przemysł embedded przyciąga tak o RTOS? Bo ja szczerze powiedziawszy nie rozumiem.
    Rozpatrzmy taki przykład z "Elektroniki Praktycznej" (7/2009). Autorem jest Krzysztof Paprocki.
    Quote:
    [...]Przedstawimy teraz przykład aplikacji działającej
    z wykorzystaniem muteksów do ochrony
    zasobów. Załóżmy sytuację, w której dwa zadania,
    jeśli zaistnieje taka potrzeba, zmieniają wypełnienie
    generowanego przez mikrokontroler
    sygnału PWM. Nowowprowadzony współczynnik
    wypełnienia nie może się zmieniać przez
    czas 500 ms, a jeśli zostanie zmieniony to może
    to spowodować nieprawidłowe działanie całego
    systemu. Aby zabezpieczyć timer TIM3 pracujący
    w roli generatora PWM, przed nieuprawnionym
    dostępem zostanie wykorzystany muteks.
    W systemie uruchomione są dwa zadania:
    vTask25PWM() oraz vTask75PWM(). Wychylnie
    joysticka na płytce ewaluacyjnej w górę powoduje
    odblokowanie pierwszego zadania i, jak
    nietrudno się domyślić, zmianę współczynnika
    wypełnienia sygnału PWM na 25%. Przeciwna
    pozycja joysticka (w dół) odblokowuje drugie
    zadania, a tym samym ustawia wypełnienie
    na 75%. Generator PWM – timer TIM3 – po
    pełnym przemapowaniu steruje wyprowadzeniem
    PC6, a więc diodą LD1. Efektem działania
    aplikacji jest zmiana intensywności świecenia
    diody w takt zmian położenia joysticka. Obecność
    w systemie pracującego muteksa można
    zaobserwować próbę zmian położenia joysticka
    z częstotliwością większą niż 1 Hz. Muteks chroniący
    zasób w postaci timera TIM3 nie pozwoli
    na częstsze zmiany intensywności świecenia
    diody LED niż co 500 ms.[...]


    No i autor przygotował taki kod do obsługi tego zadania:

    Code: c
    Log in, to see the code


    No i OK. Autor tutaj użył 2 tasków i mutexa...wszystko cacy. Ale przecież równie dobrze można sobie uruchomić timer który będzie odliczał czas tych 500ms, i będę sprawdzał sobie i dwóch różnych miejscach kodu (gdy wywołuje funkcje odpowiedzialną za wpisanie do PWM) i ten czas minął (oczywiście będę go zerował po każdym użyciu i oczywiście pod wpływem flagi synchronizacyjnej będę decydował czy to w ogóle liczyć...pewnie wiecie o co chodzi więc nie ma się co rozpisywać).
    Ale spójrzcie, mój kod będzie lżejszy i troszkę szybszy (bo scheduler mi się nie wcina). Nie będzie też jakiś cięższy do analizy czy napisania go.
    I tak podsumowując:
    Plusy i minusy
    + Faktycznie wygodniej czeka się na coś w wątkach. Po prostu ustawiam sobie czas który ma upłynąć (uzależniam się od cykli zegara) i zapominam o temacie. Nie muszę używać do tego dodatkowego timera.
    + MOŻE troszkę bardziej uporządkowany kod (ale pisząc rozsądnie "tradycyjnie", to kod też nie jest jakimś wielkim burdelem)

    - Trzeba zaimplementować OSa co zajmuje czas i miejsce w procku. Dodatkowo czas na naukę nowego OSa.
    - Biorąc po uwagę że nie ma wszystkich funkcji API do obsługi sprzętu (typu proste funkcje transmisyjne) to upada argument o pisaniu tylko aplikacji. Tu i tu trzeba pisać funkcje do obsługi sprzętu.

    Mam wrażenie że implementacja RTOSów dla embedded, to po prostu wymysł ludzi, którzy całe życie programowali na PC i gdy musieli się przenieść na embedded to nie ogarnęli tematu do końca (i OK, bo w sumie dla nich wszystko się dzieje równolegle) to na siłę zaczęli implementować RTOSy. I tak już zostało.
    Bo na prawdę, jak się staram, to nie mogę znaleźć na prawdę znaczącej przewagi nad programowaniem tzw. "bare metal".

    A więc powtarzam moje pytanie do bardziej doświadczonych kolegów: Jaki uzysk daje używanie RTOS zamiast programowania "bare metal" pod C. Co w nim jest takiego, że w sumie cały przemysł teraz już pracuje tylko pod RTOSami?

    Zaznaczam, że bardzo się staram dostrzegać te zalety, ale może moje nikłe doświadczenie w temacie nie pozwala mi ich dostrzec :)


    Uff, 30 minut pisałem to pytanie :)
    Pozdro!
  • IGE-XAO
  • #2
    Freddie Chopin
    MCUs specialist
    kiclaw wrote:
    No i właśnie, teraz postaram się zaargumentować dlaczego tak sądzę.
    No bo popatrzcie, wszyscy się cieszą że RTOS taki super, bo mamy wywłaszczenia, i się przerywają wątki i w ogóle możemy upakować procesy a scheduler sam się zajmie tym co i kiedy wywołać.
    Tylko kurczę, przecież normalnie też możemy sobie takie coś zrobić ustawiając np. dla timerów (czy innych przerwań) konkretne priorytety i mieć ich nawet 30. I mieć taki 30 poziomowy program, a proces szumnie nazwany Idle Task to przecież nic innego jak program wykonywany w pętli gdzie jest najniższy poziom przerwań.
    Więc ja osobiście, wolę sobie wywołać timer z jakąś częstotliwością (i odpowiednim priorytetem) i mieć to czarno na białym(oczywiście wykonywać jakiś kod w tym timerze). Nie widzę tutaj jakiegoś uzysku. Pracy jest więcej o może kilka linijek kodu (jednokrotny init timera).

    W ostateczności można by się zgodzić, gdyby nie drobny fakt, ze wątki są "nieskończone", a przerwania raczej niezbyt...

    kiclaw wrote:
    Następna sprawa, tak szumnie nazywanie normalnych flag synchronizacyjnych muteksami i semaforami. No przecież to się w "tradycyjnych" systemach rozwiązuje zwyczajną flagą (tudzież kilkoma flagami) synchronizacyjną.

    Jest to kompletna bzdura, ponieważ obiekty synchronizacyjne blokują wątek, a odczytywanie w kółko zmiennej "volatile bool" raczej niezbyt. Taką flagą mógłbyś w ostateczności porozumieć się przerwanie <-> idle (czyli u Ciebie main()), ale już nic więcej, bo spróbuj tak zsynchronizować wątki (czyli u Ciebie przerwania).

    kiclaw wrote:
    Ale przecież równie dobrze można sobie uruchomić timer który będzie odliczał czas tych 500ms, i będę sprawdzał sobie i dwóch różnych miejscach kodu (gdy wywołuje funkcje odpowiedzialną za wpisanie do PWM) i ten czas minął (oczywiście będę go zerował po każdym użyciu i oczywiście pod wpływem flagi synchronizacyjnej będę decydował czy to w ogóle liczyć...

    Ile ty masz tych timerów w mikrokontrolerze? Wg tego co piszesz można odnieść wrażenie, że "nieskończenie wiele", ale chyba jednak zwykle więcej jest RAMu (a więc miejsca na wątki) niż timerów... Dalej idąc, w Twoim kodzie możesz zagwarantować tylko tyle, ze zmiana PWM nie nastąpi szybciej niż po 500ms, natomiast kod z mutexami i RTOSem (przy prawidłowych priorytetach) w zasadzie gwarantuje, że zmiana wykona się po dokładnie 500ms. Mylisz "synchronizację" - czyli zablokowanie wątku i odblokowanie go w odpowiednim momencie - z prostymi flagami.

    kiclaw wrote:
    Mam wrażenie że implementacja RTOSów dla embedded, to po prostu wymysł ludzi, którzy całe życie programowali na PC i gdy musieli się przenieść na embedded to nie ogarnęli tematu do końca (i OK, bo w sumie dla nich wszystko się dzieje równolegle) to na siłę zaczęli implementować RTOSy. I tak już zostało.
    Bo na prawdę, jak się staram, to nie mogę znaleźć na prawdę znaczącej przewagi nad programowaniem tzw. "bare metal".

    No i nie znajdziesz takiego argumentu, ponieważ z góry założyłeś sobie tezę której teraz bronisz. Zaś linia obrony którą przyjąłeś wygląda mniej więcej tak:
    - po co komu RTOS jak to samo można zrobić na timerach
    - po co komu C++ jak to samo można zrobić w C
    - po co komu C jak to samo można zrobic w assemblerze
    - po co komu ARM jak to samo można zrobić na AVR
    - po co komu AVR jeśli to samo można zrobić na '51
    - po co komu mikrokontroler skoro to samo można zrobić na bramkach logicznych
    - ...

    Można też na Twoje "dowody" spojrzeć tak "po co komu scheduler skoro przecież można sobie napisać swój własny scheduler na przerwaniach". Bo to co opisałeś w skrócie tak wygląda - napisałeś swój własny kod który robi to co typowy RTOS tylko trochę inaczej i przy innych założeniach, traktując to jako dowód że RTOSy są bez sensu bo można sobie napisać scheduler samemu... Funkcję liczącą sinusa na liczbach typu double też można sobie samemu napisać, a jednak stosuje się kod z biblioteki toolchaina...

    A teraz trochę poważniej - rozwiązanie z RTOSem jest skalowalne, w przeciwieństwie do timerów. Tych drugich w systemie jest zwykle kilka-kilkanaście, wiec Twój "prosty" scheduler tyle własnie będzie miał "wątków" (no i nie będziesz miał żadnego timera, bo wszystkie zajmiesz "wątkami"). Natomiast w mikrokontrolerze który ma 64kB RAM spokojnie zmieścisz ze 100 wątków (abstrahując od tego po co komu tyle) używając tylko JEDNEGO timera. Jeśli w swoim rozwiązaniu na przerwaniach chcesz mieć więcej "wątków" na timer, to musisz już kombinować i pisać swój własny kod, który zniszczy całą teorię o tym, że wywłaszczanie możesz zastąpić przerwaniami timera. Zwróć też uwagę na to, że wątek - skoro ma stos - w czasie gdy jest zablokowany ma zapamiętany pełny stan. Coś takiego w przypadku Twoich przerwań zachodzi tylko gdy przerwanie wywłaszcza przerwanie, a w nieskończoność się chyba nie będą wywłaszczać, bo RAMu Ci braknie... Jeśli przerwanie kończysz, kończąc jednocześnie swój "wątek", to o zapamiętanie jakiegokolwiek stanu musisz się martwić sam.

    Rozwiązanie które opisałeś - z przerwaniami - ma mało wspólnego z prawdziwymi wątkami, za to można je uznać za system operujący na zdarzeniach - takie frameworki zresztą też istnieją i też będą bardziej skalowalne niż używanie sprzętowych timerów. Trzeba szukać pod hasłem "hierarchical state machine", "action object", "event driven programming" itd.

    Nigdy nie programowałem na PC (oczywiście więcej niż na zajęciach na uczelni czy coś w tym stylu), ale odkąd użyłem pierwszy raz RTOSa to w zasadzie już nigdy nie napisałem programu bez niego. Podobnie zresztą miałem z C++ - kiedyś twierdziłem, że liczy się tylko assembler, szybko jednak przerzuciłem się na C, potem na C++, a w ostateczności na C++11. Finalnie zacząłem pisać własnego RTOSa w C++11 [;
  • #3
    User removed account
    User removed account  
  • #4
    grko
    Level 33  
    @Freddie Chopin w zasadzie wszystko napisał. Dla mnie osobiście największa zaleta RTOS'a to wywłaszczanie. Używając RTOS mogę pisać drivery, które działają synchronicznie. Mało mnie obchodzi, że taki zapis na kartę SD może trwać nawet 500ms bo czasowo krytyczne rzeczy znajdują się w zadaniu o wyższym priorytecie. Jeżeli projekt jest mały to w miarę łatwo napisać go tak aby był w miarę responsywny bez RTOS'a (czyli tak aby odpowiedź na przerwanie była w miarę szybka). Dla większych programów ciężko coś takiego nawet wyliczyć. W przypadku RTOS znany jest czas odpowiedzi na IRQ(worst case scenario)
  • IGE-XAO
  • #5
    vonar
    Level 28  
    kiclaw wrote:
    Tylko kurczę, przecież normalnie też możemy sobie takie coś zrobić ustawiając np. dla timerów (czy innych przerwań) konkretne priorytety i mieć ich nawet 30. I mieć taki 30 poziomowy program

    Przy takim podejściu jesteś w oczywisty sposób ograniczony dostępnymi peryferiami i liczbą piorytetów przerwań (30 priorytetów wywłaszczania to raczej luksus; AVR - 1 (Xmega 3); Corex-M0(+) - 4; Cortex-M3/M4 - do 128, ale często tylko 16; dsPIC33/PIC24/PIC32 - 7, ...). Dla RTOS limitem jest właściwie tylko dostępna pamięć i czas. Łatwiej zmienić liczbę zadań i priorytetów, bez zastanawiania się, czy wystarczy timerów.

    kiclaw wrote:
    Pracy jest więcej o może kilka linijek kodu (jednokrotny init timera).
    Dla każdego zadania kod zależny od platformy, zamiast jednej inicjalizacji timera systemowego i wykorzystania API RTOS dla zadań. Trudniej przenieść na inny sprzęt, trudniej zasymulować na PC.

    kiclaw wrote:

    Kolega ten argumentował mi, że kompletnie olewam warstwę sprzętową bo do tego są już biblioteki, ja piszę tylko warstwę aplikacyjną. No i właśnie nie do końca. Bo w RTOSach dla jakichś konkretnych uC to znalazłem jedynie jakieś najprostsze API jak np. ustawienie pinów 1/0. O czymś takim jak np. proste funkcje (ale sprawdzone na 100%, najlepiej od producenta) do przesyłania po SPI to można zapomnieć. A więc skoro trzeba je pisać samemu, to argument o pisaniu samej aplikacji odpada.
    To prawda, HAL dla peryferii to osobna sprawa. Ale RTOS zapewnia abstrację dla wątków, więc czasem możesz bez żadnych zmian testować zawierającą sporo kodu "wysokopoziomową" część programu na innym sprzęcie (w tym interakcje między wątkami, np. działąnie kolejki pomiędzy wątkiem obsługującym sieć i dekodującym dźwięk w radiu internetowym) podstawiając tylko inny kod dla zadań niskopoziomowych.

    W tym przykładzie z EP rzeczywiście RTOS to lekka przesada, ale pewnie chodziło tylko o ilustrację zasady działania...

    Dodano po 5 [minuty]:

    O, widzę, że @Freddie Chopin już pozamiatał ;)
  • #6
    piotrva
    VIP Meritorious for electroda.pl
    NO ja dorzucę jeszcze jedno - RTOS pozwala na przerwanie działania wątku w każdej chwili, czyli jak np. napisze sobie 10 000 instrukcji, które zajmują powiedzmy 10 ms to mamy sytuację taką, że:
    1. RTOS pozwoli w zależności od potrzeb na przerwanie tego ciągu zarówno po 1ms jak i po 9ms jak i po 2,3754ms. A dla wykonywanych tam instrukcji nie będzie to miało znaczenia i nie będę musiał tych 10 000 linijek edytować przy zmianie z 9 na 2,3754.
    2. Na przerwaniu, o ile nie napiszesz własnego RTOS'a, musisz albo wykonać daną "funkcję" w całości (czyli 10ms) albo musisz sam wyznaczyć miejsca, w których będzie ona przerywana (np. robiąc maszynę stanów).

    A wiadomo, ze zawsze o ile mamy do napisania miganie diodą i odczyt przycisku to szybciej napiszemy to "bare metal" niż przez RTOS, ale jak projekt zacznie się rozrastać, a już nie mówię o dodaniu nowego "wątku" to na RTOS to kwestia dopisania kilku liniek, a w rozwiązaniu "bare metal" - może być różnie.
  • #7
    vonar
    Level 28  
    Do wymienionych już przewag RTOSa - skalowalność, samo wywłaszczanie jako takie - dochodzi ogólnie łatwiejsze zarządzanie zależnościami. Na przykład co gdy wątek musi dzielić zasoby z innym, o niższym pirorytecie? RTOS załatwia to elegancko dziedziczeniem priorytetów. "Gołe" przerwania wymagałyby więcej komplikacji.

    Dodano po 1 [minuty]:

    Tak nawiasem, aplikacja linkowana statycznie z RTOSem w jedną binarkę to chyba wciąż programowanie "bare metal", nie? ;)
  • #8
    michcior
    Level 30  
    No oczywiście, do wykonania określonego zadania, nie potrzeba systemu operacyjnego, języków wyższego poziomu, skryptów itd. Tak, tylko że napisanie tego zajmie 100 razy więcej czasu. Takie dywagacje, może prowadzić ktoś, kto nigdy nie tworzył niczego komercyjnie. Taka sztuka dla sztuki, to sobie można mnemonikami pisać. Ci, którzy nigdy nie robili niczego co mam mieć określoną nie tylko funkcjonalność, ale jeszcze powstać w określonym czasie i za określoną cenę, żyją w krainie czarów pani Alicji.

    A jeszcze zwykle się wymaga by implementacja jakiegoś zadania RT była: skalowalna, rozszerzalna, łatwa w zrozumieniu przez innych programistów, portowalna, stabilna. Spróbuj spełnić to wszystko bez bazy jaką daje RTOS.

    Dodano po 15 [minuty]:

    vonar wrote:
    Tak nawiasem, aplikacja linkowana statycznie z RTOSem w jedną binarkę to chyba wciąż programowanie "bare metal", nie? ;)


    Trochę ciekawostek, swego czasu Dolinę Krzemową opanował OSE351 detronizując wyroby firmy Montavista, który był niesamowicie zoptymalizowany. Definiowało się wątki, przerwania, kolejki i co tam jeszcze, potem specjalny program, pod daną architekturę kompilował jądro z samych makr assemblera, obsługujące dokładnie to co zostało zdefiniowane. Jak to śmigało!
  • #9
    jnk0le
    Level 18  
    Freddie Chopin wrote:

    kiclaw wrote:
    Następna sprawa, tak szumnie nazywanie normalnych flag synchronizacyjnych muteksami i semaforami. No przecież to się w "tradycyjnych" systemach rozwiązuje zwyczajną flagą (tudzież kilkoma flagami) synchronizacyjną.

    Jest to kompletna bzdura, ponieważ obiekty synchronizacyjne blokują wątek, a odczytywanie w kółko zmiennej "volatile bool" raczej niezbyt. Taką flagą mógłbyś w ostateczności porozumieć się przerwanie <-> idle (czyli u Ciebie main()), ale już nic więcej, bo spróbuj tak zsynchronizować wątki (czyli u Ciebie przerwania).


    Akurat w rozwiązaniach "bare metal" częściej widuje się maszyny stanów gdzie sprawdzenie tego biednego bool'a wystarczy aby przejść do wykonywania pozostałych zadań bez marnowania czasu cpu na polling.

    Freddie Chopin wrote:

    kiclaw wrote:
    Ale przecież równie dobrze można sobie uruchomić timer który będzie odliczał czas tych 500ms, i będę sprawdzał sobie i dwóch różnych miejscach kodu (gdy wywołuje funkcje odpowiedzialną za wpisanie do PWM) i ten czas minął (oczywiście będę go zerował po każdym użyciu i oczywiście pod wpływem flagi synchronizacyjnej będę decydował czy to w ogóle liczyć...

    Ile ty masz tych timerów w mikrokontrolerze? Wg tego co piszesz można odnieść wrażenie, że "nieskończenie wiele", ale chyba jednak zwykle więcej jest RAMu (a więc miejsca na wątki) niż timerów... Dalej idąc, w Twoim kodzie możesz zagwarantować tylko tyle, ze zmiana PWM nie nastąpi szybciej niż po 500ms, natomiast kod z mutexami i RTOSem (przy prawidłowych priorytetach) w zasadzie gwarantuje, że zmiana wykona się po dokładnie 500ms. Mylisz "synchronizację" - czyli zablokowanie wątku i odblokowanie go w odpowiednim momencie - z prostymi flagami.

    Jeden timer da się wykorzystać do więcej niż jednego zadania. Nawet maszyna stanów nie napakowana ciężkimi zadaniami od biedy da radę się zmieścić <1ms.
  • #10
    User removed account
    User removed account  
  • #11
    grko
    Level 33  
    Quote:

    Akurat w rozwiązaniach "bare metal" częściej widuje się maszyny stanów gdzie sprawdzenie tego biednego bool'a wystarczy aby przejść do wykonywania pozostałych zadań bez marnowania czasu cpu na polling.


    Teraz wyobraź sobie że masz kilkanaście (kilkadziesiąt) takich flag. Załóżmy, że nagle wszystkie Twoje ify są spełnione (taki worst case). Ciekawe jak wtedy będzie responsywny Twój system oparty na flagach.

    Quote:

    Jeden timer da się wykorzystać do więcej niż jednego zadania. Nawet maszyna stanów nie napakowana ciężkimi zadaniami od biedy da radę się zmieścić <1ms.


    Tutaj jest ten sam problem. Wszystko jest git jeżeli maszyna stanów nie korzysta z blokującego w jakikolwiek sposób IO.
  • #12
    michalko12
    MCUs specialist
    Piotrus_999 wrote:
    Jak by nie patrzec system operacyjny zdejmuje z nas wiele problemów i zmniejsza ilość potencjalnie mozliwych do popełnienia bledów

    Jedne problemy zdejmuje, inne dokłada.
    Ilość potencjalnie możliwych błędów może i jest mniejsza, ale z tej mniejszej puli błędów niektóre mogą przybrać postać wręcz magicznych, gdzie czasami żeby je rozwikłać trzeba na magicznym poziome znać samego RTOSa i jego ideę działania oraz dobrze znać sam procesor.
    I jak to z RTOSami bywa, same RTOSy są niczym innym jak biblioteką, czyli kodem pisanym przez kogoś innego. Jak pracuje się z bibliotekami to chyba już wszyscy wiedzą. Trzeba domyślać się ( w oparciu o dokumentację czasami bardzo lakoniczną ) co autor miał na myśli implementując składniki RTOSa i mieć nadzieję, że właściwie to wszystko zrozumieliśmy. Nie należy też nastawiać się na to, że w samym RTOSie nie ma żadnych błędów.
  • #13
    User removed account
    User removed account  
  • #14
    michalko12
    MCUs specialist
    Piotrus_999 wrote:
    To juz demagogia :D

    Ale o co chodzi???
    Quote:
    Demagogia
    1. głoszenie chwytliwych, zgodnych z oczekiwaniami większości haseł politycznych lub ekonomicznych, wysuwanie w celu zdobycia poparcia społecznego prostych i zazwyczaj populistycznych propozycji rozwiązania skomplikowanych problemów; populizm, politykierstwo;
    2. wszelka akcja obliczona na łatwy poklask i schlebianie najniższym gustom


    Niestety, ale współbieżność ma swoje uroki jak chociażby zakleszczenie wątków.

    Piotrus_999 wrote:
    No właśnie ze mniej wg mnie.

    Nie porównuj OS na PC do RTOSa na uC. RTOS ani trochę nie zwalnia z konieczności znania samego procesora. W przypadku debugowania czasami musisz szperać po stosach wątków i przerwań. W przypadku Cortexów są to już dwa obszary stosów dla przerwań wykorzystywanych przez RTOSa. W przypadku "bare metal" rzadko kiedy korzysta się z obydwu trybów procesora i ciągnie się na jednym stosie.
  • #15
    User removed account
    User removed account  
  • #16
    tplewa
    Level 39  
    Freddie Chopin wrote:
    Finalnie zacząłem pisać własnego RTOSa w C++11 [;


    Bo chyba masz za duzo wolnego czasu :P z reszta sie w 100% zgadzam :)
  • #17
    Freddie Chopin
    MCUs specialist
    Piotrus_999 wrote:
    michalko12 wrote:
    Jedne problemy zdejmuje, inne dokłada.


    To juz demagogia :D

    Raczej rzeczywistość (; Również moim zdaniem pisanie programów z użyciem RTOSa jest bardziej skomplikowane. Nie uważałbym tego jednak za wadę, ponieważ program z RTOSem zwykle ma sporo więcej funkcji - stopień skomplikowania jest więc z grubsza proporcjonalny do funkcjonalności i tyle.

    jnk0le wrote:
    Akurat w rozwiązaniach "bare metal" częściej widuje się maszyny stanów gdzie sprawdzenie tego biednego bool'a wystarczy aby przejść do wykonywania pozostałych zadań bez marnowania czasu cpu na polling.

    Wydaje mi się, że nigdy nie używałeś RTOSa... Ideę synchronizacji można by opisać - oczywiście skrótowo - mniej więcej tak:
    - dowolna ilość wątków mówi, że nie może się wykonywać dalej dopóki nie nastąpi jakieś zdarzenie (np. dopóki nie przyjdą jakieś dane po jakimś interfejsie),
    - wątki takie zostają zablokowane praktycznie bez żadnej interwencji programisty - jedyne co trzeba zrobić to wywołać funkcję np. "semaphore.wait()",
    - dowolna ilość źródeł (wątków lub przerwań) może zgłosić nadejście zdarzenia na które jakiś wątek (jeden lub wiele) oczekuje (lub nie) - np. przerwanie UARTa wrzuca odebrane dane do kolejki,
    - w tym momencie - N-A-T-Y-C-H-M-I-A-S-T, a nie dopiero przy następnym sprawdzaniu stanu flagi, nie po zakończeniu aktualnie realizowanej funkcji maszyny stanów, nie "za krótką chwilę", tylko natychmiast - wątek (lub wątki) który na dane oczekiwały zostaje odblokowany,
    - jeśli odblokowany wątek ma odpowiednio wysoki priorytet (czyli jeśli programista określił, że zadanie odbioru tych danych jest "bardzo ważne"), to wątek ten wznowi swoje wykonywanie N-A-T-Y-C-H-M-I-A-S-T po powrocie z przerwania - jeśli zdarzenie było zgłoszone przez przerwanie - lub natychmiast po zgłoszeniu tego zdarzenia - jeśli zostało ono zgłoszone przez wątek.

    Ja nie mówię, że maszyny stanów czy "event driven programming" są złe albo gorsze niż RTOS. To po prostu coś zupełnie innego - mają inne plusy, inne minusy, inne wady i inne zalety. Niemniej jednak nie jesteś w stanie osiągnąć odpowiedzi "real-time" w żadnym z tych dwóch paradygmatów, za to w real-time operating system - owszem.

    Quote:
    Jeden timer da się wykorzystać do więcej niż jednego zadania.

    Zgadza się - tak właśnie działa RTOS. Wracamy więc do punktu wyjścia, czyli pytania "po co komu scheduler skoro można sobie taki napisać samemu".

    Quote:
    Nawet maszyna stanów nie napakowana ciężkimi zadaniami od biedy da radę się zmieścić <1ms.

    No widzisz... A RTOS napakowany dowolnie ciężkimi zadaniami, tak że układ obciążony jest w 100%, da radę - i to nie "od biedy" tylko "ot tak" - zmieścić się w kilkanaście-kilkadziesiat cykli zegara. Powiedzmy że w 100, czyli przy układzie który działa na 50MHz mieścisz się w dwie MIKROsekundy.
  • #18
    BlueDraco
    MCUs specialist
    Moim zdaniem za użyciem RTOS przemawia po prostu lenistwo, zresztą podobnie jak za 99% praktyk programistycznych. Komuś, kto programował aplikacje na PC, łatwiej oprogramować mikrokontroler przy użyciu RTOS niż przy użyciu przyzwoitych zdarzeń - do tego trzeba i dużej wiedzy i praktyki. Początkującemu łatwiej pisze się program w stylu "przeczytaj pierwszy znak, potem przeczytaj drugi", niż "przeczytaj znak i pójdź ścieżką zależną od tego, który to był znak". To pierwsze łatwo zrobić pod RTOS, to drugie wymaga automatu (to takie stare polskie słowo, używane przed fatalnym spolszczeniem angielskiego "state machine").

    Trudniej jest zaprojektować poprawnie hordę współpracujących automatów, niż napisać program podobny do tego na PC. To zresztą również kwestia czasu i kosztów opracowania rozwiązania. Automat jest zawsze wydajniejszy, ale sporo trudniejszy dla programisty, a w większości projektów nie chodzi o to, żeby urządzenie dobrze i szybko działało, a o to, żeby szybko na nim zarobić - i to zapewnia właśnie RTOS, z którym poradzi sobie jako-tako nawet średnio zdolny programista.

    Co do rozważań nt. "implementowałności": rzadko potrzebujemy tylu priorytetów, ile jest zdarzeń do obsługi. Procesory Cortex umożliwiają programowe zgłaszanie przerwań asynchronicznych, zarówno jedynego PendSV jak i dowolnej liczby przez NVIC, więc potencjalnie są świetnie przystosowane do programowania zdarzeniowego. W przypadku opisanym przez Kolegę wyżej wystarczy jeden systemowy timer (a nie po jednym dla każdego zadania) i scheduler programowo zgłaszający zdarzenia - przerwania, których obsługę procesor wywoła już sprzętowo.

    Zrobiłem parę projektów w takiej konwencji i spodobały mi się tak bardzo, że mam ochotę na więcej.
  • #19
    Freddie Chopin
    MCUs specialist
    BlueDraco wrote:
    Moim zdaniem za użyciem RTOS przemawia po prostu lenistwo, zresztą podobnie jak za 99% praktyk programistycznych.

    Bardzo merytoryczny argument. W zasadzie większość Twojego postu można niestety streścić tak - "jestem mega mistrzem programowania, każdy kto robi coś inaczej niż ja jest niedouczonym leniem"... Praktycznie nie ma tam żadnego merytorycznego argumentu, za to pełno jest wstawek o nieuctwie i lenistwie. Ciężko z czymś takim dyskutować.

    Skoro za użyciem RTOS przemawia lenistwo, to co przemawia za użyciem C zamiast assemblera? Albo ARMa zamiast '51? Albo mikrokontrolera zamiast bramek logicznych? Albo elektroniki cyfrowej zamiast analogowej? Lenistwo?

    BlueDraco wrote:
    Trudniej jest zaprojektować poprawnie hordę współpracujących automatów

    Bardzo łatwo, tylko trzeba wyjść poza swoje własne utarte schematy i zrozumieć, że automaty nie są czymś sprzecznym z wielowątkowością. Bo w czym problem, żeby zaprojektować system "event driven" przy użyciu automatów i wielu wątków? W jednym wątku jeden automat, przy okazji skrajnie łatwy do napisania bo opierający się o "event loop" i systemowe kolejki. https://en.wikipedia.org/wiki/Event_loop

    BlueDraco wrote:
    Automat jest zawsze wydajniejszy

    Chętnie zobaczę Twój automat który będzie reagował na zdarzenie w ciągu 100 taktów zegara (oczywiście założenie jest takie, że gdy wystąpiło zdarzenie układ jest już czymś zajęty). A potem sprawdzimy czy na pewno będzie wydajniejszy niż system wielowątkowy. Bez obrazy, ale to co napisałeś tutaj jest akurat śmieszne... Automat będzie wydajniejszy tylko gdy Twoje urządzenie nie robi nic przez 99,666% czasu i tylko w kółko sprawdza flagi (i tylko gdy nie ma tych flag zbyt wielu) - w każdym innym przypadku będzie dokładnie odwrotnie.

    BlueDraco wrote:
    Procesory Cortex umożliwiają programowe zgłaszanie przerwań asynchronicznych, zarówno jedynego PendSV jak i dowolnej liczby przez NVIC, więc potencjalnie są świetnie przystosowane do programowania zdarzeniowego. W przypadku opisanym przez Kolegę wyżej wystarczy jeden systemowy timer (a nie po jednym dla każdego zadania) i scheduler programowo zgłaszający zdarzenia - przerwania, których obsługę procesor wywoła już sprzętowo.

    No i znowu - "RTOS nie jest nikomu do niczego potrzebny, bo przecież napisałem sobie tutaj własny prawie-RTOS który robi prawie to samo".

    Skoro łatwość użycia jakiegoś paradygmatu i łatwość uzyskania dzięki niemu efektów nie jest jakąkolwiek zaletą, to jak można uzasadnić używanie C zamiast assemblera? Mógłbym w 5 minut napisać identyczny post do Twojego zmieniając "RTOS" na assembler i obstawiam ze zbyt wielu zdań bym nie musiał zmieniać. Na przykład:

    "Moim zdaniem za użyciem C przemawia po prostu lenistwo, zresztą podobnie jak za 99% języków innych niż assembler. Komuś, kto programował aplikacje na PC, łatwiej oprogramować mikrokontroler przy użyciu C niż przy użyciu assemblera - do tego trzeba i dużej wiedzy i praktyki."

    "Trudniej jest zaprojektować poprawnie hordę współpracujących funkcji w assemblerze, niż napisać program w C."

    "Assembler jest zawsze wydajniejszy, ale sporo trudniejszy dla programisty, a w większości projektów nie chodzi o to, żeby urządzenie dobrze i szybko działało, a o to, żeby szybko na nim zarobić - i to zapewnia właśnie C, z którym poradzi sobie jako-tako nawet średnio zdolny programista."

    "Procesory Cortex mają świetny zestaw instrukcji, więc potencjalnie są świetnie przystosowane do programowania w assemblerze."

    Ta dyskusja robi się naprawdę głupia.
  • #20
    tplewa
    Level 39  
    BlueDraco wrote:
    Moim zdaniem za użyciem RTOS przemawia po prostu lenistwo, zresztą podobnie jak za 99% praktyk programistycznych


    Jeszcze jest cos takiego jak koszt wytworzenia oprogramowania - mozna sie bawic samemu i pisac wszystko. Pytanie kto za to zaplaci i jaka finalna bedzie cena produktu, zakladajac to ze programistow za 5zl na godzine raczej nie znajdziesz :)

    RTOS sporo ulatwia i mocno przyspiesza prace (zwlaszcza przy pisaniu rozbudowanego programu). Owszem mozna program napisac na 1000000 innych sposobow klepiac wszystko od zera - ale to zalezy w duzej mierze od aplikacji jaka tworzymy, wolnego czasu (jesli to robimy hobbystycznie) czy budzetu jaki mamy (jesli piszemy komercyjnie). Sa aplikacje do ktorych nie ma sensu dawac RTOS-a (ba sa na tyle proste ze to byl by przerost formy nad trescia), a sa takie gdzie bez niego bylo by na prawde trudno.

    Dlatego troche z tym lenistwem sie nie zgodze.

    W hobby czasami mozemy sobie pozwolic na szalenstwo, jak widac Freddie Chopin klepie RTOS-a... ja mam czasem odpaly i pisze sobie dla jaj wszystko w ASM bez grama kodu w C (od AVR poprzez ARM, MIPS do x86) lub jakies inne szalenstwa odstawiam :) Ale takich fanaberii hobbystow to ja bym raczej nie bral pod uwage w ocenianiu tego co i jak robia programisci...
  • #21
    BlueDraco
    MCUs specialist
    Nigdzie nie napisałem, że lenistwo jest złą motywacją w projektach oprogramowania. Ja np. nie używam STL na STM32 z czystego lenistwa - nie chce mi się dużo stukać w klawiaturę, a kod źródłowy bez SPL wychodzi min. 6 razy krótszy niż z SPL.
    Nie uważam też , by stosowanie RTOS było czymś złym - to po prostu kwestia kosztów czasu i łatwości uruchomienia kodu.
    Freddie:

    Zaprojektowanie wielu automatów zawsze jest trudne, niezależnie od tego, jak je zaimplementujemy. Pewnie ciut łatwiejsze, kiedy RTOS kosztem czasu procesora, więc i wydajności i poboru mocy, zamaskuje błędy w budowie programu, albo raczej sprawi, że średni jakościowo program będzie miał szansę działać.

    O zaletach RTOS napisałem, szkoda, że tego nie zauważyłeś.

    Ja zwykle zastanawiam się, ile można stracić, a ile zyskać na pójściu na łatwiznę. O ile w przypadku dylematu "C czy asembler" sprawa jest dla mnie jasna (ARM - wyłącznie C, AVR - raczej C, 51 czy PIC - tylko asembler), to w przypadku RTOS przy projektach, w których nie ma dużych obcych modułów (stos IP, system plików) moja sympatia jest po stronie rozwiązania czysto zdarzeniowego, bez RTOS. Im więcej obcych komponentów - tym większy zysk ze stosowania RTOS, który toleruje różne niezręczności w kodzie, którego sami nie napisaliśmy.

    Reakcja na zdarzenia w poprawnie zaprojektowanym systemie zdarzeniowym będzie zawsze szybsza niż przy RTOS, bo nie tracimy czasu na scheduler i przełączanie zadań, które jest ciut wolniejsze niż obsługa wyjątku..

    tplewa: pełna zgoda - to właśnie miałem na myśli.
  • #22
    tplewa
    Level 39  
    BlueDraco wrote:
    AVR - raczej C, 51 czy PIC - tylko asembler


    Luz :)

    Ale tego akurat nie rozumiem :) tzn. o ile zgodze sie z 51 :) to PIC-e i AVR-y (8 bitowe) raczej bym stawial na tym samym poziomie :)

    Owszem mozna napisac wszystko sprawniej, nawet mozna sobie napisac wlasnego mini RTOS-a ktory bedzie idealnie dostosowany do potrzeb naszej aplikacji i on tak samo moze okazac sie szybszy :) Pytanie tylko jest jedno czy ta szybkosc nam cos daje. Czasem optymalizacja jest potrzebna i wtedy piszemy sobie fragmenty w ASM aby maksymalnie wycisnac co sie da z procesora (jesli kod zoptymalizowany przez kompilator mozna poprawic), natomiast jesli takie cos nie wnosi nic wielkiego do aplikacji to jest to tez bez sensu.

    Tutaj nie ma jakiejs zlotej recepty - trzeba podchodzic do tego rozsadnie :) No chyba ze jak wczesniej pisalem - mamy chec na wariactwo i chcemy sie pobawic dla frajdy...
  • #23
    User removed account
    User removed account  
  • #24
    BlueDraco
    MCUs specialist
    tplewa:
    Zobacz, jak długi jest kod wygenerowany przez kompilator dla typowych, prostych operacji w C, np. dodawanie liczb 16-bitowych, sumowanie wektora takich liczb itp.. AVR jest przyjazny dla kompilatora (chociaż kompilator niekoniecznie w to wierzy), 51 i PIC (8-bitowy) to nie są architektury, na które daje się normalnie generować kod z języka wysokiego poziomu.
    AVR ma liniowe adresowanie pamięci (niestety aż trzech oddzielnie). PIC tego nie ma. Zrób w PIC jeden bufor na 150 bajtów danych... ;)
  • #25
    grko
    Level 33  
    Quote:

    "Bad programmers worry about the code. Good programmers worry about data structures and their relationships."


    Linus Torvalds
  • #26
    michcior
    Level 30  
    BlueDraco wrote:
    PIC (8-bitowy) to nie są architektury, na które daje się normalnie generować kod z języka wysokiego poziomu.

    Trochę, się rozejrzyj, zanim wydasz wyrok. Jest PIC12, PIC16 i PIC18, wszystko to są 8-bitowe architektury, PIC18 jest za założenia dostosowany do pisania w C.
  • #27
    User removed account
    User removed account  
  • #28
    tplewa
    Level 39  
    michcior wrote:
    BlueDraco wrote:
    PIC (8-bitowy) to nie są architektury, na które daje się normalnie generować kod z języka wysokiego poziomu.

    Trochę, się rozejrzyj, zanim wydasz wyrok. Jest PIC12, PIC16 i PIC18, wszystko to są 8-bitowe architektury, PIC18 jest za założenia dostosowany do pisania w C.


    A no dokladnie - problemem z PIC-ami jest jeszcze brak dobrego darmowego kompilatora. Ale to nie jest akurat podstawa do oceny procesorow.

    a co do cytatow to ja jeszcze dodam:
    Quote:
    For every complex problem, there is a solution that is simple, neat, and wrong.


    H. L. Mencken Quotes

    ;)
  • #29
    Marico
    Level 20  
    BlueDraco wrote:

    AVR ma liniowe adresowanie pamięci (niestety aż trzech oddzielnie).


    Pierwszy z brzegu:
    http://ww1.microchip.com/downloads/en/DeviceDoc/30327b.pdf
    cytat:
    • Linear program memory addressing to 2 Mbyte
    • Linear data memory addressing up to 4 Kbytes


    BlueDraco wrote:

    Zrób w PIC jeden bufor na 150 bajtów danych... ;)


    Proszę:
    char buf[150];
  • #30
    BlueDraco
    MCUs specialist
    OK, PIC18 to inna bajka. Miałem na myśli, jak nietrudno zgadnąć, "tradycyjne" PIC16/12/10.



    Moderated By dondu:

    Koledzy ... bardzo proszę, nie zbaczajcie z tematu RTOS rzecz kolejnej dyskusji o wyższości jednych mikrokontrolerów i ich kompilatorów nad drugimi, bo wszyscy macie rację ... ale tylko z Waszego punktu widzenia.

    Z góry dziękuję za zrozumienie :)

pcbway logo