Forum: Mikrocontroller und Digitale Elektronik Größe eines Arrays im Flash zur Compilezeit bestimmen


von J. L. (lindenbaum)


Lesenswert?

N'Abend,

ich grüble grad über der Fragestellung wie ich die Größe eines Arrays 
zur Compilezeit bestimmen kann.

Hintergrund ist, das ich einen Zeichensatz für ein Dot-Matrix-Display im 
Flash meines ATTiny2313 hinterlegt habe, welchen der "Endanwender" in 
gewissen Maßen frei erweitern dürfen soll. Dadurch würde sich natürlich 
auch die Größe des Arrays ändern. Da der Text der durch das Display 
läuft im Betrieb geändert werden können soll (und der gesamte 
Zeichensatz nutzbar sein soll), möchte ich ich gerne feststellen wann 
das letzte Zeichen erreicht wurde um wieder zum Ersten schalten zu 
können.

Klar könnte ich Sizeof verwenden, doch so wie ich das sehe wird dieses 
nicht zur Compilezeit / durch den Präprozessor ausgeführt, sondern 
während des laufenden Programms. Da 2 Kilobyte Speicher schnell 
erschöpft sind möchte ich mir eigentlich jeglichen unnötigen Code 
ersparen und Suche daher nach einer Variante die Größe durch den 
Präprozessor / Compiler ermitteln zu lassen.

Ist dies möglich? Wenn ja, wie gehe ich da vor?

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

char blahkeks[] = "dlkfjlkdslkfds";
Der Compiler hängt von selbst ein Nullbyte hinter den String und das 
erkennen alle Stringfunktionen als Ende des Strings.

von J. L. (lindenbaum)


Lesenswert?

Martin Wende schrieb:
> Nullbyte

Mein Zeichensatz kann leider Nullbytes enthalten, es ist ein Zeichensatz 
für ein 5x7-LED-Display.
Ein Zeichen besteht immer aus 5 Bytes, wobei im letzten Byte das 
"übrige" Bit (bei mir Bit 0) auf 1 gesetzt ist um das Ende eines 
Zeichens zu erkennen. Soll bei einem Zeichen jedoch mal eine komplette 
Spalte aus sein, ist das entsprechende Byte halt 0x00, entspricht also 
einem Nullbyte. Die Möglichkeit fällt also aus.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

J. L. schrieb:
> Ein Zeichen besteht immer aus 5 Bytes, wobei im letzten Byte das
> "übrige" Bit (bei mir Bit 0) auf 1 gesetzt ist um das Ende eines
> Zeichens zu erkennen.

Wenn ein Zeichen immer aus 5 Bytes besteht, wozu dann eine 
Endekennzeichnung?

von user (Gast)


Lesenswert?

also wenn die Länge bekannt ist wird sizeof rausoptimiert bei einem 
guten Compiler

von J. L. (lindenbaum)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Wenn ein Zeichen immer aus 5 Bytes besteht, wozu dann eine
> Endekennzeichnung?

Die "5-Byte-Regel" dient mehr oder minder nur der einfachen Berechnung 
der Startposition eines Zeichens im Array, soll ein Zeichen nun aber 
nicht die vollen 5 Spalten im Display ausfüllen, kann das Zeichen durch 
setzen des "Ende-Bit" frühzeitig beendet werden. Es nimmt dann keine 5 
Spalten ein, sondern eben nur die Spalten die es auch braucht.

von J. L. (lindenbaum)


Lesenswert?

user schrieb:
> also wenn die Länge bekannt ist wird sizeof rausoptimiert bei einem
> guten Compiler

hust

Der Einfachheit verwende ich den ICCAVR von Imagecraft, allerdings in 
der "Non-Commercial"-Testversion mit 4k Limitierung. Die Optimiert 
leider nix - bei Dingen dir mir unnötig Speicherfressend vorkommen 
schaue ich daher gern mal in das Assemblerlisting und baue entsprechend 
um. Für mich hat das ganze einfach den Vorteil das ich mich für 
verschiedene µC nicht an verschiedene IDE's gewöhnen muss (für MSP430er, 
Tiny11er, und 68HC11er).

von Bernhard S. (b_spitzer)


Lesenswert?

> Hintergrund ist, das ich einen Zeichensatz für ein Dot-Matrix-Display im
> Flash meines ATTiny2313 hinterlegt habe, welchen der "Endanwender" in
> gewissen Maßen frei erweitern dürfen soll.

Wie soll denn das gehen?? Der Anwender kann Teile des FLASH 
(=Programmspeicher) zur Laufzeit verändern? Wer programmiert den ersten 
Controller-Virus dafür????
Dafür braucht man ein EEPROM (I2C oder SPI oder intern, falls vorhanden 
und genügende Größe), in dem der Benutzer dann walten darf. Das Programm 
muss halt die Länge (Ende des Arrays) ebenfalls im EEPROM ablegen und 
entsprechend verändern, wenn Zeichen dazukommen.

von Kindergärtner (Gast)


Lesenswert?

J. L. schrieb:
> Klar könnte ich Sizeof verwenden, doch so wie ich das sehe wird dieses
> nicht zur Compilezeit / durch den Präprozessor ausgeführt, sondern
> während des laufenden Programms.
Quark. sizeof wird vom Compiler berechnet und gibt einfach nur die Größe 
des verwendeten Typs zurück, also eine Konstante. Auf dem AVR ist zB 
sizeof(int)=2, sizeof(char)=1, sizeof(char[5]=5) (die letzten beiden 
sogar überall). Wenn du sizeof(variablenname) schreibst wird daraus 
sizeof(typ) wobei typ der Typ der Variable ist. Der Inhalt der 
Variablen ist völlig egal. Arrays zählen hierbei auch als Variable.

Die übliche und einfachste Lösung ist zusätzlich zum Array noch ein 
Längen-Byte mit abzuspeichern, was die momentane Länge des Arrays 
angibt.

PS: Es gibt den GCC für den AVR und der kann Gerüchten zufolge ganz gut 
optimieren.

von Kindergärtner (Gast)


Lesenswert?

... oder meintest du dass der Benutzer den Programmcode selber verändert 
und die Länge des Arrays dem Compiler bekannt und konstant ist? Dann 
brauchst du lediglich sizeof().

von J. L. (lindenbaum)


Lesenswert?

Bernhard Spitzer schrieb:
> Wie soll denn das gehen?? Der Anwender kann Teile des FLASH
> (=Programmspeicher) zur Laufzeit verändern?

So war das nicht gemeint, der Zeichensatz wird natürlich nicht zur 
Laufzeit verändert, nur die Nachricht die angezeigt wird (die steht im 
EEPROM, genauso wie die Länge). Der Zeichensatz wird beim Flashen 
festgelegt. Ich will nur nicht jedesmal die "Länge" des Zeichensatzes 
neu definieren, sondern die Grenzen bzw. die Länge des Zeichensatzes 
automatisch durch den Präprozessor ermitteln und einpflegen lassen.

von Kindergärtner (Gast)


Lesenswert?

J. L. schrieb:
> Länge des Zeichensatzes
> automatisch durch den Präprozessor ermitteln und einpflegen lassen
Der Präprozessor kann das nicht. Der Compiler aber schon, mit sizeof():
1
const char charset [] =  { 1, 2, 3, 4, 5 };
2
int len = sizeof(charset); // ergibt 5.

von J. L. (lindenbaum)


Lesenswert?

Kindergärtner schrieb:
> oder meintest du dass der Benutzer den Programmcode selber verändert
> und die Länge des Arrays dem Compiler bekannt und konstant ist? Dann
> brauchst du lediglich sizeof().

Der Benutzer soll nicht den Code des Programms ändern, sondern nur neue 
"Zeichen" ins Array einpflegen - der Präprozessor soll dann halt die 
Grenzwerte meiner Vergleiche im Code entsprechend anpassen. Quasi die 
Defines ändern die ich bisher nutze, die aber fix sind.

Kindergärtner schrieb:
> Quark

Dann muss ich das heute früh nochmal testen, nach meinen letzten 
Beorbachtungen änderte sich die Menge des verbrauchten Speichers nicht 
unerheblich, weswegen ich davon ausging das "sizeof" zur Laufzeit 
ausgeführt wird.

Kindergärtner schrieb:
> sizeof(char)=1

(unsigned) Char ist exakt der Datentyp den ich verwende.

Kindergärtner schrieb:
> PS: Es gibt den GCC für den AVR und der kann Gerüchten zufolge ganz gut
> optimieren.

Schon, aber ich mag mein altmodisches Imagecraft Gezeugs :) Falls es 
wirklich nicht anders will, ändere ich den Kram notfalls von Hand. Auch 
wenn mir das nicht wirklich gefällt.

von J. L. (lindenbaum)


Lesenswert?

Verdammt, ich ziehe alles zurück - Asche auf mein Haupt. Keine Ahnung 
was ich da bei meinen letzten Versuchen verhackstückt habe, "sizeof" 
wird in der Tat durch eine Konstante ersetzt - es funktioniert 
einwandfrei ohne Änderung der Codegröße. Danke für die gegebenen 
Hinweise, sonst hätte ich das vermutlich nicht nochmal ausgetestet.

Ich gehe dann besser mal schlafen :-(

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.