Forum: Mikrocontroller und Digitale Elektronik C Pointer schieben?


von Marcus (Gast)


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?

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Marcus schrieb:
> Bei dem schieben von den Werten, bekomme ich ein Haufen Warnungen..
> Wieso?

Weil das dem compiler verdaechtig vorkommt.

Gruss
WK

von Marcus (Gast)


Lesenswert?

Kann ich das Fasten?

von Marcus (Gast)


Lesenswert?

Sorry..
Ich meinte ob ich das irgendwie weg casten kann...?

von Dergute W. (derguteweka)


Lesenswert?

Sicher

von René H. (Gast)


Lesenswert?

Willst du wirklich den Pointer verändern oder den Teil worauf er zeigt?

Grüsse,
René

von Marcus (Gast)


Lesenswert?

René H. schrieb:
> Willst du wirklich den Pointer verändern oder den Teil worauf er
> zeigt?
>
> Grüsse,
> René
So wie es da steht.

von Yalu X. (yalu) (Moderator)


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.

von Marcus (Gast)


Lesenswert?

Wenn ich den Teil auskommentiere sind die Fehlermeldungen bzw. Warnungen 
weg.
Es hat eindeutig damit was zu tun!

von Jim M. (turboj)


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.

von Jim M. (turboj)


Lesenswert?

Marcus schrieb:
> Wenn ich den Teil auskommentiere sind die Fehlermeldungen bzw. Warnungen
> weg.
> Es hat eindeutig damit was zu tun!

Dann zeige uns doch mal den kompletten Source (Anhang als .c Datei) und 
die kompletten Fehlermeldungen / Warnings. Ansonsten wird das ein 
heiteres Ratespiel.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Marcus schrieb:
> Wenn ich den Teil auskommentiere sind die Fehlermeldungen bzw. Warnungen
> weg.
> Es hat eindeutig damit was zu tun!

Es hat etwas mit diesen Codzeilen zu tun, aber nicht mit dem Schieben
eines Pointers.

Vielleicht magst du uns ja den Wortlaut der Warnungen verraten :)

von Marcus (Gast)


Lesenswert?

Der Code stammt aus einem C++ Projekt.
Der Datentyp zu den gecastet wird ist ein 16  Bit Typ, müsste also mit 
uint16_t funktionieren.  Richtig?

von Marcus (Gast)


Lesenswert?

Yalu X. schrieb:
> Vielleicht magst du uns ja den Wortlaut der Warnungen verraten :)

Okay.. Dauert einen kleinen Moment..

von Dergute W. (derguteweka)


Lesenswert?

Yalu X. schrieb:
> Vielleicht magst du uns ja den Wortlaut der Warnungen verraten :)

Doch noch nicht auf der ersten Seite des Threads. Wo bleibt denn die 
ganze Vorfreude?

SCNR,
WK

von A. S. (Gast)


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.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Marcus schrieb:
> Yalu X. schrieb:
>> Vielleicht magst du uns ja den Wortlaut der Warnungen verraten :)
>
> Okay.. Dauert einen kleinen Moment..

Die Definition von CHANNEL() (vermutlich ein Makro) wäre ebenfalls von
Interesse.

von Marcus (Gast)


Lesenswert?

Hier schon mal das Makro..
1
#define CHANNEL(channel)          ( ( ( DMA_CH_t * ) &DMA.CH0 )[channel])

Rest folgt...

von Marcus (Gast)


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

von Cyblord -. (cyblord)


Lesenswert?

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

Ist doch eindeutig und verständlich wo das Problem liegt.

von Marcus (Gast)


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?

von Markus F. (mfro)


Lesenswert?

Kann es sein, dass Du (warum auch immer) ein Programm, das ursprünglich 
für eine Maschine mit 32- (oder 24-) Bit-Adressen geschrieben wurde, 
auf/für eine(r) 16-Bit-Plattform übersetzen willst?

von c-hater (Gast)


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?

von Joe F. (easylife)


Lesenswert?

Lass mal das casten auf uintptr_t weg.
Also
1
void dmaSetSource (uint8_t channel , void *source)
2
{   
3
  CHANNEL(channel).SRCADDR0 =  source        & 0xff;
4
  CHANNEL(channel).SRCADDR1 = (source >>  8) & 0xff;
5
  CHANNEL(channel).SRCADDR2 = (source >> 16) & 0xff; 
6
}

von Yalu X. (yalu) (Moderator)


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.

von Ron C. (Gast)


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?

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.