RTV forum PL | NewsGroups PL

Jak działa dostęp do rejestrów GPIO w STM32 przy użyciu wskaźników i struktur?

[ARM] Obsługa peryferiów poprzez API (wskazniki do struktur

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Jak działa dostęp do rejestrów GPIO w STM32 przy użyciu wskaźników i struktur?

Goto page Previous  1, 2, 3  Next

slawek7
Guest

Mon May 28, 2012 8:14 pm   



On 27 Maj, 19:27, Portal <macport.u...@to.poczta.onet.pl> wrote:
Quote:
On 05/27/2012 04:37 PM, slawek7 wrote:

Zgadza się to co piszecie i zrozumiałem o co chodzi.
Przecież to jest coś takiego
(*(uint32_t*)0x40010C10)=0x0000000f;
Powoduje to bezpośredni dostęp do rejestru i operację na porcie PB.

Natomiast nie rozumiem zapisów które pojawiają się dokumentacji..
Adres jest 32 bitowy więc stąd zapewne pierwsze rzutowanie ale pojawia
się też informacja że do rejestru można się dostać
albo jako word, albo jako half-word, albo jako byte? O co tu chodzi?
Jaki adres i jakie rzutowanie wtedy się robi i co jak poda się liczbę
word 32 bitową zamiast wymaganą half-word 16 bitową?

Chyba mylisz trochę postać adresu z typem danych siedzących pod tym adresem.
Operacja:
(*(uint32_t*)0x40010C10)=0x0000000f;
oznacza tyle co zapisz wartość 0x0000000f pod adres 0x40010C10 traktując
ją (wartość, nie adres) jako liczbę 32-bitową bez znaku.

Jeżeli zrobisz podobną operację, ale w postaci:
(*(uint8_t*)0x40010C10)=0x0f;
to pod ten sam adres zapiszesz tylko pojedynczy bajt, pozostawiając
pozostałe trzy bajty 32-bitowego słowa zapisanego pod adresem 0x40010C10
bez zmian.

Chyba rozumiem. Bo czy to znaczy że jeśli jakiś rejestr 32 bitowy ma
możliwość zapisania go wartością 16 bitowa bo tak podaje dokumentacja
to chcąc dokonać takiego zapisu liczbą 16 bitową używam rzutowania 16
bitowego w postaci (*(uint16_t*)0x40010C10)=0x1234;
Natomiast jeśli rejestr musi byc zapisany tylko wartością 32 bitowa bo
tak każe dokumentacja to u zywam (*(uint32_t*)0x40010C10)=0x12345678;

Ale mam wątpliwość, czy czasem to rzutowanie nie oznacza tylko
arytmetyki wskaźników? Tzn za następny wskazywany obszar bęzie większy
albo o 2 bajty albo o 4, jak w przypadku zwykłej arytmetyki wskaźników
np
uint16_t *ptr; // wskaźnik na liczbę 16 bitową
teraz zwiększamy adres o jeden ptr++; czyli tak naprawdę wskaźnik
skacze o dwa a nie o jeden adres?

slawek7
Guest

Mon May 28, 2012 8:14 pm   



On 27 Maj, 19:27, Portal <macport.u...@to.poczta.onet.pl> wrote:
Quote:
On 05/27/2012 04:37 PM, slawek7 wrote:

Zgadza się to co piszecie i zrozumiałem o co chodzi.
Przecież to jest coś takiego
(*(uint32_t*)0x40010C10)=0x0000000f;
Powoduje to bezpośredni dostęp do rejestru i operację na porcie PB.

Natomiast nie rozumiem zapisów które pojawiają się dokumentacji..
Adres jest 32 bitowy więc stąd zapewne pierwsze rzutowanie ale pojawia
się też informacja że do rejestru można się dostać
albo jako word, albo jako half-word, albo jako byte? O co tu chodzi?
Jaki adres i jakie rzutowanie wtedy się robi i co jak poda się liczbę
word 32 bitową zamiast wymaganą half-word 16 bitową?

Chyba mylisz trochę postać adresu z typem danych siedzących pod tym adresem.
Operacja:
(*(uint32_t*)0x40010C10)=0x0000000f;
oznacza tyle co zapisz wartość 0x0000000f pod adres 0x40010C10 traktując
ją (wartość, nie adres) jako liczbę 32-bitową bez znaku.

Jeżeli zrobisz podobną operację, ale w postaci:
(*(uint8_t*)0x40010C10)=0x0f;
to pod ten sam adres zapiszesz tylko pojedynczy bajt, pozostawiając
pozostałe trzy bajty 32-bitowego słowa zapisanego pod adresem 0x40010C10
bez zmian.

Chyba rozumiem. Bo czy to znaczy że jeśli jakiś rejestr 32 bitowy ma
możliwość zapisania go wartością 16 bitowa bo tak podaje dokumentacja
to chcąc dokonać takiego zapisu liczbą 16 bitową używam rzutowania 16
bitowego w postaci (*(uint16_t*)0x40010C10)=0x1234;
Natomiast jeśli rejestr musi byc zapisany tylko wartością 32 bitowa bo
tak każe dokumentacja to u zywam (*(uint32_t*)0x40010C10)=0x12345678;

Ale mam wątpliwość, czy czasem to rzutowanie nie oznacza tylko
arytmetyki wskaźników? Tzn za następny wskazywany obszar bęzie większy
albo o 2 bajty albo o 4, jak w przypadku zwykłej arytmetyki wskaźników
np
uint16_t *ptr; // wskaźnik na liczbę 16 bitową
teraz zwiększamy adres o jeden ptr++; czyli tak naprawdę wskaźnik
skacze o dwa a nie o jeden adres?

Michoo
Guest

Mon May 28, 2012 8:33 pm   



On 28.05.2012 20:14, slawek7 wrote:
Quote:
Ale mam wątpliwość, czy czasem to rzutowanie nie oznacza tylko
arytmetyki wskaźników? Tzn za następny wskazywany obszar bęzie większy
albo o 2 bajty albo o 4, jak w przypadku zwykłej arytmetyki wskaźników
np
uint16_t *ptr; // wskaźnik na liczbę 16 bitową
teraz zwiększamy adres o jeden ptr++; czyli tak naprawdę wskaźnik
skacze o dwa a nie o jeden adres?
Skacze o jeden sizeof(typ_wskazywany) - do tego jest arytmetyka wskaźników.


Natomiast to czy użyjesz wskaźnika na uint32_t czy uint8_t wpłynie m.i.
na to, że kompilator wtedy zadba o odpowiednie opakowanie niewyrównanego
dostępu, czy wręcz (zależnie od zestawu instrukcji) z:
*((uint8_t *)0x12)=1; zamieni na odpowiednią sekwencję load-modify-store
tak, żeby nie popsuć pozostałych 3 bajtów.

--
Pozdrawiam
Michoo

Portal
Guest

Tue May 29, 2012 6:13 am   



On 05/28/2012 10:33 PM, Michoo wrote:
Quote:
Natomiast to czy użyjesz wskaźnika na uint32_t czy uint8_t wpłynie m.i.
na to, że kompilator wtedy zadba o odpowiednie opakowanie niewyrównanego
dostępu, czy wręcz (zależnie od zestawu instrukcji) z:
*((uint8_t *)0x12)=1; zamieni na odpowiednią sekwencję load-modify-store
tak, żeby nie popsuć pozostałych 3 bajtów.


Niebezpieczne założenie - nie każdy kompilator to robi i nieostrożność
programisty może skończyć się wywalaniem błedu wyrównania przez
procesor. Najlepiej w przypadkach kiedy to programista dostarcza adres
bezpośrednio w kodzie źródłowym, żeby jednak on sam zadbał również o
odpowiednie wyrównanie.

Pozdr
Portal

Portal
Guest

Tue May 29, 2012 6:20 am   



On 05/28/2012 08:13 PM, slawek7 wrote:

Quote:
Ale mam wątpliwość, czy czasem to rzutowanie nie oznacza tylko
arytmetyki wskaźników? Tzn za następny wskazywany obszar bęzie większy
albo o 2 bajty albo o 4, jak w przypadku zwykłej arytmetyki wskaźników
np
uint16_t *ptr; // wskaźnik na liczbę 16 bitową
teraz zwiększamy adres o jeden ptr++; czyli tak naprawdę wskaźnik
skacze o dwa a nie o jeden adres?

Źle podejrzewasz. Przede wszystkim typ użytego wskaźnika determinuje typ
dostępu w kodzie wynikowym tzn. fizycznie na szynie jest wystawiony
rozkaz odczytu lub zapisu tylko pojedynczego bajtu lub 16-bitowego słowa
zamiast pełnego 32-bitowego. Czyli jeżeli zapisujesz uint8_t np. pod
adres 0x00000000, to bajty pod adresami 0x00000001, 0x00000002 i
0x00000003 pozostaną nienaruszone, podczas gdy zrobienie tego samego
jako operacji na uint32_t pod adres 0x00000000 zapisze wszystkie cztery
bajty słowa.

Pozdr
Portal

RoMan Mandziejewicz
Guest

Tue May 29, 2012 6:47 pm   



Hello slawek7,

Tuesday, May 29, 2012, 8:15:41 PM, you wrote:

Quote:
A na koniec masz zadanie domowe
(*((uint32_t **) &ptr))++;
Niestety nie mój poziom, nie wiem.

Jeszcze kilka razy, bo cztery to za mało :(

--
Best regards,
RoMan
Nowa strona: http://www.elektronika.squadack.com (w budowie!)

Portal
Guest

Tue May 29, 2012 7:34 pm   



On 05/29/2012 08:47 PM, RoMan Mandziejewicz wrote:

Quote:
A na koniec masz zadanie domowe
(*((uint32_t **)&ptr))++;
Niestety nie mój poziom, nie wiem.

Jeszcze kilka razy, bo cztery to za mało Sad


Może się cztery razy przymierzał ?

Pozdr
Portal

slawek7
Guest

Tue May 29, 2012 8:02 pm   



Quote:
A na koniec masz zadanie domowe
(*((uint32_t **) &ptr))++;

Niestety nie mój poziom, nie wiem.

slawek7
Guest

Tue May 29, 2012 8:02 pm   



Quote:
A na koniec masz zadanie domowe
(*((uint32_t **) &ptr))++;

Niestety nie mój poziom, nie wiem.

slawek7
Guest

Tue May 29, 2012 8:09 pm   



Quote:
A na koniec masz zadanie domowe
(*((uint32_t **) &ptr))++;

Niestety nie mój poziom, nie wiem.

slawek7
Guest

Tue May 29, 2012 8:15 pm   



Quote:
A na koniec masz zadanie domowe
(*((uint32_t **) &ptr))++;

Niestety nie mój poziom, nie wiem.

slawek7
Guest

Wed May 30, 2012 5:45 am   



On 29 Maj, 21:34, Portal <macport.u...@to.poczta.onet.pl> wrote:
Quote:
On 05/29/2012 08:47 PM, RoMan Mandziejewicz wrote:

A na koniec masz zadanie domowe
(*((uint32_t **)&ptr))++;
Niestety nie mój poziom, nie wiem.

Jeszcze kilka razy, bo cztery to za mało :(

Może się cztery razy przymierzał ?

Ale o co Wam chodzi??????????
Moze o to że kilka razu wrzuciło jedną odpowiedz? czasami zdarza się
jak zbyt szubko odswieżę stronę. Nigdy to się Wam nie przytrafiło?
Czy Wy na prawdę nie potraficie okazać za grosz
zrozumienia????????????
Już usuwam.

Grejon
Guest

Wed May 30, 2012 6:28 am   



W dniu 2012-05-30 06:30, slawek7 pisze:
Quote:
On 29 Maj, 21:34, Portal<macport.u...@to.poczta.onet.pl> wrote:
On 05/29/2012 08:47 PM, RoMan Mandziejewicz wrote:

A na koniec masz zadanie domowe
(*((uint32_t **)&ptr))++;
Niestety nie mój poziom, nie wiem.

Jeszcze kilka razy, bo cztery to za mało :(

Może się cztery razy przymierzał ?

Ale o co Wam chodzi??????????
Moze o to że kilka razu wrzuciło jedną odpowiedz?

Tak.

Quote:
czasami zdarza się
jak zbyt szubko odswieżę stronę. Nigdy to się Wam nie przytrafiło?

Nie.

Quote:
Czy Wy na prawdę nie potraficie okazać za grosz
zrozumienia????????????

Nie musisz tak pytajnikami napierdalać.

Quote:
Już usuwam.

Dziękuję.

--
Grzegorz Jońca GG: 7366919 JID:gzesiu@jabber.wp.pl
Green Trafic 140 dCi
Mazda 6 2.0 "parafinka" kombi

Artur M. Piwko
Guest

Wed May 30, 2012 7:21 am   



In the darkest hour on Tue, 29 May 2012 21:30:24 -0700 (PDT),
slawek7 <sholojda@wp.pl> screamed:
Quote:
A na koniec masz zadanie domowe
(*((uint32_t **)&ptr))++;
Niestety nie mój poziom, nie wiem.

Jeszcze kilka razy, bo cztery to za mało :(

Może się cztery razy przymierzał ?

Ale o co Wam chodzi??????????
Moze o to że kilka razu wrzuciło jedną odpowiedz? czasami zdarza się
jak zbyt szubko odswieżę stronę. Nigdy to się Wam nie przytrafiło?
Czy Wy na prawdę nie potraficie okazać za grosz
zrozumienia????????????

W takich sytuacjach nie odświeżaj tylko wejdź z innej zakładki i sprawdź
czy dotarło.

Quote:
Już usuwam.

Nie da się w zasadzie usunąć dlatego taka reakcja.

--
[ Artur M. Piwko : Pipen : AMP29-RIPE : RLU:100918 : From == Trap! : SIG:236B ]
[ 09:21:13 user up 13184 days, 21:16, 1 user, load average: 0.98, 0.10, 0.45 ]

In democracy everyone has the right to be represented, even the jerks.

Artur M. Piwko
Guest

Wed May 30, 2012 7:24 am   



In the darkest hour on Mon, 28 May 2012 11:14:04 -0700 (PDT),
slawek7 <sholojda@wp.pl> screamed:
Quote:
Jeżeli zrobisz podobną operację, ale w postaci:
(*(uint8_t*)0x40010C10)=0x0f;
to pod ten sam adres zapiszesz tylko pojedynczy bajt, pozostawiając
pozostałe trzy bajty 32-bitowego słowa zapisanego pod adresem 0x40010C10
bez zmian.

Chyba rozumiem. Bo czy to znaczy że jeśli jakiś rejestr 32 bitowy ma
możliwość zapisania go wartością 16 bitowa bo tak podaje dokumentacja
to chcąc dokonać takiego zapisu liczbą 16 bitową używam rzutowania 16
bitowego w postaci (*(uint16_t*)0x40010C10)=0x1234;
Natomiast jeśli rejestr musi byc zapisany tylko wartością 32 bitowa bo
tak każe dokumentacja to u zywam (*(uint32_t*)0x40010C10)=0x12345678;

Ale mam wątpliwość, czy czasem to rzutowanie nie oznacza tylko
arytmetyki wskaźników? Tzn za następny wskazywany obszar bęzie większy
albo o 2 bajty albo o 4, jak w przypadku zwykłej arytmetyki wskaźników

Nie ma tu arytmetyki sensu strice.

Quote:
np
uint16_t *ptr; // wskaźnik na liczbę 16 bitową
teraz zwiększamy adres o jeden ptr++; czyli tak naprawdę wskaźnik
skacze o dwa a nie o jeden adres?

Wskaźnik skoczy o jeden adres zawsze (ale o 2 bajty).

--
[ Artur M. Piwko : Pipen : AMP29-RIPE : RLU:100918 : From == Trap! : SIG:229B ]
[ 09:22:16 user up 13184 days, 21:17, 1 user, load average: 0.98, 0.10, 0.45 ]

Would you rather have a 5-inch hard or an 8-inch floppy?

Goto page Previous  1, 2, 3  Next

elektroda NewsGroups Forum Index - Elektronika Polska - Jak działa dostęp do rejestrów GPIO w STM32 przy użyciu wskaźników i struktur?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map