logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[RTOS] vs Bare Metal - Zalety i wady w systemach embedded

kiclaw 02 Gru 2015 18:38 6423 56
Najlepsze odpowiedzi

Jakie są praktyczne zalety używania RTOS zamiast programowania bare metal w systemach embedded?

RTOS opłaca się przede wszystkim wtedy, gdy aplikacja rośnie: daje preempcję, blokowanie wątków na semaforach i mutexach zamiast aktywnego sprawdzania flag, oraz skalowalny sposób obsługi wielu zadań przy ograniczonej liczbie timerów i priorytetów przerwań [#15205493][#15205580] Wątek ma własny stos i zachowany pełny stan, więc można go wstrzymać i wznowić bez ręcznego rozbijania logiki na automaty stanów, a zdarzenie może odblokować zadanie od razu po przerwaniu, jeśli ma odpowiedni priorytet; to daje przewidywalny czas reakcji w najgorszym przypadku [#15205493][#15209389] RTOS ułatwia też zarządzanie współdzielonymi zasobami, np. przez dziedziczenie priorytetów [#15205703] Dodatkową zaletą jest rozdzielenie warstwy aplikacji od niskopoziomowych driverów, co ułatwia testy i przenoszenie wysokopoziomowego kodu na inny sprzęt [#15205588] W małych, prostych projektach bare metal albo podejście zdarzeniowe bywa prostsze i szybsze do napisania, ale przy większej liczbie zadań, blokującym I/O, stosach IP czy systemach plików RTOS zwykle daje wyraźny zysk w organizacji i utrzymaniu kodu [#15209449][#15208062]
Wygenerowane przez model językowy.
REKLAMA
  • #1 15205059
    kiclaw
    Poziom 16  
    Posty: 252
    Pomógł: 4
    Ocena: 5
    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.
    Cytat:
    [...]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:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    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!
  • REKLAMA
  • #2 15205493
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    kiclaw napisał:
    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 napisał:
    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 napisał:
    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 napisał:
    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 [;
  • REKLAMA
  • #3 15205531
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #4 15205580
    grko
    Poziom 33  
    Posty: 1386
    Pomógł: 247
    Ocena: 141
    @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)
  • #5 15205588
    vonar
    Poziom 28  
    Posty: 690
    Pomógł: 151
    Ocena: 30
    kiclaw napisał:
    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 napisał:
    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 napisał:

    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 15205687
    piotrva
    VIP Zasłużony dla elektroda
    Posty: 6409
    Pomógł: 625
    Ocena: 735
    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 15205703
    vonar
    Poziom 28  
    Posty: 690
    Pomógł: 151
    Ocena: 30
    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? ;)
  • REKLAMA
  • #8 15208062
    michcior
    Poziom 30  
    Posty: 1132
    Pomógł: 159
    Ocena: 462
    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 napisał:
    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 15208805
    jnk0le
    Poziom 18  
    Posty: 172
    Pomógł: 33
    Ocena: 31
    Freddie Chopin napisał:

    kiclaw napisał:
    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 napisał:

    kiclaw napisał:
    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 15208857
    Konto nie istnieje
    Konto nie istnieje  
  • #11 15208858
    grko
    Poziom 33  
    Posty: 1386
    Pomógł: 247
    Ocena: 141
    Cytat:

    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.

    Cytat:

    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 15208992
    michalko12
    Specjalista - Mikrokontrolery
    Posty: 3394
    Pomógł: 462
    Ocena: 321
    Piotrus_999 napisał:
    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 15209048
    Konto nie istnieje
    Konto nie istnieje  
  • #14 15209069
    michalko12
    Specjalista - Mikrokontrolery
    Posty: 3394
    Pomógł: 462
    Ocena: 321
    Piotrus_999 napisał:
    To juz demagogia :D

    Ale o co chodzi???
    Cytat:
    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 napisał:
    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 15209113
    Konto nie istnieje
    Konto nie istnieje  
  • #17 15209389
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Piotrus_999 napisał:
    michalko12 napisał:
    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 napisał:
    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.

    Cytat:
    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".

    Cytat:
    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 15209420
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    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 15209449
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    BlueDraco napisał:
    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 napisał:
    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 napisał:
    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 napisał:
    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 15209499
    tplewa
    Poziom 39  
    Posty: 6727
    Pomógł: 222
    Ocena: 991
    BlueDraco napisał:
    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 15209545
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    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 15209571
    tplewa
    Poziom 39  
    Posty: 6727
    Pomógł: 222
    Ocena: 991
    BlueDraco napisał:
    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 15209608
    Konto nie istnieje
    Konto nie istnieje  
  • #24 15209649
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    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 15209672
    grko
    Poziom 33  
    Posty: 1386
    Pomógł: 247
    Ocena: 141
    Cytat:

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


    Linus Torvalds
  • #26 15209683
    michcior
    Poziom 30  
    Posty: 1132
    Pomógł: 159
    Ocena: 462
    BlueDraco napisał:
    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 15209714
    Konto nie istnieje
    Konto nie istnieje  
  • #28 15209722
    tplewa
    Poziom 39  
    Posty: 6727
    Pomógł: 222
    Ocena: 991
    michcior napisał:
    BlueDraco napisał:
    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:
    Cytat:
    For every complex problem, there is a solution that is simple, neat, and wrong.


    H. L. Mencken Quotes

    ;)
  • #29 15209848
    Marico
    Poziom 20  
    Posty: 409
    Pomógł: 28
    Ocena: 60
    BlueDraco napisał:

    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 napisał:

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


    Proszę:
    char buf[150];
  • #30 15210026
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    OK, PIC18 to inna bajka. Miałem na myśli, jak nietrudno zgadnąć, "tradycyjne" PIC16/12/10.



    Moderowany przez 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 :)

Podsumowanie tematu

✨ Dyskusja dotyczy porównania systemów RTOS (Real-Time Operating Systems) i programowania "bare metal" w kontekście systemów embedded. Uczestnicy wymieniają zalety i wady obu podejść, podkreślając, że RTOS oferuje lepsze zarządzanie wątkami, synchronizację oraz wywłaszczanie, co jest korzystne w większych projektach. Z drugiej strony, programowanie "bare metal" może być prostsze i szybsze w przypadku mniejszych aplikacji, ale staje się bardziej skomplikowane w miarę rozwoju projektu. Wskazano również na problemy związane z debugowaniem i zarządzaniem zasobami w obu podejściach. Uczestnicy podkreślają, że wybór między RTOS a "bare metal" powinien być uzależniony od specyfiki projektu, jego skali oraz wymagań czasowych.
Wygenerowane przez model językowy.
REKLAMA