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

XMega AVR - Jak zadeklarować indeksowaną zmienną bitową w C

jp_elek 09 Gru 2016 12:09 4188 106
  • #1 16114963
    jp_elek
    Poziom 9  
    Witam ,
    Pytanie brzmi , w jaki sposób zadeklarować zmienną bitową , powiedzmy w ośmiu kolejnych bitach uint8_t, aby dostęp do niej był możliwy przy pomocy indexu -(porównywalnie do zmiennej tablicowej[]) ?.

    ps. wymóg ten pojawia się , gdyż chciałbym maksymalnie zwarcie(szybko) w pętli for
    porównywać zarówno stan pola bitowego o tym samym indeksie , co stan zmiennej (powiedzmy uint8_t) o tym samym indeksie .
    ps2. chodzi tylko o formę zapisu jak w pytaniu, bo wiem iż zadanie mogę rozpisać na osiem kolejnych warunków.
  • #2 16115021
    el2010tmp
    Poziom 25  
    Tylko dlaczego chcesz porównywać bit po bicie, zamiast wszystkie naraz ???
  • #3 16115045
    jp_elek
    Poziom 9  
    Pytanie jest raczej ogólne , bo na końcu są instrukcje asemblera - nie znam instrukcji asemblera gdzie numer bitu mógłby być zmienną, sbrc i sbrs wymaga bezpośredniego podania numeru bitu przed kompilacją.

    A wracając do Twojego pytania - powodem jest jak zawsze lenistwo - chciałbym uniknąć rozpisywania czegoś co da się zapisać w pętli ->na osiem warunków z których każdy może zająć wiele linii
  • Pomocny post
    #4 16115055
    Freddie Chopin
    Specjalista - Mikrokontrolery
    W C jest to niemożliwe. W C++ nawet nie musiałbyś tego robić sam, bo mógłbyś użyć std::bitset<8>. Jeśli bitset zajmowałby zbyt wiele miejsca (możliwe ze względu na implementację, często opartą o tablicę typu "unsigned long"), to wystarczy stworzyć typ który będzie miał zdefiniowany "operator[]".

    A tak serio, to pisząc sobie małą funkcję inline "bool getBit(uint8_t bitset, uint8_t bit)" osiągniesz identyczny efekt tylko przy innym zapisie.
  • Pomocny post
    #5 16115190
    michalko12
    Specjalista - Mikrokontrolery
    Jakieś możliwości są, ale czy o to Ci chodziło.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #7 16115208
    Konto nie istnieje
    Konto nie istnieje  
  • #8 16115221
    michalko12
    Specjalista - Mikrokontrolery
    Freddie Chopin napisał:
    Wyjątkowo ryzykowny kod, biorąc pod uwagę wyższy priorytet operatora "==" niż operatora "?:".

    No można się złapać, ale ten nie robi błędów kto nic nie robi ;)
  • #9 16115251
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Piotrus_999 napisał:
    Wracamy do tematu nawiasów : lepiej jedna para za dużo niź za mało

    E tam - w razie gdy coś nie jest oczywiste zaglądamy tu -> http://en.cppreference.com/w/c/language/operator_precedence i już jest oczywiste (;

    michalko12 napisał:
    No można się złapać, ale ten nie robi błędów kto nic nie robi

    Ano, zgadza się. Sprawdziłem nawet i ten poprzedni kod niestety nie daje warninga, trochę szkoda, czasem GCC jest tak miły żeby wyłapywać niektóre dziwne przypadki (szczególnie przy operatorach binarnych).
  • #10 16115333
    jp_elek
    Poziom 9  
    Panowie ,
    Dzięki za fachową pomoc , działa.

    ps. Nawet wygenerowany kod daje się "przełknąć" - opinia "asemblerowca"..

    zamiarem jest stworzenie 8-miu timerów programowych z możliwością zadawania czasów , startowania w dowolnej chwili z dowolnego miejsca , z ogólnie dostępnym statusem - "już naliczyłem" ON/OFF.

    dawno, temu miałem takich 16 z dodatkową konfiguracją jako generator wolnych przebiegów i zajmowało to rząd 800 cykli ( wobec tego prostaka 8 timerów z licznikami 8 bitowymi około 500 cykli) ale powoli staram się zapominać o tym że coś w "C" może być szybkie i krótkie :cry:

    Jeszcze raz wielkie dzięki J.P.
  • #11 16115585
    michalko12
    Specjalista - Mikrokontrolery
    jp_elek napisał:
    ale powoli staram się zapominać o tym że coś w "C" może być szybkie i krótkie :cry:
    To zapomnij o tym zapominaniu. To nie jest kwestia C, tylko zestawu instrukcji w danym mikroprocesorze. AVR niestety ma spore ograniczenia w niektórych przypadkach.
  • #12 16115606
    Konto nie istnieje
    Konto nie istnieje  
  • #13 16115685
    jp_elek
    Poziom 9  
    @Piotrus_999
    Dzięki za propozycję , ostatnie kilka godzin to klient korzystał z Hi_Priority Interrupt,
    wstawię kod jak nieco posilę się i "zbuduję" kompletny timer.
    J.P.

    Dodano po 1 [godziny] 31 [minuty]:

    Oto co mi wyszło , niestety prawie 600 cykli gdy wszystkie osiem timerów należy obsłużyć , jeśli tylko sprawdzić - niczego nie ustawiając to prawie 200 - okropność :cry:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod




    Lub całość gotowa do symulatora
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    J.P.
  • #14 16116052
    michalko12
    Specjalista - Mikrokontrolery
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    190 na -O1 i O2
    150 na -O3
  • #15 16116136
    Freddie Chopin
    Specjalista - Mikrokontrolery
    jp_elek napisał:
    Oto co mi wyszło , niestety prawie 600 cykli gdy wszystkie osiem timerów należy obsłużyć , jeśli tylko sprawdzić - niczego nie ustawiając to prawie 200 - okropność

    Napisz w assemblerze - za tydzień albo dwa (jak już może będzie poprawnie działać dla bardziej typowych przypadków) zmierzysz że ma 595 cykli.

    michalko12 napisał:
    190 na -O1
    150 na -O3

    Pewnie jakby zastosować powiększany wskaźnik zamiast indeksowania, to by jeszcze można coś uszczknąć. dekrementację i warunek można dać jako jedno (zmienić na pre-dekrementację). Być może dałoby się też zaoszczędzić używając lokalnych zmiennych do S_Bits i zapisywać je do RAM dopiero na koniec.

    Doskonały temat! Assemblerowi hakerzy pewnie tygodniami układaliby instrukcje żeby zaoszczędzić 5% czasu, a tu wystarczy trochę algorytm poprawić i już jest 3x lepiej (;
  • #16 16116139
    Konto nie istnieje
    Konto nie istnieje  
  • #17 16116175
    michalko12
    Specjalista - Mikrokontrolery
    Freddie Chopin napisał:
    Pewnie jakby zastosować powiększany wskaźnik zamiast indeksowania, to by jeszcze można coś uszczknąć. dekrementację i warunek można dać jako jedno (zmienić na pre-dekrementację). Być może dałoby się też zaoszczędzić używając lokalnych zmiennych do S_Bits i zapisywać je do RAM dopiero na koniec.


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


    190 na -O2

    Z tym że do zmiennych ST_ON i ST_Run dodany kwalifikator volatile.

    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod
  • #18 16116199
    Freddie Chopin
    Specjalista - Mikrokontrolery
    michalko12 napisał:
    190 na -O2

    Czyli już pewnie granica "fizyczna" skoro nic się specjalnie nie zmieniło. Tak czy siak - ~23 cykle na jeden obieg to całkiem nieźle przecież (; Czekam na wersję w assemblerze której prędkość sprawi że nam buty z nóg pospadają (;

    Zresztą - jak jest za wolno, to wystarczy pętlę rozwinąć, myślę że wtedy można zaoszczędzić sporo, a 8x ten sam kod (skrócony o rzeczy związane z pętlą) i tak nie zajmie zbyt dużo.
  • #19 16116209
    michalko12
    Specjalista - Mikrokontrolery
    Freddie Chopin napisał:
    Zresztą - jak jest za wolno, to wystarczy pętlę rozwinąć, myślę że wtedy można zaoszczędzić sporo, a 8x ten sam kod (skrócony o rzeczy związane z pętlą) i tak nie zajmie zbyt dużo.

    -O3 tak robi. Wynik 140/190

    Dodano po 2 [minuty]:

    Freddie Chopin napisał:
    Czekam na wersję w assemblerze której prędkość sprawi że nam buty z nóg pospadają (;

    Tu musiałby się wypowiedzieć specjalista @kamyczek
  • #20 16116220
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Takie 8 programowych timerów to jak znalazł do czajnika. A przy wzroście prędkości wynikającym ze zbawiennego użycia assemblera to nawet wodę szybciej zagotuje i możesz jeszcze sam kawę zaleje w czasie który mu pozostał.
  • #21 16116627
    jp_elek
    Poziom 9  
    Witam ,
    Wielkie dzięki za gruntowną analizę tematu ,
    @michalko12 <== chylę głowę przed rzeczowym podejściem do mojego pytania ,
    .. przy okazji , czy jest możliwość( jeśli tak, to w jaki sposób ?) oddzielnego dla wskazanego pliku/modułu stopnia optymalizacji ? Ox,innego niż dla pozostałych części kodu ?

    ps. kod asemblerowy gdzieś powinienem mieć ( próbuję "wykopać" z czeluści z CD-romami )problem w tym iż na pewno nie będzie ścisłym odpowiednikiem ..
    Dziękuję wszystkim J.P.
  • #22 16116638
    Freddie Chopin
    Specjalista - Mikrokontrolery
    jp_elek napisał:
    czy jest możliwość( jeśli tak, to w jaki sposób ?) oddzielnego dla wskazanego pliku/modułu stopnia optymalizacji ? Ox,innego niż dla pozostałych części kodu ?

    Jeśli Twój program nie działa z włączoną optymalizacją to znaczy że jest błędny. Rozwiązaniem jest naprawienie go, a nie wyłączanie optymalizacji. Przykładowo w kodzie tych timerów powyżej brakuje co najmniej kilku "volatile".
  • #23 16116644
    jp_elek
    Poziom 9  
    ps. "programowaniem" zajmuję się dorywczo, gdy potrzebuję coś - tak najczęściej prostego i w miarę sprawnego dorobić. Nie mam więc sprawności w tym zakresie jak wypowiadający się koledzy ..

    Dodano po 6 [minuty]:

    @ Freddie Chopin,
    o volatile nie zapomniałem , celowo stworzyłem najprostszy -osobny projekt :D
    aby ćwiczyć tylko same timery , mogę włączyć dowolny stopień optymalizacji , pytanie było "na wyrost" , z myślą iż gdy dołączę gdzieś plik z timerami i innymi "usługami" będzie możliwość aby ten właśnie plik był kompilowany z innymi ustawieniami optymalizacji niż pozostałe pliki ?
  • #24 16116670
    michalko12
    Specjalista - Mikrokontrolery
    We właściwościach plików( mowa o AtmelStudio7) jest opcja Custom Compilation Settings, ale nie korzystałem z niej nigdy.
    Zawsze możesz stworzyć sobie bibliotekę (np. softtimers.a) skompilowaną z własnymi opcjami i dołączyć ją potem do właściwego programu.
  • #25 16116683
    Konto nie istnieje
    Konto nie istnieje  
  • #26 16116685
    tmf
    VIP Zasłużony dla elektroda
    W gcc są też atrybuty - jednym z nich jest określenie optymalizacji dla funkcji. Więc można ją zmieniać nawet na poziomie funkcji, a nie nie tylko pliku. Swoją drogą po co? Jedyny sens to lokalne rozwijanie pętli, ale to też można załatwić atrybutami.
  • #27 16116695
    Konto nie istnieje
    Konto nie istnieje  
  • #28 16116767
    kamyczek
    Poziom 38  
    Freddie Chopin napisał:
    Takie 8 programowych timerów to jak znalazł do czajnika. A przy wzroście prędkości wynikającym ze zbawiennego użycia assemblera to nawet wodę szybciej zagotuje i możesz jeszcze sam kawę zaleje w czasie który mu pozostał.



    Fredek może napiszesz jak to zrobić w C uwagi na temat asemblera są raczej wizytówką tego jak "optymalnie" wygląda kod w C jak go przetłumaczysz na asemblera . Autor ma problem z C , a ja chętnie zobaczę jak sobie z tym radzi C i przede wszystkim jak to "błyskotliwie i optymalnie "wygląda po przetłumaczeniu na asembler.
  • #29 16116777
    Konto nie istnieje
    Konto nie istnieje  
  • #30 16116982
    jp_elek
    Poziom 9  
    Witam , mam nadzieję iż nie zanudziłem bez reszty..

    W zestawieniu z moimi "dokonaniami asm." kolega michalko12, jest najbliższy temu co ja kiedyś robiłem .

    Oto wersja asm z przełącznikiem kompilacji aby kompilować jako samodzielny plik - kto chce ->ten może :D
    ( ta wersja to 16-timerów, 16-nasto bitowych, każdy cztery tryby konfiguracji, oczywiście nie przystaje do tematu wątku wprost)
    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod


    A to wersja pełna całego projektu gdzie moje "to to" pracuje ( na ATMega88) potrzebując około 80% Flash, robi parę innych rzeczy "przy okazji" ...


    Tak ogólnie , oczywista przewaga "C" <=> po latach z pewnością łatwiej wrócić,
    natomiast przewaga "asm" polega na tym iż robisz tylko to co chcesz i tylko tak jak chcesz , oczywiście nakład czasu trudno porównywać ...

    Dzięki , szczególnie "C-poetom"- niestety "taki sobie asemblerowiec", nie całą Waszą "poezję-C" , do końca zrozumiał.
    Uwaga pliki dla AVR_Studio 4.xx !!
REKLAMA