C Pointer schieben?

Gast #5539375
Lesenswert?

Kurze Frage zum Thema Pointer Arithmetik..
1
void    dmaSetSource          ( uint8_t channel , void* source )       {   CHANNEL(channel).SRCADDR0 = ( uintptr_t )  source & 0xff;   CHANNEL(channel).SRCADDR1 = ( ( uintptr_t )  source >> 8 ) & 0xff;   CHANNEL(channel).SRCADDR2 = ( ( uintptr_t ) source >> 16 ) & 0xff; }

Bei dem schieben von den Werten, bekomme ich ein Haufen Warnungen..
Wieso?
Moderator #5539400
Lesenswert?

Es wird kein Pointer geschoben, da source vorher nach uintptr_t
gecastet wird. Die Warnungen (wie auch immer die lauten) beziehen sich
also auf etwas anderes.

Edit: Einen Pointer zu schieben ist nicht erlaubt und ergäbe deswegen
keine Warning, sondern einen Error.
#5539407
Lesenswert?

Dergute W. schrieb:
>> Bei dem schieben von den Werten, bekomme ich ein Haufen Warnungen..
>> Wieso?
>
> Weil das dem compiler verdaechtig vorkommt.

Nicht nur dem Compiler ... ;-)

Bei C sind IIRC nur + und [] als Operatoren auf Pointer erlaubt.

Exotische Plattformen benutzen mitunter abweichende Pointer Formate, man 
denke beispielsweise an 16-bittiges DOS (8086), welches 32-Bit in 16 Bit 
Segment und 16 Bit Offset unterteilt. Damit wären Shifts nicht ohne 
weiteres möglich.

Bei bekanntem Pointer Verhalten des Compilers kann man auf den 
entsprechenden unsigned Typ casten, z.B. uint32_t für 32-Bit ARM.
Gast #5539421
Lesenswert?

warum castest Du nicht einfach zu Beginn zu einem Integer?

also z.B. size_t x=(size_t) source;

Und dann halt die Berechnungen, nachher cast zum Pointer und dann die 
Angabe der Fehlermeldungen hier.
Gast #5539440
Lesenswert?

Hier die Fehlermeldung
1
Severity  Code  Description  Project  File  Line
2
Warning    right shift count >= width of type [-Wshift-count-overflow]  DMA  c:\users\marcus\Documents\Atmel Studio\7.0\DMA\DMA\xmega_dma.c  69
Gast #5539455
Lesenswert?

Cyblord -. schrieb:
> Marcus schrieb:
>> Hier die Fehlermeldung
>>> Severity  Code  Description  Project  File  Line
>> Warning    right shift count >= width of type [-Wshift-count-overflow]
>> DMA  c:\users\marcus\Documents\Atmel Studio\7.0\DMA\DMA\xmega_dma.c  69
>>
> Ist doch eindeutig und verständlich wo das Problem liegt.
Weil es nur ein 16 Bit Typ ist?
Gast #5539485
Lesenswert?

Marcus schrieb:

>>> Warning    right shift count >= width of type [-Wshift-count-overflow]
>>> DMA  c:\users\marcus\Documents\Atmel Studio\7.0\DMA\DMA\xmega_dma.c  69

> Weil es nur ein 16 Bit Typ ist?

Nö, weil "right shift count >= width of type". Es spielt für diese 
Warnung keine Rolle, welcher Typ es genau ist, das einzige, was eine 
Rolle spielt: es wird so weit geschoben, dass immer nur 0 oder -1 
rauskommen kann.

Sprich: du kannst dir das Schieben sparen und im Falle eines unsigned 
Types einfach 0 zurückgeben, im Falle eines signed Types je nach 
Vorzeichen 0 oder -1.

Oder anders ausgedrückt: dein Code ist offensichtlicher logischer 
Schwachsinn, so offensichtlich, dass es sogar der Compiler bemerken 
kann, der logische Fehler normalerweise eher nicht aufspüren kann. Das 
ist allerdings auch nicht seine Aufgabe, der hat eigentlich nur die 
syntaktische Korrektheit zu prüfen, aber wenn's gerade abfällt, ist es 
doch nett von ihm, den unfähigen User auf seinen Fehler mit einer 
Warnung hinzuweisen, oder?
Moderator #5539512
Lesenswert?

Ich kenne mich mit den XMegas nicht gut aus. Trotzdem ein Versuch:

Falls du maximal 64k RAM in deinem System hast, kannst du SRCADDR2
einfach auf 0 setzen, und der Käse sollte gegessen sein:

1
CHANNEL(channel).SRCADDR2 = 0;

Falls du (inkl. externen Speicher) mehr als 64k RAM hast und du mit dem
DMA-Controller auch den Adressbereich >64k ansprechen willst, geht das
IMHO nicht mit normalen C-Pointern. Du müsstest dann source statt als
Poiunter als __uint24 oder uint32_t deklarieren und den Code, der
dmaSetSource aufruft, und ggf. noch weitere Programmteile entsprechend
anpassen.
Gast #5540237
Lesenswert?

Eine Frage hätte ich da noch..
1
void    dmsSetSourceChannel          ( uint8_t channel , uint32_t *source );
1
void    dmsSetSourceChannel                ( uint8_t channel , uint32_t *source )      
2
{
3
  CHANNEL(channel).SRCADDR0 = *source & 0xFF;
4
  CHANNEL(channel).SRCADDR1 = ( *source >> 8 ) & 0xFF;
5
  CHANNEL(channel).SRCADDR2 = ( *source >> 16) & 0xFF;
6
}

Ist es korrekt, dass "source" die Adresse übergibt oder aktuell ( so wie 
im Kode zu sehen ) den Inhalt?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren