Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 30 mar 2026, o 20:58


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 11 ] 
Autor Wiadomość
 Tytuł: [xmega] _bm _gc
PostNapisane: 16 paź 2014, o 09:15 
Offline
Użytkownik

Dołączył(a): 30 sie 2014
Posty: 170
Pomógł: 2

Witam, spotkałem się z dwoma zapisami zarówno "po staremu" jak i "po nowemu" ze znakiem "|=" i bez. Niestety w komentarzach nie znalazłem odpowiedzi na proste pytanie. Szukałem też w nocie atmela starting with C code for xmega.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


jeśli chodzi o _gc to jestem pewny na 99,99% że nie zmienia innych bitów w rejestrze, bo można zazwyczaj w danym rejestrze ustawić kilka _gc co spowodowało by bałagan, a w dodatku nigdzie nie znalazłem przykładu w którym byłby kod peryfer.rejestr |= per_opis_gc; wszędzie było: peryf.rejestr= per_opis_gc;



PORTA.OUT = PIN5_bm
Składnia: [ Pobierz ] [ Ukryj ]
język asm
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


PORTA.OUT |= PIN5_bm
Składnia: [ Pobierz ] [ Ukryj ]
język asm
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Więc coś się jednak dzieje więcej - musze tylko jeszcze rozszyfrować co :D

ori : Logical OR Register and Constant
ldi : Load Immediate
sts : Store Direct to SRAM



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 paź 2014, o 11:39 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 03 mar 2014
Posty: 580
Lokalizacja: Jastrzębie-Zdrój
Pomógł: 71

Witam,

Kolega (choć mógłbym pisać bracie xD - ze względu na nick), stosuj raczej zapis:
"|=" - zawsze masz pewność, że nie zmieniasz innych bitów w danym rejestrze, jeżeli takowe się znajdują.

"=" - zawsze przypisuje operację na sztywno czyli dla mikroklocka to może być wpisane do danego rejestru np. 0b00000100. Czyli jeden ustawisz na 1, resztę skasujesz.

Ja proponuję zawsze stosować zapisy "|=" i "&=" bo może się zdarzyć, że gdzieś będziesz konfigurował rejestry np. TCCRx w dwóch linijkach i z automatu dasz tylko "=" i znów problem będzie do rozwiązania, a czasem patrzysz i nie widzisz, że zapomniałeś "głupiego" znaczka "|" - wiem z własnego doświadczenia ;)

z Niebieskim pozdRowieniem,
Doman89


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 paź 2014, o 13:48 
Offline
Użytkownik

Dołączył(a): 20 wrz 2013
Posty: 647
Zbananowany użytkownik

Pomógł: 101

doman napisał(a):
jeśli chodzi o _gc to jestem pewny na 99,99% że nie zmienia innych bitów w rejestrze

A ja nie jestem tego taki pewien. W dokumencie o którym wspomniałeś pokazują taką konfigurację USARTa:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

co mniej więcej odpowiada temu:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

jako alternatywę podają konfigurację wszystkich przerwań USARTa razem za jednym zamachem:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Mi się zdaje że zasada wciąż pozostaje ta sama: chcesz ustawić/skasować jakaś pozycję bitową bez tykania pozostałych bitów, stosujesz sumę/iloczyn bitowy.


Autor postu otrzymał pochwałę

_________________
+++++[>++++<-]>[>++++++<-]>.---------.+++.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 paź 2014, o 15:18 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 07 kwi 2013
Posty: 418
Lokalizacja: Rzeszów
Pomógł: 102

W xmega są rejestry o dostępie atomowym w przypadku wykonywania na porcie sumy (|), iloczynu (&) lub alternatywy wykluczającej (^).
Odpowiednio dla zapisu: PORTA.OUT |= PIN0_bm; jest to: PORTA.OUTSET = PIN0_bm;
Oczywiście nie powodują one uzyskania identycznego kodu wynikowego, a jedynie ich działanie jest identyczne. Zalecane jest używanie OUTSET, OUTCLR i OUTTGL.

W przypadku innych rejestrów nie ma już tak różowo i trzeba stosować "stare" zapisy. Suffix "_gc" zmienia konfigurację rejestru zamazując tym samym jego poprzednią wartość. Dla zbiorczych konfiguracji może okazać się, że faktycznie nie zmieniane są pewne bity. Dzieje się tak dlatego, że inny zapis z "_gc" może zmieniać tylko niektóre z bitów, ale nie wszystkie...


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 paź 2014, o 16:58 
Offline
Użytkownik

Dołączył(a): 30 sie 2014
Posty: 170
Pomógł: 2

Dzięki za podpowiedź doman89 8-)

Cytuj:
Zalecane jest używanie OUTSET, OUTCLR i OUTTGL.


Kto tak zaleca, atmel? Wiem że takie rejestry są, "wiem co robią", (może nie do końca wiem jak to robią) ale nie wiedziałem że jest to zalecana metoda! :idea: W przykładach Francuza nie zauważyłem żeby stosował OUTSET itd.

PORTA.OUTSET = PIN5_bm; ...... ........ ....... atomowy?
Składnia: [ Pobierz ] [ Ukryj ]
język asm
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Mimo wszystko dalej nie wiem na 100% jak pisać kod żeby wykonywał się najszybciej :D

Poczytam jeszcze raz noty, książki i wrócę do tematu.

// wszystkie przykłady asm są z <main> i pisane dla xmega32e5 bez optymalizacji



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 paź 2014, o 20:38 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 07 kwi 2013
Posty: 418
Lokalizacja: Rzeszów
Pomógł: 102

Oczywiście że nie przez Atmel, ale czyż nie po to są te nowe rejestry aby ich używać...?
Znacznie upraszcza to wynikowy kod i pomaga ustrzec się wielu problemów. Jak najbardziej można również używać poprzednich zapisów, jednak w większości przypadków zdecydowaną większość można zastąpić ich nowym odpowiednikiem.
Wiadomo, wszystko zależy od konkretnego zastosowania, a to zalecenie było atmel'a, a nie firmy Atmel ;)

W obu książkach Pana Tomasza Francuz, które posiadam ("AVR. Praktyczne projekty" oraz "AVR. Układy peryferyjne") jest wielokrotne odwołanie do tych metod. Potwierdzeniem moich słów wraz z atomowością dostępu jest podrozdział "Atomowa modyfikacja stanu pinów i wsparcie dla RMW" rozdziału 7 ("Lepiej i prościej, czyli porty IO procesora na sterydach"). Konkretnie strony 196-199 książki "AVR. Praktyczne projekty".

Dodatkowo odrębną kwestią są nieidentyczne zapisy typu: PORTA.OUTSET i PORTA_OUTSET (dla pojedynczych odwołań optymalizator sobie i tak to uprości, różnice są w przypadku wielokrotnych odwołań), ale polecam bardziej zagłębić się w ten rozdział, skoro Kolega powołuje się na książki.

Przedstawiony fragment kodu asm jasno pokazuje atomowość dostępu, nie rozumiem gdzie tu Kolega widzi niejasność.
Oczywiście dwie instrukcje assemblera nie wykluczają dostępu atomowego (rejestr R24, jest rejestrem specjalnym przy wywoływaniu funkcji i jest on odtwarzany po każdym jej powrocie).


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 17 paź 2014, o 09:30 
Offline
Użytkownik

Dołączył(a): 30 sie 2014
Posty: 170
Pomógł: 2

atmel napisał(a):
Dodatkowo odrębną kwestią są nieidentyczne zapisy typu: PORTA.OUTSET i PORTA_OUTSET (dla pojedynczych odwołań optymalizator sobie i tak to uprości, różnice są w przypadku wielokrotnych odwołań), ale polecam bardziej zagłębić się w ten rozdział, skoro Kolega powołuje się na książki.

Zagłębię się bardziej :) bo nawet nie zwróciłem uwagi na zapis peryferium.rejestr i peryferium_rejestr, ale na razie od francuza mam tylko praktyczne projekty".

atmel napisał(a):
Przedstawiony fragment kodu asm jasno pokazuje atomowość dostępu, nie rozumiem gdzie tu Kolega widzi niejasność.


A no tu: :) .OUT jest taki sam jak .OUTSET ?

PORTA.OUT = PIN5_bm
Składnia: [ Pobierz ] [ Ukryj ]
język asm
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

PORTA.OUTSET = PIN5_bm; ...... ........ ....... atomowy?
Składnia: [ Pobierz ] [ Ukryj ]
język asm
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Kompletnie nie znam assemblera, jeszcze bardziej nawet niż C :lol: ale się doedukowuję ciągle więc wybaczcie niewiedze :geek: Wydawało mi się że atomowy dostęp dotyczy tylko jednej instrukcji sbi/cbi zamiast ldi -> out (wartość bezpośrednia do rejestru zamiast załadowanie do zmiennej i wysłanie zmiennej "out" do rejestru)?

co robi taki zapis? ldi r24, 0x20 -> ładuje wartość 0x20 do r24 ?
sts 0x605, r24 -> ładuje do sramu wartość rejestru r24 ?

:oops:



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 17 paź 2014, o 15:10 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 07 kwi 2013
Posty: 418
Lokalizacja: Rzeszów
Pomógł: 102

Przy zapisie PORTA.OUTSET, PORTA jest strukturą, a OUTSET polem tej struktury. Występuje tutaj standardowe działanie operatora selekcji lub jak ktoś woli kropki, a więc dostęp do składowej struktury jest możliwy jedynie po pośrednim jej zaadresowaniu w asm. W związku z tym, aby uzyskać jeszcze efektywniejszy kod należy prócz najlepszego ustawienia optymalizacji zwrócić jeszcze uwagę na zapis PORTA_OUTSET, który to jest bezpośrednim aliasem na rejestr OUTSET portu A. Kwestia tutaj jest bardzo subtelna, ponieważ przy największym poziomie optymalizacji, pojedyncze odwołania do rejestrów poprzez pola struktury zachowują się tak samo jak bezpośredni dostęp do rejestrów. Jednak warto wiedzieć w czym rzecz.

Zauważ że działanie OUT i OUTSET nie jest tożsame, a mianowicie instrukcja "sts" dokonuje zapisu do dwóch zupełnie innych rejestrów (0x0604 i 0x0605), a ich działanie jest odmienne.
W przywoływanej książce było omówienie kwestii działania kompilatora (teraz już nie pamiętam który to rozdział) i jego bezwzględnej "ostrożności" wobec rejestrów takich jak m.in. R24, który jest traktowany specjalnie, ponieważ służy przekazywaniu argumentów do funkcji. W tym miejscu należałoby zagłębić się bardziej w kwestie działania samego kompilatora, a nie chcę tego robić, ponieważ jeśli się nie mylę zostało to zrobione w książce "AVR. Praktyczne projekty".

doman napisał(a):
co robi taki zapis? ldi r24, 0x20 -> ładuje wartość 0x20 do r24 ?
sts 0x605, r24 -> ładuje do sramu wartość rejestru r24 ?

Zgadza się. Przy czym to miejsce w pamięci SRAM jest jednym z rejestrów IO procesora.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 18 paź 2014, o 06:58 
Offline
Użytkownik

Dołączył(a): 30 sie 2014
Posty: 170
Pomógł: 2

atmel napisał(a):
Przy zapisie PORTA.OUTSET, PORTA jest strukturą, a OUTSET polem tej struktury. Występuje tutaj standardowe działanie operatora selekcji lub jak ktoś woli kropki, a więc dostęp do składowej struktury jest możliwy jedynie po pośrednim jej zaadresowaniu w asm. W związku z tym, aby uzyskać jeszcze efektywniejszy kod należy prócz najlepszego ustawienia optymalizacji zwrócić jeszcze uwagę na zapis PORTA_OUTSET, który to jest bezpośrednim aliasem na rejestr OUTSET portu A.


Jeśli dobrze Cię zrozumiałem to : polecenie PORTA.OUTSET powinno dać bez optymalizacji inny kod wynikowy niż PORTA_OUTSET ?

Sprawdziłem to na swoim eclipse: są identyczne!

PORTA.OUT = PIN5_bm;
Składnia: [ Pobierz ] [ Ukryj ]
język asm
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

PORTA_OUTSET = PIN5_bm;
Składnia: [ Pobierz ] [ Ukryj ]
język asm
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


W pliku iox32e5.h znalazłem tylko:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

brak tam definicji z "."

ps. pamiętaj że mówisz do laika :geek:



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 18 paź 2014, o 12:50 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 07 kwi 2013
Posty: 418
Lokalizacja: Rzeszów
Pomógł: 102

Może faktycznie niezbyt precyzyjnie się wyraziłem. Miałem na myśli to, że sekwencja odwołań do rejestrów będzie bardziej optymalna od sekwencji instrukcji z dostępem selektywnym (poprzez pola struktury - operator kropki) np.:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Przy włączonej optymalizacji, pierwsza linia doda dwie instrukcje ładujące bezpośrednio (ldi) adres struktury (PORTA). Pozostałe instrukcje pozostają bez wpływu na różnicę czasów wykonywania kodu (std/sts).

Pliki nagłówkowe nie będą zawierać stałych z kropką, ponieważ jest to operator języka C/C++, wyrażający dostęp do pola struktury...
Jak widzisz definicje z '_' są bezpośrednim wskazaniem na miejsce (adres) w pamięci, a sama nazwa peryferium to struktura (w przypadku portów jest to typ strukturalny PORT_t).

PS. Staram się tłumaczyć w dość prosty sposób, ale wiem że nie mam do tego talentu i nie bardzo mi to wychodzi :oops:



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 19 paź 2014, o 12:26 
Offline
Użytkownik

Dołączył(a): 30 sie 2014
Posty: 170
Pomógł: 2

A jednak kolego sie mylisz! Tlumaczenie wychodzi Ci lepiej niz myslisz :D dziekuje, wszystko jasne!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 11 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 2 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO