Frage

Ich muss Anweisungen speichern, Befehle, die ich über Serien empfangen werde. Die Befehle sind 8 Bit lang.

Ich muss die Transparenz zwischen dem Befehlsnamen und seinem Wert bewahren. Um zu vermeiden, eine 8-Bit-Nummer zu übersetzen, die in Serie in einen beliebigen Typ empfangen wird.

Ich würde gerne Aufzählungen verwenden, um mit ihnen in meinem Code umzugehen. Nur eine Aufzählung entspricht einem auf dieser Plattform eine 16 -Bit -Ganzzahl.

Die Plattform ist AVR ATMEGA169V Microcontroller auf der Butterfly Demo Board. Es ist ein 8 -Bit -System mit einer begrenzten Unterstützung für 16 -Bit -Operationen. Es ist kein schnelles System und hat ungefähr 1 KB RAM. Es gibt keinen Luxus wie Datei -E/O oder Betriebssysteme.

Also irgendwelche Vorschläge, welchen Typ ich verwenden sollte, um 8-Bit-Befehle zu speichern?
Es muss etwas Besseres geben als einen massiven Kopfball von #Defines.

War es hilfreich?

Lösung

gcc's -fshort-enums könnte nützlich sein:

Zuweisen Sie einem "Enum" -Typ nur so viele Bytes, wie er für den deklarierten Bereich möglicher Werte benötigt. Insbesondere entspricht der Typ "Enum" dem kleinsten Ganzzahl, der über genügend Platz verfügt.

In der Tat, hier'SA -Seite mit vielen relevanten Informationen. Ich hoffe, Sie stoßen auf viele GCC -Switches, von denen Sie nie wussten, dass sie existieren. ;))

Andere Tipps

Sie versuchen, ein Problem zu lösen, das nicht existiert.

Ihre Frage ist mit C. in C -Sprachumentypen im Wertkontext mit dem Tag mit den Integraltypen kompatibel und verhalten sich genauso wie andere integrale Typen. Wenn sie in Ausdrücken verwendet werden, sind sie genau dieselben integralen Werbeaktionen wie andere integrale Typen ausgesetzt. Sobald Sie dies berücksichtigen, sollten Sie erkennen, dass Sie nur einen geeigneten generischen 8-Bit-Integraltyp auswählen müssen (z. int8_t) und verwenden Sie es anstelle des Enum -Typs. Sie werden absolut nichts verlieren, indem Sie Ihre konstanten Werte für die konstanten Aufschwung in einem Objekt vom Typ speichern int8_t (im Gegensatz zu einem Objekt, das ausdrücklich mit dem Enumentyp deklariert wurde).

Das von Ihnen beschriebene Problem würde in C ++ bestehen, wo die Enumtypen viel weiter von anderen integralen Typen getrennt sind. In C ++ ist es schwieriger (zwar möglich), in C ++ einen Integraltyp anstelle des Enum -Typs zu verwenden. Aber nicht in C, wo es keinerlei zusätzliche Anstrengungen erfordert.

Ich verstehe nicht, warum eine Aufzählung nicht funktionieren würde. Vergleiche mit und Zuordnungen von einem Enum sollten alle mit der Standardweiterung gut funktionieren. Achten Sie nur darauf, dass Ihre 8 -Bit -Werte korrekt signiert sind (ich würde denken, Sie würden eine unsignierte Erweiterung wünschen).

Auf diese Weise erhalten Sie 16-Bit-Vergleiche. Ich hoffe, dass dies kein Leistungsproblem sein wird (es sollte nicht sein, insbesondere wenn Ihr Prozessor 16-Bit ist, wie es sich so anhört).

Mit dem C -Compiler von Microsoft können Sie so etwas tun, aber es handelt sich um eine Erweiterung (es ist Standard in C ++ 0x):

enum Foo : unsigned char {
    blah = 0,
    blargh = 1
};

Da Sie mit GCC mitgewiesen sind, bin ich mir nicht ganz sicher, ob dasselbe möglich ist, aber GCC könnte eine Erweiterung in haben gnu99 Modus oder etwas dafür. Wirbel.

Ich würde empfehlen, auf jeden Fall aus folgenden Gründen auf Enum zu bleiben:

  • Mit dieser Lösung können Sie Befehlswerte direkt auf das abbilden, was Ihr serielles Protokoll erwartet.
  • Wenn Sie wirklich 16-Bit-Architektur verwenden, gibt es nicht so eine große Anzahl von Vorteilen, um auf 8-Bit-Typ zu wechseln. Denken Sie über Aspekte nach, als 1 Speicher Byte gespeichert ist.
  • Bei einigen Compilern verwendete ich die tatsächliche Umlaufgröße, die minimale Anzahl von Bits verwendet hat (Umzahlen, die nur in Byte eingesetzt werden könnten, das nur Byte verwendet, dann 16 Bit, dann 32).

Zuerst sollten Sie sich nicht um die echte Typbreite kümmern. Nur wenn Sie wirklich eine effektive Speichermethode benötigen, sollten Sie Compiler -Flags wie -fshort -Enums auf dem GNU -Compiler verwenden, aber ich empfehle sie nicht, es sei denn, Sie benötigen sie wirklich.

Als letzte Option können Sie "Enum" als Präsentationsdaten für die Befehle definieren und die Konvertierung zu BYTE mit 2 einfachen Operationen verwenden, um den Befehlswert für / aus dem Speicher zu speichern / wiederherzustellen (und dies an einem Ort zu verkörpern). Was ist damit? Dies sind sehr einfache Vorgänge, sodass Sie sie sogar einfügen können (dies ermöglicht Ihnen jedoch, nur 1 Byte für die Speicherung und von der anderen Seite zu verwenden, um Operationen mit dem am häufigsten definierten Gebrauch zu erledigen.

Antwort, die relevant ist für ARC -Compiler (Zitiert aus Designware Metaware C/C ++ - Programmierhandbuch für ARC; Abschnitt 11.2.9.2)

Größe der Aufzählungen Die Größe eines Enumentyps hängt vom Status des Umschusses ab *long_enums *.

■ Wenn umschaltet * long_enums * ausgeschaltet ist, sind die Karten des Enum -Typs bis zum kleinsten von einem, zwei oder vier Bytes, so dass alle Werte dargestellt werden können.

■ Wenn umschaltet * long_enums * ist eingeschaltet, ein Enum -Karten zu vier Bytes (entspricht der AT & T -tragbaren C -Compiler -Konvention).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top