Forum: Mikrocontroller und Digitale Elektronik C - Casting Verständniss Problem


von Marcus (Gast)


Lesenswert?

Was mache ich falsch? Bin gerade fast am heulen kopf gegen wand
1
void foo( void *dest )
2
{
3
  DMA.CH0.DESTADDR0 = (uint8_t)(((uint32_t) dest) & 0xFF);
4
  DMA.CH0.DESTADDR1 = (uint8_t)(((uint32_t) dest >> 8) & 0xFF);
5
  DMA.CH0.DESTADDR2 = (uint8_t)(((uint32_t) dest >> 16) & 0xFF);
6
}
Wenn ich versuche das zu kompilieren, kommt immer ein warning. 
Wahrscheinlich zu Recht..
1
Severity  Code  Description  Project  File  Line
2
Warning    cast from pointer to integer of different size [-Wpointer-to-int-cast]  XMEGA DMA  c:\users\marcus\Documents\Atmel Studio\7.0\XMEGA DMA\XMEGA DMA\main.c  14

von STK500-Besitzer (Gast)


Lesenswert?

bei deinen Shifts fehlt ein * (Stern)

von Marcus (Gast)


Lesenswert?

Ganz sicher???

von Jim M. (turboj)


Lesenswert?

Xmega hat IIRC nur 16-bittige Pointer..?

Versuche mal die uint32_t durch uintptr_t zu ersetzen.

von Jim M. (turboj)


Lesenswert?

STK500-Besitzer schrieb:
> bei deinen Shifts fehlt ein * (Stern)

Nö. Er versucht auf der Adresse zu rechenen.

von Sam W. (sam_w)


Lesenswert?

Das sieht doch eher so aus, als würde bewusst mit den Adressen 
gearbeitet, auf die "dest" zeigt.
Eventuell liegt es einfach daran, dass Zeiger (soweit ich weiß, bitte 
berichtigt mich sonst) normalerweise die Breite der Systemarchitektur 
aufweisen und die kleiner als 32 Bit ist.

Gruß
Sam

von Reiner_Gast (Gast)


Lesenswert?

Marcus schrieb:
> Was mache ich falsch?

Hier mal schauen, lesen, verstehen:

https://www.tutorials.at/c/11-zeiger.html

von Marcus (Gast)


Lesenswert?

Jim M. schrieb:
> Xmega hat IIRC nur 16-bittige Pointer..?
>
> Versuche mal die uint32_t durch uintptr_t zu ersetzen.

Das sieht schon besser aus.
1
{
2
  DMA.CH0.DESTADDR0 = (uint8_t)((uintptr_t) dest) & 0xFF;
3
  DMA.CH0.DESTADDR1 = (uint8_t)((uintptr_t) dest >> 8) & 0xFF;
4
  DMA.CH0.DESTADDR2 = (uint8_t)((uintptr_t) dest >> 16UL) & 0xFF;
5
}

Wenn der XMEGA nur 16 Bittige Zeiger hat, wieso gibt es dann das 
Register "DESTADDR2" ?
Es kommt jedoch jetzt immer noch eine Warnung. Ist ja auch verständlich. 
Er meckert das dass schieben überläuft..

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Auf was für einem System entwickelst du? 32 oder 64 bit?

Kannst du mal ausgeben was die Größe des void Pointers ist?
1
sizeof(void*)

Evtl. liegt da der Hund begraben.

von Marcus (Gast)


Lesenswert?

Tobias B. schrieb:
> Auf was für einem System entwickelst du? 32 oder 64 bit?
>
> Kannst du mal ausgeben was die Größe des void Pointers ist?
> sizeof(void*)
> Evtl. liegt da der Hund begraben.

Das ist für nen XMEGA, schreibe den Source in C. Kann die Größe jetzt 
leider nicht ausgeben. Mein Rechner ist jedoch ein 64 Bit. Aber das 
sollte damit doch nichts zu tun haben?

von foobar (Gast)


Lesenswert?

Dein Problem ist, dass du DMA-Adressen und C-Pointer mischt. Bei einigen 
CPU-Architekturen sind die nicht identisch. Die XMEGA haben (bei deinem 
Compiler) 16-Bit C-Pointer aber 24-Bit DMA-Adressen. Mach dir eine 
Hilfsfunktion, die von C-Ptr nach DMA-Adresse umwandelt - im trivialen 
Fall ist das ein Cast, bei einigen Architekturen ist aber mehr nötig 
(Adressoffsets, etc) ...
1
typedef uint32_t dmaaddr_t;
2
#define cptr2dma(cptr) ((dmaaddr_t)(uintptr_t)(cptr))
3
4
...
5
{
6
  dmaaddr_t addr = cptr2dma(dest);
7
8
  DMA.CH0.DESTADDR0 = addr;
9
  DMA.CH0.DESTADDR1 = addr >> 8;
10
  DMA.CH0.DESTADDR2 = addr >> 16;
11
}

von Marcus (Gast)


Lesenswert?

foobar schrieb:
> Dein Problem ist, dass du DMA-Adressen und C-Pointer mischt. Bei
> einigen
> CPU-Architekturen sind die nicht identisch. Die XMEGA haben (bei deinem
> Compiler) 16-Bit C-Pointer aber 24-Bit DMA-Adressen. Mach dir eine
> Hilfsfunktion, die von C-Ptr nach DMA-Adresse umwandelt - im trivialen
> Fall ist das ein Cast, bei einigen Architekturen ist aber mehr nötig
> (Adressoffsets, etc) ...
> typedef uint32_t dmaaddr_t;
> #define cptr2dma(cptr) ((dmaaddr_t)(uintptr_t)(cptr))
>
> ...
> {
>   dmaaddr_t addr = cptr2dma(dest);
>
>   DMA.CH0.DESTADDR0 = addr;
>   DMA.CH0.DESTADDR1 = addr >> 8;
>   DMA.CH0.DESTADDR2 = addr >> 16;
> }

Ich habe mir das hier abgesehen..
/*
 * DMAController.cpp
 *
 *  Created on: 16.01.2013
 *      Author: Nicolas Göddel
 *
 * 
https://www.mikrocontroller.net/articles/Speicherdirektzugriff_(DMA)_mit_dem_ATxmega#DMAController.cpp
 */

von René H. (Gast)


Lesenswert?

Hi Marcus,

bist noch nicht viel weiter gekommen. Weshalb aber ein neuer Thread?

Vielleicht solltest Du beschreiben was du machen willst.

Grüsse,
René

von Marcus (Gast)


Lesenswert?

René H. schrieb:
> Hi Marcus,
>
> bist noch nicht viel weiter gekommen. Weshalb aber ein neuer Thread?
>
> Vielleicht solltest Du beschreiben was du machen willst.
>
> Grüsse,
> René

Hi Rene,

ich versuche ( einen Post über deinen (link) ) die C++ Bibliothek in C 
zu schreiben.

von Marcus (Gast)


Lesenswert?

foobar schrieb:
> typedef uint32_t dmaaddr_t;
> #define cptr2dma(cptr) ((dmaaddr_t)(uintptr_t)(cptr))
>
> ...
> {
>   dmaaddr_t addr = cptr2dma(dest);
>
>   DMA.CH0.DESTADDR0 = addr;
>   DMA.CH0.DESTADDR1 = addr >> 8;
>   DMA.CH0.DESTADDR2 = addr >> 16;
> }

Das sieht gut aus. Keine Warnings mehr.
Und jetzt steht dort auch die Adresse der Variablen drin oder deren 
Inhalt?

von René H. (Gast)


Lesenswert?

Marcus schrieb:
> foobar schrieb:
>> typedef uint32_t dmaaddr_t;
>> #define cptr2dma(cptr) ((dmaaddr_t)(uintptr_t)(cptr))
>>
>> ...
>> {
>>   dmaaddr_t addr = cptr2dma(dest);
>>
>>   DMA.CH0.DESTADDR0 = addr;
>>   DMA.CH0.DESTADDR1 = addr >> 8;
>>   DMA.CH0.DESTADDR2 = addr >> 16;
>> }
>
> Das sieht gut aus. Keine Warnings mehr.
> Und jetzt steht dort auch die Adresse der Variablen drin oder deren
> Inhalt?

Die Adresse.

Grüsse,
René

von Marcus (Gast)


Lesenswert?

>> Das sieht gut aus. Keine Warnings mehr.
>> Und jetzt steht dort auch die Adresse der Variablen drin oder deren
>> Inhalt?
>
> Die Adresse.
>
> Grüsse,
> René

Das mit dem Makro ist echt ne klasse Idee ;) Besten dank!

von Marcus (Gast)


Lesenswert?

Habe das gerade mal auf dem Rechner ausprobiert.
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <stdint.h>
4
#include <stdbool.h>
5
6
typedef uint32_t dmaaddr_t;
7
#define CPTR2DMA(cptr) ((dmaaddr_t)(uintptr_t)(cptr))
8
9
void foo( void *dest )
10
{
11
  printf( "%d\r\n" , CPTR2DMA( dest ) & 0xFF );
12
  printf( "%d\r\n" , ( CPTR2DMA( dest ) >> 8 ) & 0xFF );
13
        printf( "%d\r\n" , ( CPTR2DMA( dest ) >> 16 ) & 0xFF );
14
        printf( "%d\r\n" , ( CPTR2DMA( dest ) >> 32 ) & 0xFF );
15
}
16
17
18
int main(int argc, char *argv[]) 
19
{
20
  uint32_t test;
21
  
22
  foo( &test );
23
  
24
  printf( "Adresse: %d" , &test );
25
  
26
  return 0;
27
}

Wenn ich mit "printf" die ganze Adresse ausgeben möchte, kommt für mich 
eine richtige Adresse raus.

Wenn ich jedoch die Variable der Funktion "foo()" übergebe und das 
zerlege, kommt was ganz anderes raus?!

von foobar (Gast)


Lesenswert?

> Wenn ich jedoch die Variable der Funktion "foo()" übergebe und
> das zerlege, kommt was ganz anderes raus?!

Der letzte Shift ist falsch (muss >>24 sein, nicht >>32). Und mit %x 
statt %d fällt das Vergleichen leichter ...

von Marcus (Gast)


Lesenswert?

foobar schrieb:
>> Wenn ich jedoch die Variable der Funktion "foo()" übergebe und
>> das zerlege, kommt was ganz anderes raus?!
>
> Der letzte Shift ist falsch (muss >>24 sein, nicht >>32). Und mit %x
> statt %d fällt das Vergleichen leichter ...

Klasse!
1
void foo( void *dest )
2
{
3
  dmaaddr_t addr = CPTR2DMA( dest );
4
  
5
  printf( "%x\r\n" , (addr & 0x000000FF) >> 0  );
6
  printf( "%x\r\n" , (addr & 0x0000FF00) >> 8  );
7
  printf( "%x\r\n" , (addr & 0x00FF0000) >> 16 );
8
  printf( "%x\r\n" , (addr & 0xFF000000) >> 24 );
9
}
10
11
12
int main(int argc, char *argv[]) 
13
{
14
  uint32_t test;
15
  
16
  foo( &test );
17
  
18
  printf( "Adresse: %x" , &test );
19
  
20
  return 0;
21
}
Jetzt haut es hin ;)

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.