Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

28 views
Skip to first unread message

slawek7

unread,
May 26, 2012, 1:56:32 AM5/26/12
to
Cześć.
Mamy np uC STM32. Dostęp do portów np ustawienie jakiegoś
wyprowadzenia możemy zrobić albo korzystając z darowanych przez
producenta bibliotek albo poprzez odwołania do rejestrów, jak np GPIOB-
>BRR=0x0100;

I właśnie chodzi mi o ten drugi sposób z użyciem wskaźnika. Czy
dokonując zapisu GPIOB->BRR=.. operujemy na zmiennej wskaźnikowej?
Inaczej mówiąc czy mamy zdefiniowaną zmienną *GPIOB?
Nie mogę dojść do tego jak to działa. W plikach jest taka definicja
struktury:
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;


A potem coś takiego
#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) //GPIO_BASE
to liczba

Ale nie widze tutaj żadnej definicji zmiennej wskaźnikowej? Czyżby nie
była ona potrzebna? To jak to działa?

Wiem że dla Was to proste, ale jak się trochę zakręciłem i nie wiem
juz o co chodzi?

Michał Lankosz

unread,
May 26, 2012, 6:49:01 AM5/26/12
to
W dniu 2012-05-26 07:56, slawek7 pisze:
tutaj: (GPIO_TypeDef *)
W skrócie. GPIOB_BASE to adres bazowy (początkowy) rejestrów I/O portu
B. Rzutujemy tu wskaźnik na do struktury po kolei poukładanych rejestrów
I/O. Dzięki temu jedną strukturą GPIO_TypeDef możemy opisać tyle portów
ile ma dany procesor znając tylko ich adresy bazowe.
GPIOB jest więc wskaźnikiem do struktury.

Michał

slawek7

unread,
May 26, 2012, 7:59:29 AM5/26/12
to

> tutaj: (GPIO_TypeDef *)
> W skrócie. GPIOB_BASE to adres bazowy (początkowy) rejestrów I/O portu
> B. Rzutujemy tu wskaźnik na do struktury po kolei poukładanych rejestrów
> I/O. Dzięki temu jedną strukturą GPIO_TypeDef możemy opisać tyle portów
> ile ma dany procesor znając tylko ich adresy bazowe.
> GPIOB jest więc wskaźnikiem do struktury.
>
> Michał

Ale czy ten wskaźnik do struktury to fizycznie jest zmienna? Jeśli tak
to gdzie jej definicja? Typedef nie definuje i nie rodzi zmiennej, tak
samo jak #define, wiec gdzie się pojawia ta zmienna wskaźnikowa?
Przecież wskaźnik to zmienna przechowująca adres innej zmiennej, w tym
przypadku struktury, czy nie tak?

Portal

unread,
May 26, 2012, 8:43:45 AM5/26/12
to
> Ale czy ten wskaźnik do struktury to fizycznie jest zmienna? Jeśli tak
> to gdzie jej definicja? Typedef nie definuje i nie rodzi zmiennej, tak
> samo jak #define, wiec gdzie się pojawia ta zmienna wskaźnikowa?
> Przecież wskaźnik to zmienna przechowująca adres innej zmiennej, w tym
> przypadku struktury, czy nie tak?

A kto powiedział, że wskaźnik musi być zmienną? W Twoim przykładze jest
akurat stałą, która po rozwinięciu definicji GPIOB_BASE przez
preprocesor zostanie efektywnie zastąpiona natychmiastową stałą liczbową
(adres) zrzutowaną na wskaźnik odpowiedniego typu coby kompilator
wiedział co pod tym adresem siedzi dzięki czemu można w kodzie mieć
odnośniki do konkretnych pól struktury tam umieszczonej. Nie działa to
nic inaczej jak definiowanie stałych liczbowych jako makr preprocesora a
potem używanie ich np. do nadawania wartości zmiennym - tu też dopóki
nie użyjesz, to nigdzie w kodzie ta wartość nie będzie przechowywana.
W Twoim przykładzie jest tylko jedno istotne założenie tzn. że wskaźnik
do struktury jest co do warotści równy jej fizycznemu adresowi czyli nie
ma wirtualizacji pamięci (czytaj: brak OSa z prawdziwego zdarzenia).

Pozdr
Portal

J.F.

unread,
May 26, 2012, 10:28:32 AM5/26/12
to
Dnia Fri, 25 May 2012 22:56:32 -0700 (PDT), slawek7 napisał(a):
> Nie mogę dojść do tego jak to działa. W plikach jest taka definicja
> struktury:
> typedef struct
> {
> __IO uint32_t CRL;
> __IO uint32_t CRH;
> __IO uint32_t BRR;
> } GPIO_TypeDef;
>
> A potem coś takiego
> #define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
>//GPIO_BASE to liczba
> Ale nie widze tutaj żadnej definicji zmiennej wskaźnikowej? Czyżby nie
> była ona potrzebna? To jak to działa?

Zapis
(costam *) liczba

mowi "skonwertuj 'liczba' na typ: wskaznik na 'costam'"

poniewaz wskaznik to adres liczbowy, czyli po prostu liczba, wiec poza
nielicznymi wyjatkami zadna konwersja nie musi byc wykonywana.

Ale ... takie wyrazenie jest dalej traktowane jak wskaznik na obiekt typu
"costam", wiec mozesz uzywac zwyczajnych dla wskaznikow konstrukcji, np
GPIOB->pole //to jest element struktury
*GPIOB.pole //to samo co wyzej
itd.

P.S. Uwaga na nawiasy, przy takich rozwinieciach przez preprocesor cuda
moga sie zdarzyc, ktos moglby napisac

#define GPIOB (GPIO_TypeDef *) GPIOB_BASE

a potem ktos inny

#define GPIOB_BASE GPIOB_BASE_1 + 0x80
....
GPIOB->BRR = 5


I nieszczescie gotowe.
Im wiecej nawiasow tym lepiej.

J.

slawek7

unread,
May 26, 2012, 11:09:02 AM5/26/12
to
W książce o ARMach AT91SAM7 znalazłem jeszcze coś takiego przy
deklaracji struktury:

typedef struct s_TC
{
__IO uint32_t CONTROL_R;
__IO uint32_t MODE_R;
__IO uint32_t COUNTER_VALUE;
__IO uint32_t INT_STATUS;

} S_TC, *PS_TC;

Potem
#define TC0 ((PS_TC)0xFFFA0000)

liczbę rzutujemy na wskaźnik, ale dlaczego bez gwiazdki?
Czy nie powinno być
#define TC0 ((*PS_TC)0xFFFA0000)
skoro typedef utworzył typ wskaźnikowy?

bartekltg

unread,
May 26, 2012, 12:10:34 PM5/26/12
to
W dniu 2012-05-26 17:09, slawek7 pisze:
> W książce o ARMach AT91SAM7 znalazłem jeszcze coś takiego przy
> deklaracji struktury:
>
> typedef struct s_TC
> {
> __IO uint32_t CONTROL_R;
> __IO uint32_t MODE_R;
> __IO uint32_t COUNTER_VALUE;
> __IO uint32_t INT_STATUS;
>
> } S_TC, *PS_TC;
>
> Potem
> #define TC0 ((PS_TC)0xFFFA0000)
>
> liczbę rzutujemy na wskaźnik, ale dlaczego bez gwiazdki?

No włąśnie. Rzutujesz liczbę na wskażnik. TO samo robiłeś tu:

#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)

GPIOB to rzut liczby GPIOB na _wskaźnik_ do typu GPIO_TypeDef.

int a to liczba
int * b to wskaźnik do liczby.

GPIO_TypeDef A; to strukturka
GPIO_TypeDef * bla; to skaźnik do strukturki.


> Czy nie powinno być
> #define TC0 ((*PS_TC)0xFFFA0000)

Wtedy TC0 byłby wskaźnikeim do wskaźnika do struktury typu S_TC.

pzdr
bartekltg


Portal

unread,
May 26, 2012, 12:25:20 PM5/26/12
to
On 05/26/2012 06:10 PM, bartekltg wrote:
>> Czy nie powinno być
>> #define TC0 ((*PS_TC)0xFFFA0000)
>
> Wtedy TC0 byłby wskaźnikeim do wskaźnika do struktury typu S_TC.


Tak jak piszesz (wskaźnik na wskaźnik) to by było gdyby zdefiniować:
#define TC0 ((PS_TC *)0xFFFA0000)
tymaczsem konstrukcja:
#define TC0 ((*PS_TC)0xFFFA0000)
zwyczajnie się nie skompiluje jeżeli spróbuje się użyć w źródle
odniesienia do TC0.

Co do reszty zgoda - PS_TC już jest typem wskaźnikowym i gwiazdek mu nie
potrzeba. Zamiennie można użyć:
#define TC0 ((S_TC *)0xFFFA0000)

Pozdr
Portal

bartekltg

unread,
May 26, 2012, 12:29:38 PM5/26/12
to
W dniu 2012-05-26 18:25, Portal pisze:
> On 05/26/2012 06:10 PM, bartekltg wrote:
>>> Czy nie powinno być
>>> #define TC0 ((*PS_TC)0xFFFA0000)
>>
>> Wtedy TC0 byłby wskaźnikeim do wskaźnika do struktury typu S_TC.
>
>
> Tak jak piszesz (wskaźnik na wskaźnik) to by było gdyby zdefiniować:
> #define TC0 ((PS_TC *)0xFFFA0000)
> tymaczsem konstrukcja:
> #define TC0 ((*PS_TC)0xFFFA0000)
> zwyczajnie się nie skompiluje jeżeli spróbuje się użyć w źródle
> odniesienia do TC0.


Aj, racja. Nie sprawdzałem dokłądnie kodu sławka, autokorekta
zadziałała;)


> Co do reszty zgoda - PS_TC już jest typem wskaźnikowym i gwiazdek mu nie
> potrzeba. Zamiennie można użyć:
> #define TC0 ((S_TC *)0xFFFA0000)


pzdr
bartekltg

slawek7

unread,
May 27, 2012, 10:37:29 AM5/27/12
to
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ą?

slawek7

unread,
May 27, 2012, 10:37:34 AM5/27/12
to

Portal

unread,
May 27, 2012, 1:27:20 PM5/27/12
to
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.
Kwestia czy nadpisany zostanie najmniej czy najbardziej znaczący bajt
słowa zależy od "endianności" systemu - najczęściej jest to little
endian czyli 0x40010C10 wskazuje na najmniej znaczący bajt słowa,
0x40010C11 na kolejny i tak aż do 0x40010C13.

Przy zapisach 16-bitowych możesz analogicznie zapisać tylko pół rejestru
adresując połówki jako uint16_t pod adresem 0x40010C10 oraz 0x40010C12.
W większości RISCowych architektur dostęp do danych musi uwzględniać
wyrównanie tzn. adresy dla 32-bitowych dostępów muszą być
wielokrotnością czwórki, dla 16-bitowych wielokrotnością dwójki a bajty
można czytać i pisać "zewsząd" (o ile dany fragment przestrzeni
adresowej w ogóle uwzględnia możliwość takiego dostępu - w Twoim
przykładzie jak widać rejestry peryferyjne uwzględniają taką możliwość).

Pozdr
Portal

slawek7

unread,
May 28, 2012, 2:14:08 PM5/28/12
to
On 27 Maj, 19:27, Portal <macport.u...@to.poczta.onet.pl> wrote:
> 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

unread,
May 28, 2012, 2:14:16 PM5/28/12
to
On 27 Maj, 19:27, Portal <macport.u...@to.poczta.onet.pl> wrote:
> 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.

slawek7

unread,
May 28, 2012, 2:14:04 PM5/28/12
to
On 27 Maj, 19:27, Portal <macport.u...@to.poczta.onet.pl> wrote:
> 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.

slawek7

unread,
May 28, 2012, 2:13:59 PM5/28/12
to
On 27 Maj, 19:27, Portal <macport.u...@to.poczta.onet.pl> wrote:
> 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.

J.F.

unread,
May 28, 2012, 3:52:19 PM5/28/12
to
Dnia Mon, 28 May 2012 11:13:59 -0700 (PDT), slawek7 napisał(a):
> 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

Czyli chyba nie rozumiesz

0x40010C10
to liczba. a moze i adres.

(uint32_t*)0x40010C10
liczba, zasadniczo ta sama, ale juz typu "wskaznik na cos"

*(uint32_t*)0x40010C10
obiekt wskazywany przez ten wskaznik. A poniewaz wskaznik mial wskazywac
na uint32, to obiekt jest uint32. Albo inny, jesli tak ustalisz.

(*(uint32_t*)0x40010C10)=0x0000000f;
a tu masz wpisanie wartosci do obiektu.

Przy czym moze nastapic kolejna konwersja wyrazenia z prawej strony, na typ
obiektu z lewej. Np

(*(uint8_t*)0x40010C10)=0x00001234;
to zapisze jeden bajt, 34

(*(uint32_t*)0x40010C10)=0x9f;
a to zapisze 0000009f, albo ffffff9f :-)

> 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

A to oczywiscie tez. Tylko trzeba umiejetnie wykorzystywac.

> 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?

Tylko wiesz ze nie zapiszesz
((uint8_t*)0x40010C10)++)

ani
((uint32_t *) ptr)++;

Za to mozesz sprobowac
*((uint32_t *)ptr+1)=1 ;

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

J.

Michoo

unread,
May 28, 2012, 4:33:03 PM5/28/12
to
On 28.05.2012 20:14, slawek7 wrote:
> 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

unread,
May 29, 2012, 2:13:03 AM5/29/12
to
On 05/28/2012 10:33 PM, Michoo wrote:
> 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

unread,
May 29, 2012, 2:20:03 AM5/29/12
to
On 05/28/2012 08:13 PM, slawek7 wrote:

> 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

slawek7

unread,
May 29, 2012, 2:02:43 PM5/29/12
to
>A na koniec masz zadanie domowe
>(*((uint32_t **) &ptr))++;

Niestety nie mój poziom, nie wiem.
Message has been deleted
Message has been deleted
Message has been deleted

RoMan Mandziejewicz

unread,
May 29, 2012, 2:47:33 PM5/29/12
to
Hello slawek7,
Jeszcze kilka razy, bo cztery to za mało :(

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

Portal

unread,
May 29, 2012, 3:34:06 PM5/29/12
to
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ł ?

Pozdr
Portal

slawek7

unread,
May 30, 2012, 12:30:24 AM5/30/12
to
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

unread,
May 30, 2012, 2:28:51 AM5/30/12
to
W dniu 2012-05-30 06:30, slawek7 pisze:
> 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.

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

Nie.

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

Nie musisz tak pytajnikami napierdalać.

> Już usuwam.

Dziękuję.

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

Artur M. Piwko

unread,
May 30, 2012, 3:24:03 AM5/30/12
to
In the darkest hour on Mon, 28 May 2012 11:14:04 -0700 (PDT),
slawek7 <shol...@wp.pl> screamed:
>> 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.

> 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?

Artur M. Piwko

unread,
May 30, 2012, 3:21:56 AM5/30/12
to
In the darkest hour on Tue, 29 May 2012 21:30:24 -0700 (PDT),
slawek7 <shol...@wp.pl> screamed:
>> >>> 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.

> 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.

RoMan Mandziejewicz

unread,
May 30, 2012, 4:41:21 AM5/30/12
to
Hello slawek7,

Wednesday, May 30, 2012, 6:30:24 AM, you 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??????????

O nadmiar. Znaków zapytania też.

> Moze o to że kilka razu wrzuciło jedną odpowiedz?

Samo się nie wrzuciło...

> czasami zdarza się jak zbyt szubko odswieżę stronę.

28 minut między pierwszą a ostatnią wrzutką - to ma być za szybkie
odświeżanie?

> Nigdy to się Wam nie przytrafiło?

Nie.

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

Oczekujesz zrozumienia ode mnie? Chyba sobie jaja robisz :D

> Już usuwam.

Znaczy przyjedziesz do mnie do domu i usuniesz? To już poszło w świat.

Bądź mężczyzną, weź to na klatę, grzecznie przeproś a nie zachowuj się
jak http://rtfm.killfile.pl/#lajza

Grzegorz Niemirowski

unread,
May 31, 2012, 4:34:41 PM5/31/12
to
slawek7 <shol...@wp.pl> napisał(a):
> 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?

Jaką stronę? Ja korzystam z czytnika i niczego nie odświeżam. Jak kliknę
Wyślij to znika mi okienko pisania wiadomości i nie ma możliwości, żeby coś
poszło dwa razy.

--
Grzegorz Niemirowski
http://www.grzegorz.net/
OE PowerTool i Outlook Express: http://www.grzegorz.net/oe/
Uptime: 0 days, 13 hours, 24 minutes and 54 seconds

0 new messages