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

Jak zadeklarować zmienne na portach GPIORx w AVR XMEGA/ATMega?

jp_elek 13 Sty 2014 14:52 2412 7
  • #1 13172509
    jp_elek
    Poziom 9  
    Witam ,
    Kolejny problem C-beginners,
    Usiłuję rozsupłać dostęp do rejestrów GPIORx procesorów AVR,
    ponieważ nic zadowalającego nie wymyśliłem , pozwolę sobie tylko nazwać problem.

    Potrzebuję umieścić zmienne na portach GPIORx , aby móc wymusić / usilnie domagać się, od kompilatora wykorzystania znanych instrukcji szybkiego dostępu bitowego do rejestrów o adresach poniżej 0x20.

    O ile korzystając ze sposobu podanego w ks. Pana T.Francuza ,w ramach jednego pliku, wszystko działa , o tyle nie znalazłem sposobu zadeklarowania
    takiej zmiennej jako extern .. , a jak wiadomo , dwie definicje - ani potrzebne , ani do przełknięcia dla kompilatora..( mówią nawet, że grzech ciężki)

    Prośba:
    1. jeśli ktoś ma tyle życzliwości by pomóc , proszę o przykładowe deklaracje , dające się wielokrotnie użyć w różnych plikach
    2. Czy zadeklarowaną strukturę według drugiej wersji da się umieścić na GPIORx,
    jak wtedy deklarować / definiować ?

    Bliższe sprecyzowanie pytania :
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Dodano po 56 [minuty]:

    ps. druga wersja da się też w analogiczny sposób do pierwszej "zainstalować" na GPIORx , jednak czy będzie tak samo interpretowana, gdyż jedna struktura, to rzeczywiste pola bitowe , a druga to pole zmiennej 8-mio bitowej, fizycznie to to samo , czy jednak dla kompilatora też to samo?
  • #2 13179128
    jp_elek
    Poziom 9  
    Cóż ... sądząc po liczbie odwiedzin - są użytkownicy jakoś zainteresowani ,
    jako że brak odpowiedzi jak umiem odpowiadam sobie? -sam
    Po pierwsze , z powodu braku mojej staranności , przepraszam autora , pierwszej książki
    za błąd w imieniu , powinno być oczywiście .. Tm. Francuza ,( niezamierzony , jednak popełniony .

    Do rzeczy : znalazłem złe rozwiązanie, choć działające...

    1. Tworzymy plik np. GPIOR.h a w nim umieszczamy definicję typów struktur,
    same zmienne-tak naprawdę wskaźniki do tych zmiennych na GPIOR tylko deklarujemy jako extern : Jak zadeklarować zmienne na portach GPIORx w AVR XMEGA/ATMega?

    2. Tworzymy plik np. GPIOR.c
    W tm pliku definiujemy już i inicjujemy wskaźnik do zmiennej w GPIOR,
    dodatkowo umieszczamy prościutkie funkcje testujące skutki takiego podziału
    deklaracja/definicja. :
    Jak zadeklarować zmienne na portach GPIORx w AVR XMEGA/ATMega?
    3 w pliku main. dołączamy plik GPIOR.h ,deklarujemy extern ( opcjonalnie ,ale chyba tylko w AS6) , i próbujemy dostępu do naszych rejestrów GPIOR x
    Jak zadeklarować zmienne na portach GPIORx w AVR XMEGA/ATMega?

    No i kompilujemy , doznając przykrego rozczarowania ,
    a. Operacje na porcie GPIOR wykonywane bezpośrednio w pliku main.c, są wykonywane jak zwykłe operacje na zmiennych gdzieś w zwykłym obszarze pamięci powyżej 0x1F , ..zonk, którego chciałem uniknąc
    Jak zadeklarować zmienne na portach GPIORx w AVR XMEGA/ATMega?
    b. Operaje na porcie GPIORx, niezależnie od tego jaką strukturą się posłużyliśmy , wykonywane są poprawnie jeśli funkcję umieszczono w tym samym pliku gdzie definiowano i inicjowano wskaźnik[b]
    Jak zadeklarować zmienne na portach GPIORx w AVR XMEGA/ATMega?

    Zatem jeśli jeszcze temat nie stał się zanadto męczący;
    1.Jak wymusić [b]zaprzyjaźnienie się
    kompilatora z pełną definicją wskaźnika , mimo extern ?( pomijam na razie grubiańskie użycie tych wskaźników jako globalne )
    2.Czy zauważona różnica będzie systematyczna , czy też "jak uzna za wygodne kompilator" ?

    ps. jeśli temat zbyt długi , czy też zdaniem moderatora nie zasługujący na kontynuację , oczywiście można zamknąć/usunąć .
    J.P.
  • #3 13179230
    tmf
    VIP Zasłużony dla elektroda
    Jaka wersja kompilatora?
    Problem jest chyba nierozwiązywalny - kompilator widząc deklarację, która jest w pliku nagłówkowym nie wie na co będzie wskazywał wskaźnik. Nie może więc wygenerować zoptymalizowanych instrukcji, bo kod musi być uniwersalny. Ten kod mógłby zoptymalizować linker, gdyby wiedział jak, niestety niesądzę aby LTO na AVR jakoś dramatycznie się rozwijało.
    Także jedyna możliwość to IMHO umieszczenie deklaracji z definicją w jednym pliku, w efekcie nietraktowanie tego jako zmiennej globalnej, ew. posłużenie się makrem.
    Dodatkowe pytanie - dlaczego tak ci zależy, aby to była jedna instrukcja?
  • #4 13179416
    jp_elek
    Poziom 9  
    Witam , dzięki za odpowiedź .. i to od samego MISTRZA.

    odnośnie kompilatora (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.2.939\avr8-gnu-toolchain\bin\avr-gcc.exe" .

    Dla porządku - jestem startującym do C , zatem wiele pytań , dla wielu pewnie w kategorii " oczywista oczywistość".

    Dotąd pisałem w asm. próbując przesiąść się na C , zaczynam po prostu "przenosić" swoje xx.asm na C , zaczynam od tego czego najbardziej nie lubię , a nieuniknione, obsługa użytkownika == przyciski klawiatury , z powodu iż XMega ma tak wiele GPIOR , aż grzech nie wykorzystać , jako flagi po pełnym przetworzeniu przycisków, długich , krótkich , repetycji itp. naciśnięć klawiszy w przerwaniach.
    Aby był pożytek z takowych , musi być do nich dostęp z co najmniej kilku plików , stąd usiłowanie uzyskania takiego dostępu właśnie szybkiego - bitowego.
    Zresztą jeśli chcieć używać jako flagi to niezależnie od przeznaczenia i tak dostęp i obsługa bitowa będzie szybsza .
    Reasumując - tak raz na dłużej _ usiłuję wyrobić sobie w miarę pełen pogląd na co mogę liczyć w C.
    Pozdrawiam J.P.
  • Pomocny post
    #5 13181138
    tmf
    VIP Zasłużony dla elektroda
    Jeśli mogę coś doradzić, to na początek nie staraj się porównywać asm do C, porównując krótkie fragmenty kodu możesz poczuć się sfrustrowany. Zacznij pisać w C, a optymalizacje zostaw na później, wtedy kiedy będą naprawdę potrzebne. Jak rozwiązać problem przy pomocy makr możesz podglądnąć w Atmel Studio klikając prawym przyciskiem myszy na GPIOR i patrząc na sposób jego zdefiniowania w plikach nagłówkowych. Jeśli z jakiegoś powodu makra nie będą ok, zawsze możesz zdefiniować swoje funkcje z ciałami napisanymi w asemblerze, wykorzystujące operacje spi/cbi. Przykłady, co prawda dotyczące LAS/LAT/LAC masz w mojej książce - możesz się na nich wzorować.
    BTW, jeśli chodzi o C/C++ to jest tu wielu mistrzów, a nawet wirtuozów tego języka, np. BlueDraco, albertb, Marek_Skalski i zapewne wiele więcej osób, których nie wymieniłem.
  • #6 13181310
    jp_elek
    Poziom 9  
    .. nie żeby usiłować wejść na szczyty, bez rzetelnego przygotowania, ale głównie z powodu aby uczyć się na czymś co i tak dla własnych projektów zrobić muszę, choćby jako minimum - te nieszczęsne klawisze, wyświetlacz z uc1608 itp.- ( na razie prolog+epilog obsługi , jest +- tak samo długi jak sama obsługa 4-ro pozimowa klawisza) , przyznasz iż trudno się tym cieszyć . Na czymś prostym i tak muszę ćwiczyć , więc niech to co najbardziej jałowe a nieuniknione , mam za sobą. Wierzę iż na takich prostych rzeczach łatwiej załapać " filozofię C "

    ps. używając macr , kompilator dostaje zawsze pełną dawkę informacji , i niezależnie od pliku wstawia zoptymalizowany kod, zatem przepisuję na kolejną wersję , mam nadzieję iż puryści języka C wybaczą mi jako początkującemu :?:
  • #7 13222352
    percol
    Poziom 12  
    A nie wygodniej w każdym z plików stworzyć zmienną lokalną (nawet o tej samej nazwie) odniesioną do tego samego GPIOR?
    I linker nie będzie miał wątpliwości i wykorzystasz efektywnie pola bitowe, wszak modyfikował będziesz konkretny bit danego GPIORx a w innym miejscu testujesz jego stan i wszystko gra...

    Jakieś uwagi? ;-)
  • #8 13295892
    jp_elek
    Poziom 9  
    Przepraszam , zaniedbałem się z odpowiedzią ,

    Tak , widzę taką możliwość , jednak potrzeba "pilnowania zgodności " we wszystkich plikach, z czasem może być nie lada wyzwaniem .

    Pozostaję ( póki co ) przy makrach .

    Temat zamykam , dziękuję za pomoc .
    J.P.
REKLAMA