-
1. Data: 2012-05-26 07:56:32
Temat: [ARM] Obsługa peryferiów poprzez API (wskazniki do struktury)
Od: slawek7 <s...@w...pl>
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?
-
2. Data: 2012-05-26 12:49:01
Temat: Re: [ARM] Obsługa peryferiów poprzez API (wskazniki do struktury)
Od: Michał Lankosz <m...@t...pl>
W dniu 2012-05-26 07:56, slawek7 pisze:
> 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?
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ł
-
3. Data: 2012-05-26 13:59:29
Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
Od: slawek7 <s...@w...pl>
> 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?
-
4. Data: 2012-05-26 14:43:45
Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
Od: Portal <m...@t...poczta.onet.pl>
> 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
-
5. Data: 2012-05-26 16:28:32
Temat: Re: [ARM] Obsługa peryferiów poprzez API (wskazniki do struktury)
Od: "J.F." <j...@p...onet.pl>
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.
-
6. Data: 2012-05-26 17:09:02
Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
Od: slawek7 <s...@w...pl>
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?
-
7. Data: 2012-05-26 18:10:34
Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
Od: bartekltg <b...@g...com>
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
-
8. Data: 2012-05-26 18:25:20
Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
Od: Portal <m...@t...poczta.onet.pl>
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
-
9. Data: 2012-05-26 18:29:38
Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
Od: bartekltg <b...@g...com>
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
-
10. Data: 2012-05-27 16:37:29
Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
Od: slawek7 <s...@w...pl>
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ą?