Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

kod - Niezrozumiały kod

elords 03 Sty 2013 02:11 1488 14
  • #1 03 Sty 2013 02:11
    elords
    Poziom 8  

    Uczę się programowania dlatego proszę o pomoc w rozszyfrowaniu tego kodu:

    1. Dlaczego jest taki zapis i co on oznacza

    Kod: c
    Zaloguj się, aby zobaczyć kod


    gdzie
    Kod: c
    Zaloguj się, aby zobaczyć kod



    2. Dlaczego w main.c
    Kod: c
    Zaloguj się, aby zobaczyć kod

    czemu nie wystarczy
    Kod: c
    Zaloguj się, aby zobaczyć kod



    3. Co daje wypisanie w pliku hex poszczególnych funkcji wykorzystanych w programie

    Kod: c
    Zaloguj się, aby zobaczyć kod



    Jeżeli ktoś mógłby jeszcze polecić dobrą książkę na temat programowania STM32

    0 14
  • #2 03 Sty 2013 08:40
    94075
    Użytkownik usunął konto  
  • Pomocny post
    #3 03 Sty 2013 11:29
    kedzi1
    Poziom 18  

    ad.1
    Aby zrozumieć co się dzieje w tej linijce musisz dowiedzieć się co to są wskaźniki i rzutowanie typów.
    Jeżeli restart to tablica, to:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    przepisze pierwszy element z tablicy do zmiennej x.
    Nazwa tablicy to jednocześnie wskaźnik (adres w pamięci) do tej tablicy.
    I na przykład:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    zadziała tak samo jak:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Gwiazdka daje nam dostęp do wartości zmiennej na jaką wskazuje wskaźnik.
    Rzutowanie zaś działa tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    To taka zmiana typu zmiennej w locie. To duże uproszczenie, poczytaj o tym najlepiej.

    Twój przykład to połączenie tych dwóch technik. Czyli:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    to wskaźnik na drugi element tablicy (jego adres w pamięci), bez +1 mieli byśmy adres pierwszego elementu. Tablica zawiera elementy 8 bitowe więc o adres dalej jest drugi jej element.
    Kod: c
    Zaloguj się, aby zobaczyć kod

    teraz wskaźnik wskazuje na zmienną 16 bitową.
    Czyli:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    pozwala nam odczytać drugi i trzeci element tablicy 8 bitowej jako jedną zmienną 16 bitową.
    Są na to lepsze metody, to trochę taki skrót programistyczny. Nie polecam go, ale jest dość często stosowany.

    0
  • #4 03 Sty 2013 12:08
    Freddie Chopin
    Specjalista - Mikrokontrolery

    kedzi1 napisał:
    Są na to lepsze metody, to trochę taki skrót programistyczny. Nie polecam go, ale jest dość często stosowany.

    O wiele lepiej napisać, że na wielu architekturach taka operacja skończy się krytycznym wyjątkiem lub - w najlepszym wypadku - odczytem jakiejś bezsensownej wartości, ponieważ jest to proszenie się o unaligned access.

    4\/3!!

    1
  • #5 03 Sty 2013 12:13
    BlueDraco
    Specjalista - Mikrokontrolery

    Freddie, z ust mi to wyjąłeś... ;)

    No ale w nowiuśkim C można już napisać:

    uint8_t _Alignas uint16_t buf[64];

    i już będzie ok. A w starym C też się da, tylko trochę więcej czarodziejskich zaklęć potrzeba.

    0
  • #6 03 Sty 2013 12:38
    kedzi1
    Poziom 18  

    Zgadza się. Nie napisałem, że takie "sztuczki" najczęściej można spotkać w kodzie na AVRy.
    Lepiej jest odczytać obie 8 bitowe części zmiennej z osobna, a później bardziej znaczący bajt przesunąć o 8 bitów lub pomnożyć przez 256:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    lub
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Oczywiście dla porządku little endian...

    0
  • #7 03 Sty 2013 13:58
    Freddie Chopin
    Specjalista - Mikrokontrolery

    BlueDraco napisał:
    i już będzie ok.

    Wcale nie będzie OK. W zależności od endianness jedna z tych dwóch operacji wciąż jest niebezpieczna:

    *(uint16_t*)(buf+1);
    *(uint16_t*)(buf);

    Bo tak czy siak jedna z nich będzie niewyrównana.

    4\/3!!

    0
  • #8 03 Sty 2013 14:02
    kemot55
    Poziom 30  

    Jak są liczby typu int to OK. Ja stosując odwołanie poprzez adres (czyli podobnie jak w poście 1) rozbijałem liczby zmienno-przecinkowe na bajty (np. żeby wysłać to poprzez jakiś port szeregowy) i nigdy nie miałem kłopotów. W sumie to nie wiem jak to zrobić inaczej. Pewnie jest na to jakiś inny patent - chętnie poznam.
    I tak na marginesie: w jakiej architekturze próba odwołania do zawartości pamięci pod konkretnym adresem może generować błąd?

    0
  • #9 03 Sty 2013 14:48
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Chyba nie widzisz jednego problemu - nikt nie pisze tutaj o rozbijaniu int/float na bajty (czyli z "dużego" typu na "mały"), tylko o operacji odwrotnej, w której masz tablice bajtów i chcesz sobie nagle odczytać ją jako float, najlepiej od 3 bajtu (przejście z "małego" typu na "duży").

    kemot55 napisał:
    I tak na marginesie: w jakiej architekturze próba odwołania do zawartości pamięci pod konkretnym adresem może generować błąd?

    http://en.wikipedia.org/wiki/Segmentation_fault
    Cytat:
    Bus error

    Bus errors are usually signaled with the SIGBUS signal, but SIGBUS can also be caused by any general device fault that the computer detects. A bus error rarely means that the computer hardware is physically broken—it is normally caused by a bug in a program's source code.
    There are two main causes of bus errors:
    ...
    unaligned access
    Most CPUs are byte-addressable, where each unique memory address refers to an 8-bit byte. Most CPUs can access individual bytes from each memory address, but they generally cannot access larger units (16 bits, 32 bits, 64 bits and so on) without these units being "aligned" to a specific boundary. For example, if multi-byte accesses must be 16 bit-aligned, addresses (given in bytes) at 0, 2, 4, and so on would be considered aligned and therefore accessible, while addresses 1, 3, 5, and so on would be considered unaligned. Similarly, if multi-byte accesses must be 32-bit aligned, addresses 0, 4, 8, 12, and so on would be considered aligned and therefore accessible, and all addresses in between would be considered unaligned. Attempting to access a unit larger than a byte at an unaligned address can cause a bus error.


    4\/3!!

    0
  • #10 03 Sty 2013 14:49
    94075
    Użytkownik usunął konto  
  • #11 03 Sty 2013 14:57
    Freddie Chopin
    Specjalista - Mikrokontrolery

    albertb napisał:
    Na marginesie to chyba wszystkie nie 8 bitowe pojawiające się regularnie na elektrodzie.

    Akurat Cortex-M3 obsługuje unaligned access, ale "wewnętrznie" jest to dostęp wieloetapowy.

    P.S. Przy zapisie pod tak sformułowany wskaźnik, nawet jeśli układ obsługuje niewyrównany dostęp pojawia się problem atomowości takowego (a raczej braku).

    4\/3!!

    0
  • #12 03 Sty 2013 15:04
    94075
    Użytkownik usunął konto  
  • #13 03 Sty 2013 16:08
    elords
    Poziom 8  

    dzięki za pomoc :)

    Freddie Chopin napisał:
    Akurat Cortex-M3 obsługuje unaligned access, ale "wewnętrznie" jest to dostęp wieloetapowy.
    to znaczy że ten procesor jest wielowątkowy?? czyli wiele procesów realizuje w jednym czasie

    0
  • Pomocny post
    #14 03 Sty 2013 16:15
    Freddie Chopin
    Specjalista - Mikrokontrolery

    elords napisał:
    to znaczy że ten procesor jest wielowątkowy??

    To znaczy że odczyt jednej "zmiennej" jest realizowany przez kilkukrotny (i oczywiście sekwencyjny) dostęp do pamięci. Żaden procesor nie jest wielowątkowy, chyba że ma wiele rdzeni, ale wtedy to tak naprawdę wiele jedno-wątkowych układów w jednej obudowie. Nawet słynny HyperThreading nie daje rzeczywistej wielowątkowości, tylko bardzo szybką (w zasadzie błyskawiczną) zmianę kontekstu poprzez zdublowanie wszystkich wewnętrznych rejestrów rdzenia.

    4\/3!!

    0
  • #15 03 Sty 2013 17:13
    kemot55
    Poziom 30  

    No jasne. Moje działania nigdy nie zakładały, że z bajtów zrobię float "jednym ruchem" (zawsze było to operacje na tablicy 4...8 elementowej) i stąd to wszystko działa na znacznej grupie maszyn. Natomiast wracając do tematu to w STM'ie nie do wszystkich rejestrów jest dostęp "unaligned". A poza tym można ustawić reakcję (fault) na zdarzenie typu "unaligned access".
    W sumie to sprawa istotna a nigdy w to nie wnikałem.

    0