Problem z odwolywaniem sie do struktury. (kod na avr)

0

Witam
Podczas czytania książki natrafiłem na pewien fragment kodu, wygląda on następująco .
Dodam,ze kod jest pisany na avr.

#include<avr/io.h>

#define _PORTB ( *(volatile IO*) &PORTB)     //wlasnie tego polecenia nie rozumiem

int main(void)
{
DDRB=0xFF;
PORTB=0xFF;

typedef struct 
{
 unsigned int b0;
 unsigned int b1;
 unsigned int b2;
 unsigned int b3;
 unsigned int b4;
 unsigned int b5;
 unsigned int b6;
 unsigned int b7;
} IO ;

_PORTB.b0=0;
_PORTB.b1=1;
_PORTB.b2=0;
}

Nie moge niestety zrozumieć jak działa poniższy fragment kodu

#define _PORTB ( *(volatile IO*) &PORTB)

wiem jak działa #define, wiem co oznacza volatile, jednak nie mogę zrozumieć całosci.
byłbym bardzo wdzięczny gdyby ktoś mógł mi to wytłumaczyć(postarać się powoli przeanalizować), oraz pokazać jakiś najprostszy przykład w klasycznym C na zastosowanie podobnej sztuczki.

usunięcie zbędnych pustych linii z kodu - fp

1

A to rozumiesz?

#define A (&PORTB)
#define B ((volatile IO*)A)
#define _PORTB *B
  1. Wyciagniecie adresu PORTB
  2. Rzutowanie go na typ IO* ze modyfikatorem volatile
  3. Wyciagniecie obiektu spod tego adresu.

Co do zastosowania to po prostu upychasz obiekt na okreslony adres i tyle.

0

Dziękuje, zrozumiałem, aczkolwiek chyba nie do końca ponieważ nie mogę tego zastosować na najprostszym przykładzie.

 
#include <stdio.h>
#include <stdlib.h>

#define  X (&A)
#define  Z  ((volatile C*) X)
#define  odwolanie *Z

int main(int argc, char *argv[]) {

	typedef struct 
	{
	int   C1,C2,C3;
	} C ;

	typedef struct  
       {
        int	A1,A2,A3;
	} A ;

odwolanie.C1=0;      // w tej lini sygnalizowany jest błąd

	return 0;
}

przy próbie kompilacji wyświetla sie następujący błąd :

[Error] expected expression before 'A'

niestety nie mam pojęcia co zepsułem :(

0

Nie wiadomo czym jest A + Takie mazanie po pamieci nie jest bezpieczne, chyba ze wiesz gdzie mazesz.

Okej, my bad... Nie zauwazylem tego A. Wiec A jest nazwa typu u Ciebie w kodzie. Stworz obiekt tego typu i z niego wyciagaj adres.

0

Wydaje mi się, ze mógłbym się sprzeczać, A jest obiektem, a typ nie posiada nazwy (jest to tzw struktura anonimowa).
a zatem odwołuje się do adresu konkretnego obiektu - obiektu A.

Próbowałem już osobno definiować strukture ( już nie anonimowa) i osobno tworzyć obiekt tej struktury - to również nie pomaga...

0

Chcesz to sie sprzeczaj, mi to rybka :P

#include <stdio.h>
#include <stdlib.h>
 
#define  X (&a)
#define  Z  ((volatile C*) X)
#define  odwolanie (*Z)

int main(int argc, char *argv[]) {
 
    typedef struct 
    {
        int C1,C2,C3;
    } C ;
    
    typedef struct  
    {
        int A1,A2,A3;
    } A ;
    
    A a;
    odwolanie.C1=123;
    printf("%d", odwolanie.C1);
    
    return 0;
}

BTW. Zmien kurs/ksiazke czy z czego tam sie uczysz. Zaoszczedzisz sobie klopotow na przyszlosc.

0

ze strukturami miałem do czynienia w C++; w C uczę się ich dopiero teraz i rzeczywiście w tym moim kursie popisali głupoty...
dzięki za pomoc ;)

1

@Sylwek91 mylisz dwie różne konstrukcje. Otóż gdybyś miał tu

struct {
  /cośtam
} A;

To struktura faktycznie byłaby anonimowa i byłby jeden obiekt tego typu o nazwie A.
Ale masz tu zupełnie inną konstrukcję, mianowicie:

typedef typ nowa_nazwa_typu;

W efekcie u ciebie A staje się nazwą typu a żadnego obiektu nie ma. To jest taka śmieszna konstrkcja żeby nie trzeba było wszędzie pisać "struct X" tylko samo "X".

0

@Sylwek91 nie pisz mi na prv ;)

możesz mi jeszcze powiedzieć, dlaczego w tym pierwszym programie ( w tym na avr)
nie musiałem tworzyć obiektu ?

Okej, w tym pierwszym kodzie wyciagales adres zmiennej PORTB, ktora prawdopodobnie jest zdefiniowana w <avr/io.h>, wiec juz miales odpowiedni obiekt, zeby wyciagnac jego adres. Natomiast w drugim kodzie definiowales wlasny typ, i chciales wyciagnac adres typu - co nawet brzmi absurdalnie. Po zdefiniowaniu obiektu, mozna bylo dopiero wyciagnac adres tego obiektu.

0

rozjaśnia się mi coraz więcej ;p

powiedzcie mi jeszcze na koniec
gdy piszę

 
#define A (&PORTB)
#define B ((volatile IO*)A)    //  tutaj wykonuje rzutowanie, a zatem mogę rzutować na coś co nie posiada adresu ?
#define _PORTB *B
  
0

Nie rozumiem pytania. Chodzi ci o to czy mógłbyś rzutować jakieś "A" które nie jest wskaźnikiem?

0

Pytanie było głupie, trochę poczytałem i sam sobie odpowiedziałem :)
jeszcze raz dziękuje wam za pomoc

1 użytkowników online, w tym zalogowanych: 0, gości: 1