Forum: Compiler & IDEs Datentypen / Übergabewerte Funktionen


von Gregor S. (chiefmic)


Lesenswert?

Hallo,

ich bin momentan dabei vom Keil 8051-C51 auf AVR-GCC (Atmel Studio 6) 
umzusteigen. Hierbei durfte ich feststellen, dass GCC einige Datentypen, 
die es in C51 von Keil gibt, nicht kennt. So schlagen in C51 
einwandfreie Funktionsdefinitionen wie z.B.

"unsigned char i2c_get(bit ack)"

gnadenlos fehl da Datentyp "bit" bei GCC unbekannt.

Nachdem ich einiges zum Thema gelesen haben, glaube ich verstanden zu 
haben, dass GCC auf einem AVR(mega) letztendlich nur mit Bytes umgehen 
kann. Zugriff auf Bits ist nur über Bitfelder (mit entsprechend höherem 
Rechenaufwand für die Rangierung in Bytes) möglich.

Bedeutet dies dann, dass die "kleinste" Möglichkeit betreffend 
Ram-Verbrauch wie folgt aussieht ??

"unsigned char i2c_get(unsigned char ack)"
bzw:
"uint8_t i2c_get(uint8_t ack)"

Hier müsste ich dann Rückgabewerte für True/False in meiner Funktion 
festlegen und im weiteren Programm entsprechend auswerten ??


Danke und Grüße
Gregor

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Gregor S. schrieb:
> Hallo,
>
> ich bin momentan dabei vom Keil 8051-C51 auf AVR-GCC (Atmel Studio 6)
> umzusteigen. Hierbei durfte ich feststellen, dass GCC einige Datentypen,
> die es in C51 von Keil gibt, nicht kennt. So schlagen in C51
> einwandfreie Funktionsdefinitionen wie z.B.
>
> "unsigned char i2c_get(bit ack)"
>
> gnadenlos fehl da Datentyp "bit" bei GCC unbekannt.

Das könnte damit zusammenhängen, daß gcc ein C-Compiler ist ;-)

Tipp: "bit" ist kein Schlüsselwort in C.

Oder erwartest du, daß GCC ungültigen Code akzeptiert? (Vorausgesetzt, 
bit ist weder C-konformes Makro noch Typedef etc.)

> Nachdem ich einiges zum Thema gelesen haben, glaube ich verstanden zu
> haben, dass GCC auf einem AVR(mega) letztendlich nur mit Bytes umgehen

Es genügt zu wissen, daß avr-gcc ein C-Compiler ist.

Füttere ihn also mit einem C-Programm.

> kann. Zugriff auf Bits ist nur über Bitfelder (mit entsprechend höherem
> Rechenaufwand für die Rangierung in Bytes) möglich.
>
> Bedeutet dies dann, dass die "kleinste" Möglichkeit betreffend
> Ram-Verbrauch wie folgt aussieht ??
>
> "unsigned char i2c_get(unsigned char ack)"

Das verbraucht überhaupt kein RAM weil achk nicht im RAM übergeben 
wird.

> "uint8_t i2c_get(uint8_t ack)"

Verbraucht auch kein RAM, weil der return-Wert nicht im RAM übergeben 
wird.

> Hier müsste ich dann Rückgabewerte für True/False in meiner Funktion
> festlegen und im weiteren Programm entsprechend auswerten ??

Wenn du einen Bool'schen Wert brauchst, nimmst zu zB stdbool.h

von Rolf Magnus (Gast)


Lesenswert?

Gregor S. schrieb:
> "unsigned char i2c_get(unsigned char ack)"
> bzw:
> "uint8_t i2c_get(uint8_t ack)"

Ich würde vorschlagen:
1
uint8_t i2c_get(bool ack)
nach einem
1
#include <stdbool.h>

von Michl (Gast)


Lesenswert?

Johann L. schrieb:
> Das verbraucht überhaupt kein RAM weil achk nicht im RAM übergeben
> wird.


> Verbraucht auch kein RAM, weil der return-Wert nicht im RAM übergeben
> wird.


Klugscheiß: Spielst du hier darauf an dass der Wert auf dem Stack 
übergeben wird? Der Stack liegt, zumindest bei mir, auch im RAM.

Du hast natürlich recht, den statischen Verbrauch erhöht das nicht. Nur 
hart an der Grenze des freien RAMs darf man sich nicht bewegen :-)

Ansonsten hat Rolf Magnus natürlich recht.

von Peter II (Gast)


Lesenswert?

Michl schrieb:
> Klugscheiß: Spielst du hier darauf an dass der Wert auf dem Stack
> übergeben wird? Der Stack liegt, zumindest bei mir, auch im RAM.

nein rückgabe werte werden sogar nur im Register übergeben, auch bei 
wenigen parameter wird nur mit Registern gearbeitet also wirkich kein 
Ram.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Peter II schrieb:
> nein rückgabe werte werden sogar nur im Register übergeben

Wenn sie reinpassen und der Compiler das so vorsieht. Muss aber nicht so 
sein, was soll beispielsweise geschehen, wenn der Rückgabewert ein 
uint64_t ist? Oder eine noch größere Struktur?

von (prx) A. K. (prx)


Lesenswert?

Rufus Τ. Firefly schrieb:
> sein, was soll beispielsweise geschehen, wenn der Rückgabewert ein
> uint64_t ist?

Dann sind es 2. Aber irgendwann ist es Speicher, das stimmt schon.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

A. K. schrieb:
> Dann sind es 2

Der Threadstarter nutzt 8-Bit-Systeme, da sind es dann 8 Register.

von Checker-Bunny (Gast)


Lesenswert?

Ist lange her, dass ich mit dem Keil C51 gearBytet habe.

Bist du sicher, dass "bit" und Konsorten nicht in irgendeiner Keil 
Headerdatei definiert sind?
Wie schon gesagt wurde, das ist kein elementarer C-Datentyp.

von Checker-Bunny (Gast)


Lesenswert?

... tatsächlich ...
Habe ein bischen gegoogelt und ein C51 User Manual gefunden.
http://www.keil.com/support/man/docs/c51/c51_le_bit.htm

Im Kapitel "Language Extensions" ist der Datentyp "bit" beschrieben. 
Dieses Kapitel solltest du dir mal zu Gemüte führen. Es beschreibt die 
Abweichungen vom C Standard.

von Rolf Magnus (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> A. K. schrieb:
>> Dann sind es 2
>
> Der Threadstarter nutzt 8-Bit-Systeme, da sind es dann 8 Register.

Ja, also 1/4 der Register des AVR. Prozentual immer noch weniger als 
beim PC ;-)

von Klaus F. (kfalser)


Lesenswert?

Gregor S. schrieb:
> Zugriff auf Bits ist nur über Bitfelder (mit entsprechend höherem
> Rechenaufwand für die Rangierung in Bytes) möglich.

Der Rechenaufwand ist (abgesehen von irgendwelchen Optimierungen, die 
der eine oder andere Compiler besser macht), der selbe.
Auch ein Keil Compiler kann einer Funktion kein einzelnes Bit übergeben, 
weil der Prozessor mit 8 bit breiten Daten arbeitet.
Er kann den Aufwand nur besser (aber nicht C-Konform) vor Dir 
verstecken.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Klaus Falser schrieb:
> Auch ein Keil Compiler kann einer Funktion kein einzelnes Bit übergeben,
> weil der Prozessor mit 8 bit breiten Daten arbeitet.

Sowohl MCS-51 als auch AVR bieten auf Assemblerebene direkte 
Bitzugriffe, die im Falle des Keil-Compilers mit nichtportierbaren 
Klimmzügen als C-Konstrukt abgebildet werden.

Die Bitzugriffe des AVR sind einer der Gründe, warum die Bitkonstanten, 
die für Registerbeschreibungen verwendet werden, Bitnummern und nicht 
Bitwertigkeiten sind, was wiederum der Grund für die bei 
AVR-Programmierern so beliebten Schiebe-und-OR-Orgien zur 
Bitwertbestimmung sind.

Bei andere Systemen, wie z.B. MSP430, werden Bitkonstanten als 
Bitwertigkeit definiert, so daß im Code nur OR-verknüpfte Konstanten 
auftauchen.

von Rolf Magnus (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Klaus Falser schrieb:
>> Auch ein Keil Compiler kann einer Funktion kein einzelnes Bit übergeben,
>> weil der Prozessor mit 8 bit breiten Daten arbeitet.
>
> Sowohl MCS-51 als auch AVR bieten auf Assemblerebene direkte
> Bitzugriffe, die im Falle des Keil-Compilers mit nichtportierbaren
> Klimmzügen als C-Konstrukt abgebildet werden.

Das hat aber nichts mit der Frage zu tun, ob und wie man ein Bit einzeln 
als Parameter an eine Funktion übergeben kann. Die Bitzugriffe, von 
denen du sprichst, bekommen auch ein ganzes Register übergeben.

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.