Forum: Compiler & IDEs ATxmega: Warnung bei Adresse->Integer Wandlung für DMA


von Simon K. (simon) Benutzerseite


Lesenswert?

Hallo, vielleicht ist ja gerade ein GCC Crack am Start. Habe soeben den 
DMAC vom ATxmega ans laufen bekommen, allerdings stören mich da noch ein 
paar Fehlermeldungen.
Es geht darum eine Adresse in einen integralen Datentypen zu wandeln und 
auf die Art und Weise in 3 8-Bit-Stückchen zu zerhacken, damit man diese 
Adresse in das Adressregister der DMA laden kann.

Konkret handelt es sich um folgenden Code:
1
  EXTADC_TX_DMA.SRCADDR0 = (uint8_t) ( (uint32_t) ( (void*)ConvBytes ) >> 0 );
2
  EXTADC_TX_DMA.SRCADDR1 = (uint8_t) ( (uint32_t) ( (void*)ConvBytes ) >> 8 );
3
  EXTADC_TX_DMA.SRCADDR2 = (uint8_t) ( (uint32_t) ( (void*)ConvBytes ) >> 16 );
4
  EXTADC_TX_DMA.DESTADDR0
5
      = (uint8_t) ( (uint32_t) ( (void*)& ( EXTADC_UART.DATA ) ) >> 0 );
6
  EXTADC_TX_DMA.DESTADDR1
7
      = (uint8_t) ( (uint32_t) ( (void*)& ( EXTADC_UART.DATA ) ) >> 8 );
8
  EXTADC_TX_DMA.DESTADDR2
9
      = (uint8_t) ( (uint32_t) ( (void*)& ( EXTADC_UART.DATA ) ) >> 16 );

In jeder Zeile gibt es folgenden Fehler:
1
../ExtADC.c:113: warning: cast from pointer to integer of different size

Nunja, die Fehlermeldung kommt wohl, weil (void*) 16-Bit breit ist und 
uint32_t eben 32-Bit breit. Auch wenn ich hier kein Gefahrenpotenzial 
sehe, wird das als Warnung angegeben. Leider sehe ich aber auch keinen 
Weg drumherum, bzw. ich sehe gar nicht den Grund, warum der DMAC 
überhaupt 24-Bit Adressen braucht, wenn der GCC sowieso nur 16-Bit 
verwalten kann?

Eine zweite Stellungnahme wäre vielleicht interessant, danke schon mal 
im Voraus.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Simon K. wrote:
1
   EXTADC_TX_DMA.SRCADDR1 = (uint8_t) ( (uint32_t) ( (void*)ConvBytes )
2
>> 8 );

Nun, du machst aus irgendwas einen Zeiger, schiebst den dann aber um
8 Bits nach rechts, was ihn implizit zu einem Integer macht.

Funktioniert es denn so?
1
EXTADC_TX_DMA.SRCADDR1 = (uint8_t) ((uint32_t)(void*)ConvBytes ) >> 8);

Wobei ich mir gerade nicht sicher bin, ob der Cast nach void* nicht
ggf. die obersten 8 Bits abschneiden würde.

> ..., bzw. ich sehe gar nicht den Grund, warum der DMAC
> überhaupt 24-Bit Adressen braucht, wenn der GCC sowieso nur 16-Bit
> verwalten kann?

Der Xmega ist nun einmal nicht an den Limitierungen eines GCC konzipiert
worden. ;-)  Ich nehme mal an, dass das RAM-Adressen sind hier?  Der
Xmega kann ja wohl extern mehr als 64 KiB an RAM verwalten, auch wenn
der GCC dies nicht direkt (also in Form von Variablen) andressieren
kann.

von Simon K. (simon) Benutzerseite


Lesenswert?

Jörg Wunsch wrote:
> Simon K. wrote:
>
>
1
>    EXTADC_TX_DMA.SRCADDR1 = (uint8_t) ( (uint32_t) ( (void*)ConvBytes )
2
>>> 8 );
3
>
>
> Nun, du machst aus irgendwas einen Zeiger, schiebst den dann aber um
> 8 Bits nach rechts, was ihn implizit zu einem Integer macht.
>
> Funktioniert es denn so?
Vor dem Schieben wird doch der Zeiger wieder in einen uint32_t 
gewandelt. So funktioniert es, jep.

>
1
> EXTADC_TX_DMA.SRCADDR1 = (uint8_t) ((uint32_t)(void*)ConvBytes ) >> 8);
2
>
Brauch ich nun wirklich eine Brille oder ist das nicht genau das 
Gleiche, wie ich geschrieben habe, nur mit weniger Leerzeichen? :-)

> Der Xmega ist nun einmal nicht an den Limitierungen eines GCC konzipiert
> worden. ;-)  Ich nehme mal an, dass das RAM-Adressen sind hier?  Der
> Xmega kann ja wohl extern mehr als 64 KiB an RAM verwalten, auch wenn
> der GCC dies nicht direkt (also in Form von Variablen) andressieren
> kann.
Das heißt ja zwangsläufig, dass man bei Adressen > 64kiB da irgendwas 
zusammenfrickeln muss für das DMA-Adress-Highest-Byte. Hm.
Dann kann ich ja eigentlich auch direkt das DMA.SRCADDR2 Register auf 0 
setzen und den Zeiger statt in uint32_t in uint16_t wandeln. Dann kommt 
die Warnung nämlich nicht mehr ;)

Danke jedenfalls für deine Antwort.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Simon K. wrote:

> Brauch ich nun wirklich eine Brille oder ist das nicht genau das
> Gleiche, wie ich geschrieben habe, nur mit weniger Leerzeichen? :-)

Ich hätte nicht so früh am Morgen posten sollen. ;-)  Da ist noch ein
Klammerfehler drin, und wenn man den rausnimmt, ist es effektiv das
gleiche wie deins, ja.

von Helmut R. (heru01)


Lesenswert?

Hallo Simon, hallo Jörg,
in den Appnotes ist dieses Bsp. enthalten. Meldungen bei DMA und EBI.
Nun aber doch die Frage: ...und wie bekomme ich jetzt die Meldung weg? 
Ich weiss dass ich sie ignorieren kann, aber: kann ich eine Direktive 
setzen, die diese Meldung unterdrückt, in der Art:
1
#Meldung_aus
2
3
 EXTADC_TX_DMA.SRCADDR1 = (uint8_t) ( (uint32_t) ( (void*)ConvBytes )
4
>>> 8 );
5
6
#Meldung an

Gruß
Helmut

von Simon K. (simon) Benutzerseite


Lesenswert?

Welche Fehlermeldung genau? Die Fehlermeldung die ich dazu bekommen habe 
war, weil GCC 16Bit Pointer verwendet, ich aber das obere 2. Byte haben 
wollte. Was es bei 16Bit natürlich nicht gibt.
Sprich: Die Fehlermeldung kam bei mir nur in der Zeile mit SRCADDR2.
Setze das Register einfach auf 0, das sollte moralisch in Ordnung gehen 
:-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.