Forum: Mikrocontroller und Digitale Elektronik C-cast der besonderen Art MSP430


von Dietmar S. (dsausw)


Lesenswert?

Moin,
ich habe zu einem Experimenterboard von TI eine Demo-SW,
in der eine Code-Stelle ist, die mir etwas verwirrend vorkommt:
1
DMA0DA = (void (*)())MemstartTest;

DMA0DA ist ein DMA-Register
In der controllerspezifischen Headerdatei definiert:
SFR_20BIT(DMA0DA);    /* DMA Channel 0 Destination Address */
vom Typ __SFR_FARPTR
MemstartTest ist ein fixer Wert:
1
#define MemstartTest      0x40000
Was soll jetzt dieses cast-Konstrukt void (*)() ?

Besten Dank schon einmal

Dietmar

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dietmar Sch. schrieb:
> vom Typ __SFR_FARPTR

Und wie sieht dieser Typ aus?

Und wie das Macro SFR_20BIT?

von nicht"Gast" (Gast)


Lesenswert?

Moin,

das komische Ding biegt die Adresse auf einen Funktionszeiger um.

Welchen Sinn das an der Stelle hat, kann dir nur die Doku zu SFR_20BIT() 
sagen.


Grüße,

von Dietmar S. (dsausw)


Lesenswert?

Ne watt schnell-
Die Definition aus der Headerdatei
//#define SFR_20BIT(address)  extern volatile unsigned int address
typedef void (* __SFR_FARPTR)();
#define SFR_20BIT(address) extern __SFR_FARPTR address

von Dietmar S. (dsausw)


Lesenswert?

Vielleicht eine wichtige Zusatzinfo:
Nicht nur, das ich das nicht verstehe ;-) /
es gibt auch einen Fehler:
#173-D invalid type conversion
Die SW muss aber einmal gelaufen sein-
sie ist aber von 2009 mit einem TI C-compiler
übersetzt worden.

von Karl H. (kbuchegg)


Lesenswert?

Dietmar Sch. schrieb:
> Vielleicht eine wichtige Zusatzinfo:
> Nicht nur, das ich das nicht verstehe ;-) /

Wie schon gesagt: das ist ein Funktionspointer.

> es gibt auch einen Fehler:
> #173-D invalid type conversion

Das wird wohl der __SFR_FARPTR sein. Der Name suggeriert bereits, dass 
es sich dabei wohl nicht um einen normalen Pointer (wohl 16 Bit) 
handelt, sondern um einen Pointer, der 24 Bit umfasst.

Der
1
#define MemstartTest      0x40000
passt da auch dazu, weil die Zahl für einen 16 Bit Wert zu gross ist.

Wenn da nicht irgendeine besondere Absicht dahinter steckt, dann hätte 
der Cast überhaupt nie so geschrieben werden sollen. Ändere das mal um 
auf
1
DMA0DA = (__SFR_FARPTR)MemstartTest;


Und besorg dir ein C Buch und lies über Funktionspointer nach. Wer 
Computer programmieren will, sollte seine Programmiersprache kennen! 
Auch wenn ich durchaus zugestehe, dass Funktionspointer nicht tägliches 
Brot sind.

: Bearbeitet durch User
von Dietmar S. (dsausw)


Lesenswert?

Was bisher geschah ;-)
Ich gehöre tatsächlich zu den stolzen Besitzern mehrerer
Bücher über C- ja auch den K&R.
Zum Thema:
Ich habe mittlerweile herausgefunden, das TI die Art:
2.2.2 Assigning a Pointer to a location greater than 0xFFFF
In CCEv3:
  DMA0DA = (void (*)())MemstartTest;
In IAR:
  __data16_write_addr((unsigned short)&DMA0DA, MemstartTest );
im CCE (Vorläufer des CCS) empfiehlt.
Heute ist die Version vom IAR präferiert.
1
DMA0DA = (__SFR_FARPTR)MemstartTest;
ergibt auch eine "invalid type conversion"

Trotzdem besten Dank für die Belehrung

von Bernd K. (prof7bit)


Lesenswert?


von Gunther Mannigel (Gast)


Lesenswert?

Ja, das (void (*)()) soll wohl wirklich nur einen 20-Bit-Zeigerwert 
erzeugen.
Das kannst Du auch im Headerfile sehen.
Ich habe in meinen Quellen DMA0DAL mit einem 16-Bit-Wert beschrieben. 
Das funktioniert genau so gut, solange der zu schreibende Wert in 16 Bit 
passt.

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.