Forum: Compiler & IDEs Compiler warning: cast from pointer to integer of different size


von Alexxx (Gast)


Lesenswert?

Hallo,

ich möchte eine Peripherie- oder Speicheradresse den Xmega-DMA 
Adressregistern mit einer Funktion zuweisen:

void InitDmaChannel(DMA_CH_t channel, register8_t *source, register8_t 
*destination, register16_t BlockCnt, register8_t TrigSrc, bool forever)
{
...
  channel.SRCADDR0= (uint8_t)(((uint32_t)source)>>0);
  channel.SRCADDR1= (uint8_t)(((uint32_t)source)>>8);
  channel.SRCADDR2= (uint8_t)(((uint32_t)source)>>16);
...
}

ebenso...

Bsp:
DMA.CH0.SRCADDR0= (((uint32_t)(&Buffer))>>0*8) & 0xFF;
DMA.CH0.SRCADDR1= (((uint32_t)(&Buffer))>>1*8) & 0xFF;
DMA.CH0.SRCADDR2= (((uint32_t)(&Buffer))>>2*8) & 0xFF;

Aber auch mit dem gefundenen Beispiel (s.o.) gibt der Compiler die 
Warnung aus: "cast from pointer to integer of different size"

- Wie kann man das elegant schreiben, ohne dass Warnungen produziert 
werden?
- Das mit dem "& 0xFF" kann man doch besser mit einem cast uint8_t() 
machen?
- Sind nicht einige Klammern überflüssig?

Alexxx

von Andreas B. (Gast)


Lesenswert?

Vielleicht uintptr_t statt uint32_t? Soweit ich das sehen kann, sind die 
Zeiger auf Xmega schließlich 24 und nicht 32 Bit breit. Die intptr_t und 
uintptr_t sind allerdings optional und deshalb nicht notwendigerweise 
definiert.

von (prx) A. K. (prx)


Lesenswert?

Unabhängig vom Problem kommt mir das komisch vor:
 DMA_CH_t channel
 channel.SRCADDR0= ...
denn damit modifizierst du einen struct Parameter, kein DMA-Register. 
Meinst du vielleicht
 DMA_CH_t *channel
 channel->SRCADDR0= ...

von (prx) A. K. (prx)


Lesenswert?

Zum Problem: Die Xmegas mögen wohl eine 24-Bit Datenadressierung 
beherrschen, aber ob das der GCC auch weiss? Ich vermute, dass der in 
alter AVR-Tradition auch bei den Xmegas Adressen nur 16-Bit breit 
versteht und ein Programmierer, der mehr als 64KB Datenadressen 
verwendet, ein Problem kriegt. Und daher vorsorglich darauf hingewiesen 
wird, dass ein Casten nach 32-Bit Integer einen Fehler enthalten könnte.

von Alexxx (Gast)


Lesenswert?

Für die internen Adressen (und deshalb für mich) reichen wirklich 16-Bit 
aus.
Der Xmega kann aber 16MB externen RAM ansprechen!
wie wäre es mit einem far-pointer?

Alexx

von (prx) A. K. (prx)


Lesenswert?

Alexxx schrieb:

> Der Xmega kann aber 16MB externen RAM ansprechen!
> wie wäre es mit einem far-pointer?

Soweit mir bekannt gibt es die im GCC nicht, d.h. nicht wirklich. GCC 
hat generell ziemliche Probleme, zwischen verschiedenen Sorten von 
Pointern (codespace, dataspace, short, near, far, ...) zu 
differenzieren.

Man kann daher mit Attributen zwar die Platzierung statischer Daten 
steuern, also riesige Arrays ins Flash oder einen erweiterten 
Datenadressraum legen, nicht aber Pointer so steuern, dass 
unterschiedlicher Code raus kommt. Siehe auch die Hacks und 
Laufzeitfunktionen statt Dereferenzierung für Daten im Flash.

Da landet man schlicht und einfach an den Grenzen des AVR-GCC.

von Alexxx (Gast)


Lesenswert?

@ A. K.:
Du hast natürlich recht!

@ Alle
PS: die Fehlermeldung ist tatsächlich weg, wenn man...

  channel->SRCADDR0= (uint8_t)(((uint16_t)source)>>0);
  channel->SRCADDR1= (uint8_t)(((uint16_t)source)>>8);
  channel->SRCADDR2= 0;

schreibt.

Danke für eure Hilfe.

von Olaf (Gast)


Lesenswert?

> wie wäre es mit einem far-pointer?

Der gcc kennt nur eine Sorte Pointer. Ob die nun 16, 24, oder 32Bit 
gross sind das koennte man beim implementieren des Codegenerators 
festlegen.

Die einfachste Loesung ist nun immer einen moeglichst grossen Pointer zu 
nehmen. Leider blaeht das aber den Code deutlich auf und macht ihn 
langsamer. Das will man also auch nicht.

Beim M16C wird das geloest indem nur 16Bit Pointer genutzt werden, und 
fuer Spruenge auf Funktionen eine Tabelle angelegt wird die dann 
ueberrall hin springen kann. Natuerlich auch nicht die beste Loesung.

Da ist es wohl ein Nachteil das der gcc hauptsaechlich fuer dicke CPUs 
entwickelt wird und man Microcontoller nicht so wichtig nimmt.

Olaf

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.