Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA w 2025? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 8 kwi 2025, o 05:55


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 9 ] 
    Autor Wiadomość
    PostNapisane: 5 sty 2022, o 16:21 
    Offline
    Nowy
    Avatar użytkownika

    Dołączył(a): 05 sty 2018
    Posty: 14
    Pomógł: 0

    Chcę powitać wszystkich. Cześć.
    Odświeżę trochę wątek wskaźników, ale w innej kwestii. Wskaźniki, piękna rzecz, ale... Mam problem z deklaracją wskaźników. Mówi się, że deklaracja (typ) wskaźnika powinna być taka sama jak deklaracja (typ) zmiennej, której adres wskazuje (mimo, że w avr 8 bit zawsze wskaźnik będzie dwubajtowy - wynika to z adresacji) to dla:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Chyba do tej pory dobrze myślę.

    I teraz. Rozumiem to, że typ wskaźnika musi być taki jak typ zmiennej, ponieważ przy operacji odwrotnej czyli zapisu do komórki pod adres wskaznik_zmiennej_x jakiejś nowej wartości np. xx typ jej musi być zgodny z typem zmiennej x (w moim przykładzie 4 bajtowej) z której pobraliśmy adres żeby "zmienna się tam zmieściła".

    Ale wymyśliłem sobie, że na port PORTB chcę wysłać najmłodszy bajt zmiennej unit32_t czyli x, a na port PORTD najstarszy bajt zmiennej x. I tutaj okazuje się, ze dla deklaracji wskaźnika dla zmiennej x jako unit32_t mam z tym problem, a dla deklaracji wskaźnika jako unit8_t dla tej zmiennej unit32_t wszystko działa dobrze. Ale najprościej będzie chyba pokazać część programu.

    Dla wersji uint32_t *WSK_PORTB;
    ----------------------------------------------------------

    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    -----------------------------------------------------------
    Na POTRB wysłana prawidłowa wartość, na PORTD jakaś przypadkowa wartość.

    Teraz dla wersji uint8_t *WSK_PORTB;
    ------------------------------------------------------------
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    ---------------------------------------------------------
    Na POTRB wysłana prawidłowa wartość i na PORTD też przypadkowa wartość.

    Czy można tak jak powyżej deklarować wskaźnik o typie innym niż zmienna, której dotyczy. Na razie ta część programu działa dobrze, ale może w jakiejś sytuacji coś pójdzie nie tak.
    Z góry dziękuję za sugestie.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 5 sty 2022, o 17:40 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 06 mar 2015
    Posty: 323
    Lokalizacja: Rybnik
    Pomógł: 23

    Poczytaj o przesunięciach bitowych i obejrzyj przy okazji te poradniki zaczynając od tego:
    https://www.youtube.com/watch?v=V83w0pu7MVo&t=2s

    _________________
    http://www.avrboss.pl



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 5 sty 2022, o 18:01 
    Offline
    Moderator
    Avatar użytkownika

    Dołączył(a): 03 paź 2011
    Posty: 27366
    Lokalizacja: Szczecin
    Pomógł: 1043

    nowy_stary napisał(a):
    PORTD = *(WSK_PORTB+3);

    W pierwszym przypadku gdy twój wskaźnik ma typ uint32_t robisz masakrę bo pominąłeś to jak działa arytmetyka wskaźników. Operacja WSK_PORT+3 powoduje przesunięcie i odczyt o fizycznie 12 bajtów dalej. Zajrzyj proszę do Bluebooka do wskaźników są fajne przykłady jak działa arytmetyka wskaźników.

    W drugim przypadku gdy już twój *WSK_PORTB jest typu uint8_t powinno być dobrze - ale widać że kod piszesz niedbale - bo na pewno zgłaszają ci się warningi - chociażby podczas operacji przypisania

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    albo może działasz w kocim Atmel Studio w którym masz wyłączone warningi - oczywiście to nie jest powodem błędu o którym piszesz może on leżeć gdzie indziej ale dobrze byłoby zobaczyć PORZĄDNY kod testowy i dowiedzieć się na czym to testujesz - bo skoro wysyłasz sobie wartość na PORTD to jak to odczytujesz - masz podłączone 8 diod LED ? Nie prościej albo wysyłać sobie wartość liczbową na UART albo podłączyć byle wyświetlacz LCD i wyświetlać sobie zamiast takie karkołomne testy robić

    Napisz tą drugą wersję kodu poprawnie i pokaż - ale tak, żeby żaden warning podczas kompilacji się nie pojawiał. Bo oczywiście druga wersja kodu powinna działać poprawnie - tu arytmetyka WSK_PORTB+3 zadziała zgodnie z twoim założeniem - na PORTD powinna być podana wartość czwartego bajtu zmiennej x

    _________________
    zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 5 sty 2022, o 18:55 
    Offline
    Nowy
    Avatar użytkownika

    Dołączył(a): 05 sty 2018
    Posty: 14
    Pomógł: 0

    Dzięki za szybką reakcję.
    mirekk36 napisał(a):
    W pierwszym przypadku gdy twój wskaźnik ma typ uint32_t robisz masakrę bo pominąłeś to jak działa arytmetyka wskaźników. Operacja WSK_PORT+3 powoduje przesunięcie i odczyt o fizycznie 12 bajtów dalej.

    OK, to pomyłka przy przepisywaniu. Miało być :
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    ale i tak nie działa dobrze. A ja chciałem wymusić przesuniecie się na ostatni bajt zmiennej uint32_t zmieniając typ wskaźnika. Taki mój pomysł. Warning podczas kompilacji oczywiście się pojawia dlatego powstał wątek, bo działa dobrze, ale jest warning.

    mirekk36 napisał(a):
    albo może działasz w kocim Atmel Studio


    Nie żadne Atmel Studio - 100% Mirku Twoja szkoła i sprzęt.

    mirekk36 napisał(a):
    Napisz tą drugą wersję kodu poprawnie i pokaż - ale tak, żeby żaden warning podczas kompilacji się nie pojawiał. Bo oczywiście druga wersja kodu powinna działać poprawnie - tu arytmetyka WSK_PORTB+3 zadziała zgodnie z twoim założeniem - na PORTD powinna być podana wartość czwartego bajtu zmiennej x


    Dobrze, ale rozumiem, że mam przyzwolenie na to, żeby stosować typ uint8 dla wskaźnika dla zmiennej uint32.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 5 sty 2022, o 19:20 
    Offline
    Moderator
    Avatar użytkownika

    Dołączył(a): 03 paź 2011
    Posty: 27366
    Lokalizacja: Szczecin
    Pomógł: 1043

    nowy_stary napisał(a):
    OK, to pomyłka przy przepisywaniu. Miało być :

    to i tak źle - przecież jeśli wskaźnik jest typu uint32_t to wsk+1 przesunie ci się fizycznie o 4 bajty rozumiesz ? o rozmiar typu - a typ uint32_t to 4 bajty

    _________________
    zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 5 sty 2022, o 19:44 
    Offline
    Nowy
    Avatar użytkownika

    Dołączył(a): 05 sty 2018
    Posty: 14
    Pomógł: 0

    Dokładnie tak. Wiem to od początku. Rozumiem rozkład bajtów itd. Dlatego zmieniłem typ wskaźnika żeby poruszać się co bajt, a nie tyle bajtów co wynika z typu wskaźnika zmiennej 4 bajtowej. Teraz tylko próbuję dociec czy używanie typu wskaźnika innego niż typ zmiennej, której wskaźnik dotyczy jest właściwe. Chyba nie bo eclipsik się buntuje wysyłając warning. Ale kurcze efekt jest prawidłowy po kompilacji. Chyba, że jest inny sposób na obejście tego, żeby używając wskaźnik zmiennej 4 bajtowej poruszać się w pamięci o jeden bajt. O to mi głównie chodzi.
    Przecież nie dodam do wskaźnika zmiennej 4 bajtowej 0,25 żeby znaleźć się na najmłodszym bajcie zmiennej :).



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 5 sty 2022, o 20:05 
    Offline
    Moderator
    Avatar użytkownika

    Dołączył(a): 03 paź 2011
    Posty: 27366
    Lokalizacja: Szczecin
    Pomógł: 1043

    nowy_stary napisał(a):
    eraz tylko próbuję dociec czy używanie typu wskaźnika innego niż typ zmiennej, której wskaźnik dotyczy jest właściwe. Chyba nie bo eclipsik się buntuje wysyłając warning.

    a co ma eclipsik który jest tylko zwykłym edytorem tekstu do kodu źródłowego w C ? NIC

    Warninga to masz od kompilatora i trzeba się go pozbyć robiąc jawne rzutowanie i o tym też było i jest w Bluebooku

    u ciebie musi być

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    ------------------------ [ Dodano po: kilkunastu sekundach ]

    nowy_stary napisał(a):
    Chyba, że jest inny sposób na obejście

    A po co obchodzić coś co się załatwia właśnie w ten sposób

    ------------------------ [ Dodano po: 1 minucie ]

    po to są właśnie wskaźniki


    Autor postu otrzymał pochwałę

    _________________
    zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 5 sty 2022, o 20:18 
    Offline
    Nowy
    Avatar użytkownika

    Dołączył(a): 05 sty 2018
    Posty: 14
    Pomógł: 0

    Dzięki zatrybiłem. Wystarczyło na początku napisać jawne... :)
    Tak od kompilatora.
    Jeszcze raz dzięki. Może ta dyskusja komuś też pomoże.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 6 sty 2022, o 11:02 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 29 lis 2019
    Posty: 145
    Pomógł: 37

    To co tu robisz ze wskaźnikiem ma swoją nazwę: strict aliasing violation. Efekt tych dziań jest nieokreślony (undefined behaviour). Dalej - arytmetyka wskaźników ma sens tylko w ramach jednej tablicy. NIE ma sensu w przypadku niezależnych zmiennych. Kolejne UB.
    Także, rozdział o wskaźnikach do powtórki.

    _________________
    Think for yourself and question authority.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    Wyświetl posty nie starsze niż:  Sortuj wg  
    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 9 ] 

    Strefa czasowa: UTC + 1


    Kto przegląda forum

    Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 4 gości


    Nie możesz rozpoczynać nowych wątków
    Nie możesz odpowiadać w wątkach
    Nie możesz edytować swoich postów
    Nie możesz usuwać swoich postów
    Nie możesz dodawać załączników

    Szukaj:
    Skocz do:  
    Sitemap
    Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
    phpBB SEO