eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronika[ARM] Obsługa peryferiów poprzez API (wskazniki do struktury)
Ilość wypowiedzi w tym wątku: 32

  • 11. Data: 2012-05-27 16:37:34
    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ą?


  • 12. Data: 2012-05-27 19:27:20
    Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
    Od: Portal <m...@t...poczta.onet.pl>

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


  • 13. Data: 2012-05-28 20:13:59
    Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
    Od: slawek7 <s...@w...pl>

    On 27 Maj, 19:27, Portal <m...@t...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?


  • 14. Data: 2012-05-28 20:14:04
    Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
    Od: slawek7 <s...@w...pl>

    On 27 Maj, 19:27, Portal <m...@t...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?


  • 15. Data: 2012-05-28 20:14:08
    Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
    Od: slawek7 <s...@w...pl>

    On 27 Maj, 19:27, Portal <m...@t...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?


  • 16. Data: 2012-05-28 20:14:16
    Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
    Od: slawek7 <s...@w...pl>

    On 27 Maj, 19:27, Portal <m...@t...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?


  • 17. Data: 2012-05-28 21:52:19
    Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
    Od: "J.F." <j...@p...onet.pl>

    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.


  • 18. Data: 2012-05-28 22:33:03
    Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
    Od: Michoo <m...@v...pl>

    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


  • 19. Data: 2012-05-29 08:13:03
    Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
    Od: Portal <m...@t...poczta.onet.pl>

    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


  • 20. Data: 2012-05-29 08:20:03
    Temat: Re: Obsługa peryferiów poprzez API (wskazniki do struktury)
    Od: Portal <m...@t...poczta.onet.pl>

    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

strony : 1 . [ 2 ] . 3 . 4


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: