PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Flag - Speicherplatz sparen



Ali_Baba
24.02.2009, 09:39
Hallo,

in meinem Programm brauche ich einige Variable, die nur den Wert 1 oder 0 speichern müssen.

Wie programmiert man so etwas speichersparend?

Die Variable Char oder Short Int braucht mindestens ein ganzes Byte; ich muß aber nicht pro Variable 256 verschiedene Möglichkeiten speichern, sondern nur zwei.

Kann mir jemand bitte weiterhelfen?

Ali_Baba

CsT
24.02.2009, 09:49
Die Lösung findest du hier (http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Bitfelder). Dort ist genau dein Problem angesprochen .. die Lösung: Bitfelder.

Grüße Tobi

Ali_Baba
24.02.2009, 10:34
Herzlichen Dank!! :-)

SprinterSB
24.02.2009, 12:27
Falls es um avr-gcc geht: Den Code, den der für Bitfelder produziert, ist monströs. Um ein paar Bytes RAM zu sparen, wird man nich den Code dermassen aufblähen wollen, wie der avr-gcc das (noch) für Bitfelder tun.

Eine Alternative ist Bitfummelei mit Masken, die aber zugegebenermassen nicht schon zu lesen ist. Über Makros kann man das etwas schönschminken.

Wie auch immer: Ob Bitfelder oder Bitgefummel; um zB ein einziges Bit zu setzen braucht man mindestens 10 Bytes an Programmspeicher, bei Bitfeldern eher doppelt so viele. Von der Laufzeit dafür ganz zu schweigen.

Einige neue AVR-Derivate haben GPIOR-Register, die man zur freien Verfügung hat. Auf einem ATmega*8 zum Beispiel liegt GPIOR0 im Bit-adressierbaren SFR-Bereich.

Dieses Register ist damit optimal prädestiniert, um Flags darin unterzubringen: Setzen bzw. Rücksetzen kosten jeweils 2 Byte und 2 Ticks, und ein Abtesten 4 Bytes.

Weiterer Vortail: Die Zugriffe sind atomar, d.h. man kann die Flags zur Kommunikation zwischen ISRs und Anwendung hernehmen, ohne beim Setzen/Rücksetzen ständig die IRQs deaktivieren/reaktivieren zu müssen. In dem Fall spart das weitere kostbare Zeit und Speicherplatz.

Zum Schreiben eines solchen Flags sollten immer 0 bzw. 1 verwendet werden, um den besten und atomaren Code zu bekommen, auch wenn's etwas mehr hinzutexten ist:



#define FLAGS GPIOR0

// gut
if (x)
FLAGS |= (1 << 3);
else
FLAGS &= ~(1 << 3);

// schlecht:
FLAGS = (FLAGS & ~(1 << 3)) | ((x & 1) << 3);