eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronika › C++ ośla łączka
Ilość wypowiedzi w tym wątku: 91

  • 31. Data: 2023-02-16 13:20:42
    Temat: Re: C++ ośla łączka
    Od: Piotr Gałka <p...@c...pl>

    W dniu 2023-02-15 o 19:50, heby pisze:

    > I nagle chcesz odczytywać wewnatrzny status CPU, co do którego nie ma
    > nawet pewności, że istnieje na jakiejś architekturze sprzętowej, ani jak
    > działa w konkretnym przypadku. To proszenie się o katastrofę. Od tej
    > pory C musiał by być *tylko* na procesory z flagą C i to w dodatku
    > działającą w jakiś specyficzny sposób. A jak jej nie ma wcale?

    Akurat brat przyszedł do mnie z pytaniem, jak coś zrobić w C (o tym
    dalej bo ja nie znam odpowiedzi ale powiedziałem mu, że zapytam
    mądrzejszych ode mnie) więc wspomniałem mu o tym co tu napisałem o bicie
    przeniesienia, czy parzystości.

    On ma całkiem odmienne zdanie od Twojego.
    Nie widzi żadnego problemu, aby w C dla zmiennych całkowitych było na
    przykład pojęcie bitu parzystości. Jak procesor go ma to kompilator
    korzysta bezpośrednio, a jak nie ma to wtedy wylicza tak jak ja w tej
    crc16().
    Gdzie tu proszenie się o katastrofę?
    A....
    Nie wspomniałem mu o różnych reprezentacjach zmiennych o których pisałeś
    z czego on (tak jak i ja) całkowicie nie zdaje sobie sprawy. Ale
    faktycznie są stosowane jakieś inne reprezentacje?

    A teraz pytanie brata na które nie znamy odpowiedzi.

    Ogólnie to jest pierwsze podejście do procesorów ARM (nie wiem z którym
    w tej chwili walczy (Silabs EFM32PG22..., EFM32PG23..., a może EFM32TG11..).
    Zanim użyje procesor po raz pierwszy musi opanować podstawowe działania
    no i jest właśnie na tym etapie.

    On by potrzebował sizeof(funkcja).

    Ale jak próbuje to zrobić to dostaje 1.
    Zasugerowałem, że może jak wstawi etykietę (przypomnieliśmy sobie, że
    chyba w C coś takiego jest) na nawiasie zamykającym funkcję to uda się
    policzyć różnicę między jej adresem a adresem początku funkcji.
    Właśnie mi krzyknął (jego pokój jest piętro niżej), że z zewnątrz
    funkcji nie ma dostępu do tej etykiety.

    Napiszę do czego mu to potrzebne bo czasem może rozwiązanie głównego
    problemu robi się inaczej niż on kombinuje.

    Wczoraj wieczorem wspólnie tłumaczyliśmy dwa akapity datasheet, czy
    manuala (nie wiem - on mi po prostu podświetlił akapit na ekranie i
    chodziło o to jak to rozumiemy).

    Tam było, że jak się coś robi z programowaniem flasha z wnętrza programu
    to ogólnie nie ma gwarancji, że wszystko się uda. I to zdanie było
    ogólne - czyli nawet jak ruszasz inną stronę niż jesteś to może coś nie
    zadziałać. Nie napisali co dokładnie, ale skoro może coś się nie udać to
    my tego nie chcemy. Napisali, żeby przekopiować odpowiednią funkcję do
    RAMu, wywołać ją i z niej uruchomić proces kasowania, czy programowania
    flasha.

    Już opanował wywoływanie funkcji po jej skopiowaniu do RAMu.
    Z adresem początku sobie radzi, choć mówi, że wskaźnik na funkcję jest
    zawsze większy o 1 od prawdziwego adresu i ustalając fragment do
    kopiowania on musi tę jedynkę odejmować.
    Wszystko już działa, tylko, że na razie rozmiar funkcji bierze z sufitu
    na zapas.

    No i jedyne co brakuje do odhaczenia kolejnej funkcjonalności to
    ustalenie w jednej funkcji jaki jest sizeof drugiej funkcji.

    Może wiesz (lub ktoś inny) jak to się robi.
    P.G.


  • 32. Data: 2023-02-16 13:45:45
    Temat: Re: C++ ośla łączka
    Od: heby <h...@p...onet.pl>

    On 16/02/2023 12:46, Grzegorz Niemirowski wrote:
    >> Do tego, co piszesz, służa bariery/fence.
    > Możesz podać przykład na ATmegę?

    Nie. Bo mowa o C ogólnie. Szczególne dla AVR stosujemy sztuczki
    asemblerowe, nielegalne w danej sytuacji słowa kluczowe itd itp. Sam
    fakt użycia "przerwania" jest z definicji nieistniejącym bytem w C i
    wymaga poza-językowych narzędzi, bo sam język nie dostarcza wsparcia dla
    przerwań wiec trudno tez, aby dostarczał mechnizmy ich wspierania.

    Uwaga o volatile dotyczy *języka* C a nie implementacji tego na AVR.

    Jeśli pytałbyś o ogólny C++ to zasugeroeałbym okolice:

    https://mariadb.org/wp-content/uploads/2017/11/2017-
    11-Memory-barriers.pdf

    Czy poprawna implementacja na AVR istnieje - nie wiem. Może kiedyś zerknę.

    >> Jeśli potraktujesz przerwania jako wątki preemptive, to tak naprawdę
    >> piszesz o zagadnieniu dostępu do zmiennych przez kilka watków. Tego
    >> zagadnienia *NIE* należy rozwiązywać za pomocą volatile, ono nie
    >> powstało do tego i sie do tego NIE nadaje.
    > Wiem. Nic o wątkach nie pisałem.

    Mimo to przerwanie jest czymś identycznym z wątkiem preemptive. Ma te
    same konsekwencje i dla dużych procesorów, szczególnie wielordzeniowych,
    niesie z sobą dokładnie te same zagrożenia, co wątki. I nie jest tak, że
    świat kończy się na 8051. Wielordzeniowe procesory embedded to nic
    specjalnie dziwnego.

    Tam, wszyscy programiści od volatile, wybiją sobie zęby o protokoły
    synchronizacji cache, out-of-order execution itd itp.

    PS. Zaznaczam, że nic nie pisałeś o AVR w poprzednim poście, wiec w
    ogólnym wypadku, volatile nie może i nie powinno być uzywane w celu
    synchronizacji zmiannych w przerwaniach. W szczególnym, kiedy znasz
    konkretną architekturę, być może.


  • 33. Data: 2023-02-16 13:54:54
    Temat: Re: C++ ośla łączka
    Od: heby <h...@p...onet.pl>

    On 16/02/2023 13:20, Piotr Gałka wrote:
    > Nie widzi żadnego problemu, aby w C dla zmiennych całkowitych było na
    > przykład pojęcie bitu parzystości. Jak procesor go ma to kompilator
    > korzysta bezpośrednio, a jak nie ma to wtedy wylicza tak jak ja w tej
    > crc16().

    A do czego to potrzebne przeciętnemu suwerenowi? Z tej samej przyczyny w
    C nie ma gotowej funkcji do wygrywania melodyjek na głośniczku podpiętym
    pod PB.3. Jest dosłownie 3 osoby na świecie z tą potrzebą.

    Dodakowo: jak liczysz parzystość?

    Czy -0 i +0 są, czy nie, parzyste? Przypadkowo zakładajmy architekturę
    wspierajacą signed-magnitude albo 1-complement. Oba dopuszczalne w C. W
    obu występują dwa zera.

    > Gdzie tu proszenie się o katastrofę?

    W tym, że standard nie definiuje nawet reprezentacji bitowej liczb.
    Skoro tak, to niby jak miałby określać znacznie głębsze detale jak
    parzystość, przeniesienie czy cokolwiek detalicznego i związanego z
    konkretną architekturą?

    > A....
    > Nie wspomniałem mu o różnych reprezentacjach zmiennych o których pisałeś
    > z czego on (tak jak i ja) całkowicie nie zdaje sobie sprawy. Ale
    > faktycznie są stosowane jakieś inne reprezentacje?

    Nie są w praktyce, poza małymi wyjątkami.

    Ale standard nie przejmuje się, czy są stosowane, czy nie. Są
    dopuszczalne, wiec nie możesz zakładać, że nie mogą istnieć. Standard
    nie może ich ignorować.

    > On by potrzebował sizeof(funkcja).

    [...]

    > Już opanował wywoływanie funkcji po jej skopiowaniu do RAMu.

    Czytaj wątek z przed paru dni:

    "MCU - start programu z RAM"

    > Z adresem początku sobie radzi, choć mówi, że wskaźnik na funkcję jest
    > zawsze większy o 1 od prawdziwego adresu i ustalając fragment do
    > kopiowania on musi tę jedynkę odejmować.
    > Wszystko już działa, tylko, że na razie rozmiar funkcji bierze z sufitu
    > na zapas.
    > No i jedyne co brakuje do odhaczenia kolejnej funkcjonalności to
    > ustalenie w jednej funkcji jaki jest sizeof drugiej funkcji.
    > Może wiesz (lub ktoś inny) jak to się robi.

    Było to omawiane w tym wątku. Ogólnie, jesli ma to związek z
    programowaniem flasha, to boje się zapytać, czy jakoś się zabezpieczacie
    prze utratą zasilania w trakcie.


  • 34. Data: 2023-02-16 14:35:09
    Temat: Re: C++ ośla łączka
    Od: "J.F" <j...@p...onet.pl>

    On Thu, 16 Feb 2023 13:45:45 +0100, heby wrote:
    > On 16/02/2023 12:46, Grzegorz Niemirowski wrote:
    >>> Do tego, co piszesz, służa bariery/fence.
    >> Możesz podać przykład na ATmegę?
    >
    > Nie. Bo mowa o C ogólnie. Szczególne dla AVR stosujemy sztuczki
    > asemblerowe, nielegalne w danej sytuacji słowa kluczowe itd itp. Sam
    > fakt użycia "przerwania" jest z definicji nieistniejącym bytem w C i
    > wymaga poza-językowych narzędzi, bo sam język nie dostarcza wsparcia dla
    > przerwań wiec trudno tez, aby dostarczał mechnizmy ich wspierania.

    W standardzie jezyka niby nie ma, ale w praktyce czesto jest.
    Widac potrzebne, tylko ze realizacja rózna w róznych systemach,
    to nie wsadzili do jezyka.

    >>> Jeśli potraktujesz przerwania jako wątki preemptive, to tak naprawdę
    >>> piszesz o zagadnieniu dostępu do zmiennych przez kilka watków. Tego
    >>> zagadnienia *NIE* należy rozwiązywać za pomocą volatile, ono nie
    >>> powstało do tego i sie do tego NIE nadaje.
    >> Wiem. Nic o wątkach nie pisałem.
    >
    > Mimo to przerwanie jest czymś identycznym z wątkiem preemptive. Ma te
    > same konsekwencje i dla dużych procesorów, szczególnie wielordzeniowych,
    > niesie z sobą dokładnie te same zagrożenia, co wątki. I nie jest tak, że
    > świat kończy się na 8051. Wielordzeniowe procesory embedded to nic
    > specjalnie dziwnego.

    Wielozadaniowosc tez była różna w wielu systemach.
    Stad i "nakładki" na języki.

    > Tam, wszyscy programiści od volatile, wybiją sobie zęby o protokoły
    > synchronizacji cache, out-of-order execution itd itp.
    >
    > PS. Zaznaczam, że nic nie pisałeś o AVR w poprzednim poście, wiec w
    > ogólnym wypadku, volatile nie może i nie powinno być uzywane w celu
    > synchronizacji zmiannych w przerwaniach. W szczególnym, kiedy znasz
    > konkretną architekturę, być może.

    Przeciez to nie tylko C ma ten problem.
    Wiec jesli są rozwiązania dobre, to mozna je w i C zaimplementowac.
    Tylko ... schowac pod volatile, czy osobno.

    Bo problemow w zaawansowanych systemach istotnie coraz wiecej.

    J.


  • 35. Data: 2023-02-16 15:23:50
    Temat: Re: C++ ośla łączka
    Od: "Grzegorz Niemirowski" <g...@g...net>

    heby <h...@p...onet.pl> napisał(a):
    > Tam, wszyscy programiści od volatile, wybiją sobie zęby o protokoły
    > synchronizacji cache, out-of-order execution itd itp.

    Ale ja nic nie mówiłem o cache procesora ani kolejności operacji. Chodzi o
    problem jaki wprowadza kompilator optymalizując dostęp do zmiennej poprzez
    przeniesienie jej z RAM-u do rejestru w jakimś fragmencie kodu. Żadne
    bariery na to nie pomogą. Powszechnie problem ten rozwiązuje się stosując
    volatile.

    > Uwaga o volatile dotyczy *języka* C a nie implementacji tego na AVR.

    To nie musi być AVR. Wspomniałem o nim, bo on nawet nie ma operacji do
    barier jak np. ARM (DSB, DMB, ISB).

    > Sam fakt użycia "przerwania" jest z definicji nieistniejącym bytem w C

    Kogo to obchodzi? Jak na złość w prawie każdym procesorze są przerwania.

    > PS. Zaznaczam, że nic nie pisałeś o AVR w poprzednim poście, wiec w
    > ogólnym wypadku, volatile nie może i nie powinno być uzywane w celu
    > synchronizacji zmiannych w przerwaniach. W szczególnym, kiedy znasz
    > konkretną architekturę, być może.

    A dlaczego nie powinno i co polecasz w zamian? Nie podałeś żadnego argumentu
    przeciw volatile. Cały czas chodzi o programy bare metal, bez schedulera.
    volatile jest powszechnie stosowanym oraz polecanym rozwiązaniem problemu
    optymalizacji na MCU, o którym wspomniałem poprzednio, a doprecyzowałem na
    początku tego posta, żeby było jasne o co chodzi. I jakoś w Internecie nie
    widzę polemiki z tym polecaniem volatile, z wyjątkiem Twoim postów. Pomijam
    oczywiście przypadki używania volatile do innych problemów, do których się
    nie nadaje, jak atomowość.

    Więc mamy kod:

    int z = 0;

    int main() {
    while(!z);
    return 0;
    }

    isr_handler() {
    z = 1;
    }

    Przy kompilacji z -O0 nie ma problemu, przerwanie przerwie pętlę while. Przy
    wyższej optymalizacji pętla może czytać kopię zmiennej i przez to nie
    zauważyć jej modyfikacji. volatile łatwo i szybko usuwa ten problem. Mam
    nadzieję, że teraz już jest wszystko jasne i w końcu dowiem się jakie
    straszne efekty spowoduje tutaj wprowadzenie volatile oraz co jest lepszego.

    --
    Grzegorz Niemirowski
    https://www.grzegorz.net/


  • 36. Data: 2023-02-16 15:33:40
    Temat: Re: C++ ośla łączka
    Od: Piotr Gałka <p...@c...pl>

    W dniu 2023-02-16 o 13:54, heby pisze:
    >> Już opanował wywoływanie funkcji po jej skopiowaniu do RAMu.
    >
    > Czytaj wątek z przed paru dni:
    >
    > "MCU - start programu z RAM"

    Przesłałem bratu (on nie czyta Usenetu) wszystkie wiadomości z tamtego
    wątku.
    W czasie jak pisałem dalszą część tej wiadomości wstępnie powiedział, że
    według niego nie ma tam tego co on szuka. Ale rozmawialiśmy tylko
    zgrubnie (ja siedzę w swoim pokoju a on piętro niżej). Coś mówił o
    sekcjach, ale że to... coś tam (nie dosłyszałem).
    Też rzucę okiem, tylko, że tak właściwie nie mam na to czasu.

    > Było to omawiane w tym wątku. Ogólnie, jesli ma to związek z
    > programowaniem flasha, to boje się zapytać, czy jakoś się zabezpieczacie
    > prze utratą zasilania w trakcie.

    Chyba powinien się obrazić :)

    Napisałeś tak, jakby przeprogramowywanie flasha było jakąś nadzwyczajną
    czynnością, a to przecież chyba wszyscy robią.
    Są jeszcze jakieś urządzenia bez upgrade?
    Do tej pory używaliśmy AtXmega z EEROMem na pokładzie. O ile się
    zorientowaliśmy to w ARM (które chyba dużo ludzi używa) EEPROM to jakaś
    egzotyka. Stosowana jest emulacja EEPROM we flashu więc wszyscy, którzy
    chcą EEPROMu wewnątrz procka muszą programować Flasha.

    Od czasu jak tylko przenieśliśmy się z procesorów OTP na flash (jak
    pojawiły się pierwsze Atmele) jesteśmy moim zdaniem dobrze zabezpieczeni.

    Pierwsza linia obrony:
    Nasze urządzenia zasilane są z zasilaczy z podtrzymaniem bateryjnym
    (starczającym na kilka godzin). Dopóki nie ma tak długich przerw w
    zasilaniu to zanik napięcia zasilania urządzenia praktycznie nie zdarza
    się przez lata.

    Druga linia obrony:
    Jest czujnik napięcia na elektrolicie przed stabilizatorem VCC.
    Od przerwania z tego czujnika do choćby drgnięcia w dół napięcia VCC
    mija więcej czasu niż flash potrzebuje na dokończenie rozpoczętego
    procesu programowania, czy kasowania strony - czyli (pod warunkiem, że
    procesor po tym przerwaniu wyłączy wszelkie zbędne obciążenia) każda
    rozpoczęta operacja na flashu zostanie dokończona w komfortowych
    warunkach. Oczywiście po tym NMI następna operacja nie zostanie rozpoczęta.
    To zabezpieczenie występuje tylko w urządzeniach, które przechowują we
    flashu jakieś dane. Na przykład nie ma go w czytnikach RFID. Tam
    uważamy, że pozostałe zabezpieczenia wystarczą bo tam chodzi tylko o
    upgrade, a on się skutecznie broni sam.

    Trzecia linia obrony:
    Brown-out, który zadziała po tym wszystkim zabezpiecza przed zgłupieniem
    procesora, który mógłby wtedy coś nabruździć we flashu.

    Różne inne zabezpieczenia, którym trudno nadać kolejne numery:
    - ważne informacje we flashu mają sumy kontrolne. Po resecie procesor je
    sprawdza. Jak się nie zgadza to przyjmuje bezpieczne wartości default.
    - informacja o każdym resecie trafia do rejestracji i serwer może po
    resecie skontrolować całą zawartość urządzenia.
    - produkujemy urządzenia przez 'upgrade' z programu testowego to
    oznacza, że w każdym urządzeniu są praktycznie dwie kopie programu.
    - po resecie bootloader sprawdza crc32 programu i jak jest błędne to
    sprawdza crc32 upgrade'u i ewentualnie wykonuje upgrade.
    - przesyłanie upgrade'u nie niszczy programu (on nadal normalnie działa)
    więc przerwanie przesyłania upgrade'u w dowolnym momencie nie jest
    problemem,
    - dopiero jak przyjdą wszystkie strony upgrade'u jest sprawdzany jego
    podpis i upgrade jest wykonywany - zakładamy, że jakby upgrade został
    przerwany w tym trakcie to po resecie crc32 to wykryje i upgrade
    rozpocznie się od nowa (nie przesyłanie a wykonywanie).

    Dotychczas nie zauważyliśmy problemu, którego źródłem byłoby
    niedokończenie zapisu flasha.
    P.G.


  • 37. Data: 2023-02-16 15:37:23
    Temat: Re: C++ ośla łączka
    Od: "J.F" <j...@p...onet.pl>

    On Thu, 16 Feb 2023 13:20:42 +0100, Piotr Gałka wrote:
    > A teraz pytanie brata na które nie znamy odpowiedzi.
    >
    > Ogólnie to jest pierwsze podejście do procesorów ARM (nie wiem z którym
    > w tej chwili walczy (Silabs EFM32PG22..., EFM32PG23..., a może EFM32TG11..).
    > Zanim użyje procesor po raz pierwszy musi opanować podstawowe działania
    > no i jest właśnie na tym etapie.
    >
    > On by potrzebował sizeof(funkcja).

    I to ma zwrocic rozmiar kodu funkcji, czy rozmiar typu zwracanego
    przez funkcję?

    > Ale jak próbuje to zrobić to dostaje 1.
    > Zasugerowałem, że może jak wstawi etykietę (przypomnieliśmy sobie, że
    > chyba w C coś takiego jest) na nawiasie zamykającym funkcję to uda się
    > policzyć różnicę między jej adresem a adresem początku funkcji.
    > Właśnie mi krzyknął (jego pokój jest piętro niżej), że z zewnątrz
    > funkcji nie ma dostępu do tej etykiety.

    Nie liczylbym na to, ze to zadziała poprawnie.

    Ale jak chcecie miec klopoty ... dodajcie do funkcji kolejny argument,
    ktory przy wywolaniu zwroci róznice miedzy etykietami.
    Albo gdzies zapamieta, bo przeciez typ funkcji moze byc inny.

    > Napiszę do czego mu to potrzebne bo czasem może rozwiązanie głównego
    > problemu robi się inaczej niż on kombinuje.
    >
    > Wczoraj wieczorem wspólnie tłumaczyliśmy dwa akapity datasheet, czy
    > manuala (nie wiem - on mi po prostu podświetlił akapit na ekranie i
    > chodziło o to jak to rozumiemy).
    >
    > Tam było, że jak się coś robi z programowaniem flasha z wnętrza programu
    > to ogólnie nie ma gwarancji, że wszystko się uda. I to zdanie było
    > ogólne - czyli nawet jak ruszasz inną stronę niż jesteś to może coś nie
    > zadziałać. Nie napisali co dokładnie, ale skoro może coś się nie udać to
    > my tego nie chcemy. Napisali, żeby przekopiować odpowiednią funkcję do
    > RAMu, wywołać ją i z niej uruchomić proces kasowania, czy programowania
    > flasha.

    Kopiowanie pod inny adres wymaga relokowalnego kodu - czesto taki
    jest, ale warto by sie upewnic.

    > Już opanował wywoływanie funkcji po jej skopiowaniu do RAMu.
    > Z adresem początku sobie radzi, choć mówi, że wskaźnik na funkcję jest
    > zawsze większy o 1 od prawdziwego adresu i ustalając fragment do
    > kopiowania on musi tę jedynkę odejmować.

    Ciekawe, bardzo ciekawe.

    A niech wywola gdzies funkcje ze wskaznika, i zobaczy jak to sie
    skompiluje - tez bedzie cofnięcie o bajt?
    Chyba, ze przed punktem startowym funkcji jest cos waznego zapisane.

    > Wszystko już działa, tylko, że na razie rozmiar funkcji bierze z sufitu
    > na zapas.
    > No i jedyne co brakuje do odhaczenia kolejnej funkcjonalności to
    > ustalenie w jednej funkcji jaki jest sizeof drugiej funkcji.

    To chyba nie ma.

    Napisalbym to w assemblerze, zeby wiadomo bylo, ze nic sie nie sp*,
    lub postaral sie skorzystac z jakiejs dynamicznie ladowanej biblioteki
    lub pozostal przy zapasie :-)

    > Może wiesz (lub ktoś inny) jak to się robi.

    https://developer.arm.com/documentation/ka003803/lat
    est

    cos takiego?

    :-(

    J.


  • 38. Data: 2023-02-16 16:05:00
    Temat: Re: C++ ośla łączka
    Od: Piotr Gałka <p...@c...pl>

    W dniu 2023-02-16 o 15:37, J.F pisze:

    >> On by potrzebował sizeof(funkcja).
    >
    > I to ma zwrocic rozmiar kodu funkcji, czy rozmiar typu zwracanego
    > przez funkcję?

    Wiedziałem, że w tym miejscu jest niejasne i ze zaraz dalej się wyjaśni.

    >> Już opanował wywoływanie funkcji po jej skopiowaniu do RAMu.
    >> Z adresem początku sobie radzi, choć mówi, że wskaźnik na funkcję jest
    >> zawsze większy o 1 od prawdziwego adresu i ustalając fragment do
    >> kopiowania on musi tę jedynkę odejmować.
    >
    > Ciekawe, bardzo ciekawe.

    On dokładnie wie o co chodzi i próbował mi wyjaśnić ale nie do końca
    ogarnąłem. To nie jest kwestia błędu kompilatora tylko hardware'u i tak
    ma być. Na tyle na ile zrozumiałem to przy operacji wywołania funkcji
    (nie na poziomie C tylko na poziomie assemblera) wymagane jest
    ustawienie najmłodszego bitu adresu na 1. A że wszystkie funkcje
    umieszczane są pod adresami modulo (nie wiem, coś więcej niż 1) to
    ustawienie tego bitu na 1 daje adres o 1 większy.

    >> Może wiesz (lub ktoś inny) jak to się robi.
    >
    > https://developer.arm.com/documentation/ka003803/lat
    est
    >

    Dzięki.
    Wygląda na dokładnie jego pytanie.
    Na razie nie próbowałem zrozumieć odpowiedzi.
    Przesłałem mu. Zobaczymy. Na razie chwilowo go nie ma (chyba poszedł na
    obiad, co i ja zaraz zrobię).
    P.G.


  • 39. Data: 2023-02-16 17:56:15
    Temat: Re: C++ ośla łączka
    Od: heby <h...@p...onet.pl>

    On 16/02/2023 15:23, Grzegorz Niemirowski wrote:
    > Ale ja nic nie mówiłem o cache procesora ani kolejności operacji. Chodzi
    > o problem jaki wprowadza kompilator optymalizując dostęp do zmiennej
    > poprzez przeniesienie jej z RAM-u do rejestru w jakimś fragmencie kodu.
    > Żadne bariery na to nie pomogą.

    Istnieje wiele metod, które pozwalają dostać co chcesz bez udziału volatile.

    Mutexy, external function, sekcje krytyczne, atomiki, interlocked itd itp.

    > Powszechnie problem ten rozwiązuje się
    > stosując volatile.

    Nie. Powszechnie rozwiązuje się ten problem używając poprawnych wzorców
    projektowych dostępnych w języku i czasami na danej platformie
    kompilatora bądź hardware.

    Używanie volatile w tym celu pochodzi z czasów, kiedy nie było innych metod.

    Volatile jest np. bezsensowne, bo uniemożliwia optymalizacje w
    miejscach, gdzie jej nie chcesz i niestety również tam, gdzie chcesz.
    Albo wszystko albo nic.

    Na chwile obecną volatile uzyteczne jest tylko przy komunikacji z
    hardware *oraz* na wyjątkowo zapuszczonych architekturach, gdzie
    dokłądnie wiesz, co się stanie po jego użyciu.

    Przykładowo, na 8051 przy jednoczesnym dostępie do RAMu bajtowo i
    bitowo, biedy kompilator może źle wyoptymalizować kawałek kodu. Ale to
    akuratnie taka popieprzona architektura, do której C pasuje w sposób
    wymagający wbijania go młotkiem, trudo się więc dziwić, że wymaga
    również przedziwacznych konstrukcji prostujących ten C do czegoś
    użytecznego na guano 8051.

    >> Uwaga o volatile dotyczy *języka* C a nie implementacji tego na AVR.
    > To nie musi być AVR. Wspomniałem o nim, bo on nawet nie ma operacji do
    > barier jak np. ARM (DSB, DMB, ISB).

    Więc wyraźnie wyjaśniam, że jeśli chodzi o ogólne uzycie volatile, to
    jest ono bezsensowne do rzeczy innych niż pamięć rejetrowa urządzeń. Ale
    w szczególności, w programach do migania diodą na AVR, może być w jakimś
    stopniu emulacją brakującej funkcjonalności i tam stosując je rozważnie
    da się dostać namiastkę poprawnej synchronizacji.

    >> Sam fakt użycia "przerwania" jest z definicji nieistniejącym bytem w C
    > Kogo to obchodzi? Jak na złość w prawie każdym procesorze są przerwania.

    Które obsługiwane są przez skrajnie specyficzny kod, zazwyczaj niezgodny
    z ABI kompilatora, wymagajacy workaroudów typu pre/post i naked. To, że
    procedure przerwania można napisać w C nie oznacza, że to "normalne" C.
    To wyjątkowo wyjątkowe kodowanie, zazwyczaj na poziomie OSa, którego
    zwykłego kodera C nie dotyczy.

    User na górze, nawet jeśli wołany jest z wnętrza przerwania, nie widzi
    róznicy między nim a wątkiem. Katastrofy z volatile i weak memory
    ordering sa jak najbardziej możliwe, im wyżej w komplikacji procesora
    wylądujesz ze swoim kodem.

    >> PS. Zaznaczam, że nic nie pisałeś o AVR w poprzednim poście, wiec w
    >> ogólnym wypadku, volatile nie może i nie powinno być uzywane w celu
    >> synchronizacji zmiannych w przerwaniach. W szczególnym, kiedy znasz
    >> konkretną architekturę, być może.
    > A dlaczego nie powinno i co polecasz w zamian?

    Atomik? Mutex? Sekcja krytyczna? IPC?

    > Nie podałeś żadnego
    > argumentu przeciw volatile.

    Przecież zlinkowałem arykuł, w którym masz jasno wypisane powody i
    ostrzeżenie.

    Volatile działa inaczej, niż mysli 95% programistów C. I o ile w małych
    systemach z AVRkiem to akurat nie problem, co najwyżej przyczyna
    marudzenia "panie, jakie te kompialtory złe robio, nawet zopymalizować
    nie potrafio", to w dużych systemach prowadzi prosto do wybicia sobie
    zębów. A te "duże systemy" to obecnie coś, co dobija się z hukiem do
    drzwi embedowców. Czasy 8051, po raz kolejny, jak co roku od 40 lat,
    minęły. Za chwile powszechne będą RISC-V z kilkoma rdzeniami, w
    zależnosci od wymogów mocowych, ze złożonymi superskalarnymi potokami i
    pokręconym cache. Dalej będziesz w nich stosował volatile?

    > Cały czas chodzi o programy bare metal, bez
    > schedulera.

    Przerwania to multitasking, taki sam jak w schedulerze preemptive.

    > volatile jest powszechnie stosowanym oraz polecanym
    > rozwiązaniem problemu optymalizacji na MCU

    W pierdołowatych małych cpu zapewne tak. W dużych absolutnie nie. Pisząc
    relatywnie duże programy, o dużej złożoności, z masą wątków i wymianą
    danych między nimi, nie miałem okazji użyć volatile ani razu. Z
    ciekawostek: w poważnych firmach słowo volatile jest wyłapywane przez
    linter kodu i wymaga zgody komisji za zielonym suknem.

    > I jakoś w Internecie nie widzę polemiki z tym polecaniem
    > volatile

    Bo jej nie szukasz. Google aż krzyczy "nie uzywaj volatile, to nie
    działa jak myślisz".

    Choćby wiki:

    https://en.wikipedia.org/wiki/Volatile_(computer_pro
    gramming)

    [...]Furthermore, in C and C++ it does not work in most threading
    scenarios, and that use is discouraged.[...]"

    "[...]Operations on volatile variables are not atomic, nor do they
    establish a proper happens-before relationship for threading. This is
    specified in the relevant standards (C, C++, POSIX, WIN32),[1] and
    volatile variables are not threadsafe in the vast majority of current
    implementations. Thus, the usage of volatile keyword as a portable
    synchronization mechanism is discouraged by many C/C++ groups[...]".

    Niezliczona ilość postów/stron wyjasnia, dlaczego volatile nie jest tym,
    o czym myślisz, że do czego jest.

    Serio, nie zauważyłes?

    > Więc mamy kod:
    > int z = 0;
    > int main() {
    >    while(!z);
    >    return 0;
    > }
    > isr_handler() {
    >    z = 1;
    > }
    > Przy kompilacji z -O0 nie ma problemu, przerwanie przerwie pętlę while.
    > Przy wyższej optymalizacji pętla może czytać kopię zmiennej i przez to
    > nie zauważyć jej modyfikacji. volatile łatwo i szybko usuwa ten problem.

    W małym procesorze tak.

    Teraz weź duży procesor. Być może Ci zaskoczy, że jeśli to przerwanie to
    inny wątek na innym rdzeniu, to mimo, że rdzeń zapisze z = 1, to pętla
    nigdy się nie zakończy. Bo możesz mieć system ze słabą koherencją cache
    i bez bariery/fence informacja nigdy nie zostanie zsynchronizowana z
    lokalnymi cache obu rdzeni. Albo ciekawoski z przestawianiem zapisów,
    kiedy jeden rdzeń widzi zapis w innej kolejnosci niż wykonany w
    sąsiednim rdzeniu.

    Swoją drogą ten problem jest trudny do zauważenia przez przeciętnego
    wciskacza klawiszy, bo x86 jest wyjątkowo tolerancyjny dla dziadowskiego
    kodu. Tam to działa przypadkiem i wiele osób ma podejrzenie, że nie bez
    powodu takie decyzje projektowe podjęto: łatwiej było zaprojektować
    tolerancyjny procesor niż liczyć na poprawianie miliardów lini kodu po
    kiepskich programistach.

    > Mam nadzieję, że teraz już jest wszystko jasne i w końcu dowiem się
    > jakie straszne efekty spowoduje tutaj wprowadzenie volatile oraz co jest
    > lepszego.

    Powoduje: zablokowanie optymalizacji *całej* zmiennej, wszędzie oraz nie
    usuwa innych problemów z wątkowością, takich jak weak memory ordering
    czy synchronizacja cache.

    Ogólnie działa tylko na małych systemach, gdzie nie ma tego typu
    zagrożeń, co powoduje że volatile jest narzędziem workaroudującym
    prawidłowe metody, a nie metodą samą w sobie.

    Na większych sens jest zerowy, poza dostępem do rejestrów.

    Jak już musisz mieć niskopoziomowo to wyjasnione, to może zerknij tutaj:

    https://www.kernel.org/doc/html/latest/process/volat
    ile-considered-harmful.html


  • 40. Data: 2023-02-16 18:01:23
    Temat: Re: C++ ośla łączka
    Od: heby <h...@p...onet.pl>

    On 16/02/2023 15:33, Piotr Gałka wrote:
    > Napisałeś tak, jakby przeprogramowywanie flasha było jakąś nadzwyczajną
    > czynnością, a to przecież chyba wszyscy robią.

    Niezliczona ilośc błędów popełnianych przez programistów w takim kodzie
    każe mi dmuchać na zimne. Taki kod powinien podlegać weryfikacji
    formalnej a z drugiej strony "zbrickowanie" urządzeń to rzecz tak
    powszechna, że zastanawiam się kto w ogóle pisze te bootloadery,
    flashery itd itp. bo wyglądają jak prace zaliczeniowe kiepskich studentów.

    > Dotychczas nie zauważyliśmy problemu, którego źródłem byłoby
    > niedokończenie zapisu flasha.

    Zastanawia mnie wobec tego ta kombinacja z flashowaniem z RAM.

    Musicie skasować cały flash (wątpię)? Ma byćszybciej? Coś innego nie działa?

strony : 1 ... 3 . [ 4 ] . 5 ... 10


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: