Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

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

jp_elek 09 Gru 2016 12:09 3036 106
  • #1 09 Gru 2016 12:09
    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.

    0 29
  • #2 09 Gru 2016 12:37
    el2010tmp
    Poziom 25  

    Tylko dlaczego chcesz porównywać bit po bicie, zamiast wszystkie naraz ???

    0
  • #3 09 Gru 2016 12:51
    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

    0
  • Pomocny post
    #4 09 Gru 2016 12:55
    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.

    0
  • Pomocny post
    #5 09 Gru 2016 14:04
    michalko12
    Specjalista - Mikrokontrolery

    Jakieś możliwości są, ale czy o to Ci chodziło.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #6 09 Gru 2016 14:09
    Freddie Chopin
    Specjalista - Mikrokontrolery

    michalko12 napisał:
    if( x[i] == (bits & (1<<i)) ? 1 : 0)

    Wyjątkowo ryzykowny kod, biorąc pod uwagę wyższy priorytet operatora "==" niż operatora "?:".

    0
  • #7 09 Gru 2016 14:17
    2675900
    Użytkownik usunął konto  
  • #8 09 Gru 2016 14:22
    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 ;)

    0
  • #9 09 Gru 2016 14:36
    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).

    0
  • #10 09 Gru 2016 15:24
    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.

    0
  • #11 09 Gru 2016 17:53
    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.

    0
  • #12 09 Gru 2016 18:05
    2675900
    Użytkownik usunął konto  
  • #13 09 Gru 2016 20:21
    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
    Zaloguj się, aby zobaczyć kod




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


    J.P.

    0
  • #14 09 Gru 2016 21:25
    michalko12
    Specjalista - Mikrokontrolery

    Kod: c
    Zaloguj się, aby zobaczyć kod

    190 na -O1 i O2
    150 na -O3

    0
  • #15 09 Gru 2016 21:51
    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 (;

    0
  • #16 09 Gru 2016 21:52
    2675900
    Użytkownik usunął konto  
  • #17 09 Gru 2016 22:13
    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
    Zaloguj się, aby zobaczyć kod


    190 na -O2

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

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod

    0
  • #18 09 Gru 2016 22:19
    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.

    0
  • #19 09 Gru 2016 22:26
    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

    0
  • #20 09 Gru 2016 22:29
    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ł.

    0
  • #21 10 Gru 2016 09:51
    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.

    0
  • #22 10 Gru 2016 10:00
    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".

    0
  • #23 10 Gru 2016 10:10
    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 ?

    0
  • #24 10 Gru 2016 10:23
    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.

    0
  • #25 10 Gru 2016 10:33
    2675900
    Użytkownik usunął konto  
  • #26 10 Gru 2016 10:33
    tmf
    Moderator Mikrokontrolery Projektowanie

    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.

    0
  • #27 10 Gru 2016 10:40
    2675900
    Użytkownik usunął konto  
  • #28 10 Gru 2016 11:29
    kamyczek
    Poziom 34  

    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.

    0
  • #29 10 Gru 2016 11:35
    2675900
    Użytkownik usunął konto  
  • #30 10 Gru 2016 13:49
    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: avrasm
    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 !!

    0