Forum: Compiler & IDEs Speicherökonomie AT Mega128


von John S. (student)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

zum allgemeinen Verständnis für meine Frage habe ich Euch ein ScreenShot 
meines aktuellen Projektes angehängt.

Worum geht es?

Ich betreibe eine LGB-Eisenbahn, die ich mit üCs steuere. Dabei kommt in 
jede Lok (15+!) ein üC mit Funk-Receiver. Der üC in der Lok steuert den 
gesamten elektrischen Verbrauch der Lok in Abhängigkeit der Fahrbefehle 
... Rest dürfte klar sein.

Auch das Streckenbild (Weichen, Signale, ect.) steuere ich über (einen 
oder mehrere üCs). Das ganze funktioniert im Prototypenstadium schon 
wunderbar.
Weichen werden alle schon üC (funkgesteuert), eine Lok fährt ebenfalls 
(mit allen Funktionen - einschliesslich selbst An - und Abkuppeln und 
sonstigen Spässen) über Funk.

Warum mache ich das ? - Ganz einfach:
Ich will die Loks nicht über die digitalen, käuflichen Schienen 
Protokolle (z.B. DCC) steuern, sondern über Funk, das eröffnet eine ganz 
andere Dimension der Programmierungsmöglichkeiten.

Im übrigen erspare ich mir die teuere BoosterTechnologie, um die Signale 
auf die Schiene aufzumodulieren - und ich habe einen vollwertigen 
Rückkanal, dass heisst, die Lok sagt mir, wieviel Strom sie verbraucht, 
wie die Spannung am Gleis ist und die Loks kommunizieren untereinander 
im gekuppelten Verbund und teilen sich selbst mit, wie die Zuglast 
untereinander verteilt werden soll ...und und und. Und ich kann 10 Loks 
hintereinander fahren lassen (30 Ampere ... - das schafft kein Booster 
mehr ...)

Nun bastele ich mir gerade einen "Handregler" (natürlich mit 
Funkreceiver) zur Steuerung der Anlage - ist wirklich noch Prototyp - 
(bitte keine Kommentare zum Design ... - habe momentan dafür keine Zeit 
- kommt zum Schluss des Projektes)!

Ihr seht im Screenshot, dass ich einen Ausschnitt der Anlage als 
Gleisbild im Screen (1) habe. Mit einem Cursor (roter Kreis)  "fahre" 
ich über das Bild (2), wähle z.B. eine  Weiche (3) an ... und die Weiche 
schaltet ... und im Display springt der Richtungspfeil der Weiche um 
(kommt als nächstes)!

Dieses Gleisbild braucht ca. 23 KB, die momentan im Flash meines Mega128 
liegen und durch GCC initial mit dem Programm geladen werden. Ich möchte 
aber nun ca. 10 solcher Bilder laden (die Anlage ist insgesamt grösser). 
Wenn der Cursor an den Rand der Anlage kommt (rote Gleisendung), soll 
das nächste, fortsetzende Gleisbild nachgeladen werden ... und das 
natürlich so fix wie möglich (1/10 Sekunde ???)

Ich werde eine SD - Karte mit den vorbereiteten Gleisbildern 
anschliessen .. das steht schon fest. Nun die Gretchenfrage: Lade ich 
zuerst von der Karte ins Flash (im Hintergrund), ... oder direkt auf den 
Bildschirm ? Wie schnell funzt das ? Hat jemand Erfahrungswerte ? Die 
Frage mag trivial klingen .. ich habe aber noch einige andere Sachen im 
Hinterkopf - deshalb wichtig für mich. Übrigends: Gleisbild vom Flash 
auf den Screen geht in weniger als 1/10 Sekunde. Ziehen des Cursors (mit 
Bildrefresh an der Stelle, wo der Corsor vorher stand, geht absolut 
smooth - ohne dass man nur ein Bildzucken erkennt.)

Habe ich vielleicht sonst etwas Grundlegendes vergessen ? Any hints are 
appreciated.

Ach ja: Die gesamten Interrupts, Timer, UART Kommunikation, ADCs,  ... 
alles klappt hervorragend ... Dank dieses Forums - vielen herzlichen 
Dank. Ohne Euch wäre ich in Jahren noch nicht da, wo ich jetzt stehe.

Grüsse












 - ich optimiere nun, d.h. stelle nun alles auf AVRs um.

von die ??? (Gast)


Lesenswert?

Charly Grosse wrote:
> Nun die Gretchenfrage: Lade ich zuerst von der Karte ins Flash (im
> Hintergrund), ... oder direkt auf den Bildschirm ?

Vor diese Frage wirst du garnicht gestellt. Der Flash ist ROM.

  AVR-Tutorial: Speicher

von Jojo S. (Gast)


Lesenswert?

Speichereffizienter ginge es vielleicht die Map in Form von 'Token' 
abzulegen. Jedes mögliche Symbol wird als Byte definiert und der 
Bildschirm dann als 2x2 Array dieser Token abgelegt. Im Flash müssten 
dann alle möglichen Token liegen und ein Interpreter muß das Bild daraus 
rendern. Und auf PC Seite bräuchte man einen Editor um die Bilder 
bequemer erstellen zu können.

von John S. (student)


Lesenswert?

die ??? wrote:
> Charly Grosse wrote:
>> Nun die Gretchenfrage: Lade ich zuerst von der Karte ins Flash (im
>> Hintergrund), ... oder direkt auf den Bildschirm ?
>
> Vor diese Frage wirst du garnicht gestellt. Der Flash ist ROM.
>
>   AVR-Tutorial: Speicher


http://www.mikrocontroller.net/articles/MMC/SD_Bootloader_f%C3%BCr_AT_Mega

Man kann übrigends sehr wohl ins Flash laden, wenn die Prozeduren im 
Boot Sector stehen ...!

Meine Frage hat also wohl Berechtigung, sorry.

Trotzdem - Danke - bin für jeden Hinweis dankbar.

Grüsse

von John S. (student)


Lesenswert?

Johannes Stratmann wrote:
> Speichereffizienter ginge es vielleicht die Map in Form von 'Token'
> abzulegen. Jedes mögliche Symbol wird als Byte definiert und der
> Bildschirm dann als 2x2 Array dieser Token abgelegt. Im Flash müssten
> dann alle möglichen Token liegen und ein Interpreter muß das Bild daraus
> rendern. Und auf PC Seite bräuchte man einen Editor um die Bilder
> bequemer erstellen zu können.

Hallo, vielen Dank für Deine Antwort -

Du hast grundsätzlich Recht, so werde ich es machen, wenn ich z.B. das 
Symbol für die Weichenrichtung ändere. Ich lade mir dann nur das 
"getoggelte Symbol" an die entsprechende Stelle. Ich habe allerdings vor 
mir zu jedem Gleisplanausschnitt ein zweites Map zu generieren, welches 
jeweils alle toggelbaren Punkte genau invertiert zeigt. Das macht die 
Sache dann total simpel, ich brauche nur die gleiche Speicherposition in 
der getoggelten "Bank" (im Flash) anzusprechen und schon "switcht" die 
Weiche auf dem Display ...! 2*25 KB wären dann also immer im Flash.

Aber trotzdem, wenn ich mir den Aufwand gering halten möchte und die 
kompletten Maps aus dem PC möglichst 1:1 übernehmen möchte - (ich denke 
dabei auch an Veränderungen der Gleisführung, die ich möglichst mit 
minimalem Aufand im Controller nachziehen möchte ...!), dann sollte ich 
erst einmal das Timing  über das Nachladen einer kompletten Map von der 
Karte (entweder über den Umweg Flash) oder direkt in den Speicher 
klären. Flash wäre natürlich besser, die Geschwindigkeit kenne ich ja 
schon (beim Read), wenn ich die Map auf den Bildschrim bringe. Mich 
interessiert aber mehr die Zeit das Lesens (2* 25KB) von der Karte und 
das Schreiben ins Flash.

Die Frage bleibt für mich also aktuell.

Nur am Rande: wenn ich die Streckenführung ändere (und die geänderte MAP 
im Controller habe), schalte ich den Controller auf Lernmodus, klicke 
die neuen Weichen oder Signalpositionen auf dem Display mit dem Cursor 
an und geben eine Nummer für die Weiche oder das Signal ein. Damit ist 
dann auch die Nummer im Telegramm geändert und die richtige Weiche 
schaltet ...!

Aus diesem Grunde ist es empfehlenswert, mit kompletten Layouts aus dem 
PC zu arbeiten ... und nachzuladen , anders als sich das Bild aus 
Sympolen im Controller mit Berechnung aufzubauen! Bin halt faul - will 
später auch einmal mit der Bahn spielen ... und nicht immer nur 
programmieren.

Grüsse

von die ??? (Gast)


Lesenswert?

Charly Grosse wrote:
> Man kann übrigends sehr wohl ins Flash laden, wenn die Prozeduren im Boot
> Sector stehen ...!

Achso, du möchtest beim scrollen immer booten. Ja dann...

von John S. (student)


Lesenswert?

die ??? wrote:
> Charly Grosse wrote:
>> Man kann übrigends sehr wohl ins Flash laden, wenn die Prozeduren im Boot
>> Sector stehen ...!
>
> Achso, du möchtest beim scrollen immer booten. Ja dann...

... nee, möchte ich nicht. Ich dachte, ich bin in der Lage, im 
Bootsector eine  Routine abzulegen, die Daten von der SD einliest und im 
ROM ablegt. Die Routine (so denke ich - aber vielleicht geht das ja 
nicht ???) sollte aus dem normalen Programm aufrufbar sein. Aber ich 
gebe zu, ich habe mich mit dem Bootsector überhaupt nicht 
auseinandergesetzt.

Aus Deiner Antwort entnehme ich, dass man aus dem normal ablaufenden 
Programm nicht im Bootsector eine Funktion aufrufen kann?

Grüsse

von Sebba (Gast)


Lesenswert?

SChön das euer Hauptziel schon wieder ist euch gegenseitig zu sagen wie 
doof ihr seid...

So wie ich das grad im mega32 Datenblatt lese:
"Entering the Boot Loader takes place by a jump or call from the 
application program. This may be initiated by a trigger such as a 
command received via USART, or SPI interface"

Kann man also ganz einfach die BLS aus dem Programm anspringen um an 
beliebiger Stelle nachzuladen...

Allerdings gibt es einen anderen ganz einfachen Grund dies nicht zutun.
Auch hier mal ein Datenblatt Zitat:
"– Write/Erase Cycles: 10,000 Flash"

Klar ist das nur ein Richtwert - und dazu ein recht hoher - aber bei 
täglich 2 Std Eisenbahn spielen und alle 10 Sek ein neues Segment laden 
==>
10.000 / ((2*60*60) / 10) = 13,bla
hättest du also fast 2 Wochen Spass

Wie siehts denn mit nem externen RAM aus?

Schöne Grüße, Sven

von Rolf Magnus (Gast)


Lesenswert?

> Du hast grundsätzlich Recht, so werde ich es machen, wenn ich z.B. das
> Symbol für die Weichenrichtung ändere.

Warum nicht immer? Dann ist das Bild evtl. klein genug, um auch ins RAM 
zu passen.

> Aber trotzdem, wenn ich mir den Aufwand gering halten möchte und die
> kompletten Maps aus dem PC möglichst 1:1 übernehmen möchte - (ich denke
> dabei auch an Veränderungen der Gleisführung, die ich möglichst mit
> minimalem Aufand im Controller nachziehen möchte ...!),

Das bliebe ja dann so einfach wie zuvor.

> Mich interessiert aber mehr die Zeit das Lesens (2* 25KB) von der Karte

Die würde sich auch deutlich verkürzen.

> und das Schreiben ins Flash.

Das würde durch RAM-Zugriffe ersetzt, die viel schneller sind.
Laut Datenblatt dauert das Löschen und Neubeschreiben einer Flash-Page 
von 256 Bytes zwischen 3,7 und 4,5 Millisekunden. 25 kB zu schreiben 
dauert dann so ca 0,4 Sekunden, was alleine schon deutlich über der 
geforderten Zehntelsekunde liegt.

> Aus diesem Grunde ist es empfehlenswert, mit kompletten Layouts aus dem
> PC zu arbeiten ... und nachzuladen , anders als sich das Bild aus
> Sympolen im Controller mit Berechnung aufzubauen!

Ich verstehe nicht, wo hier der Unterschied sein soll. Wenn du aber bei 
kompletten Bildern bleiben willst, würde ich auch externes RAM 
empfehlen. Der Mega128 hat ein Speicherinterface mit 64 kB Adressraum. 
Da passen dann auch deine 2*25 kB rein, und du hast keine Probleme wegen 
Schreibzeiten und Lebensdauer.

>  Bin halt faul - will später auch einmal mit der Bahn spielen ... und
> nicht immer nur programmieren.

Dafür hast du aber doch schon ein ziemlich großes Projekt aufgezogen ;-)

von Malte _. (malte) Benutzerseite


Lesenswert?

Von dem ständigem Neuanlegen im Flash rate ich ab, wegen der langen 
Programmierzeit und den begrenzten Schreibzyklen. Wenn du einen externen 
RAM hast, nimm diesen. Ansonsten schlage ich auch die Symbolmethode vor. 
Oder alternativ eine einfache Längenkompremierung des Bitmaps, die 
dürfte bei den großen weißen Flächen recht effektiv sein, nur die auf 
pixelebene basierte Umdrehung ist dann recht kompliziert.

PS: Ziemlich aufwändiges Projekt.

von John S. (student)


Lesenswert?

Hallo,

Danke für die vielen Tips.

Ich habe mich (vorerst) entschieden, die Farbtiefe der Gifs von 256 auf 
4 zu reduzieren (unter Nutzung von Farbpaletten).
Damit komme ich auf ca. 5KB pro Bild. Die lade ich mir beim 
Programmieren ins Flash. Die Optimierung kommt dann später ... 
vielleicht wechsele ich auch einfacheitshalber direkt auf einen 256er . 
Man muss ja immer den Aufwand und den Preis in Relation sehen.

Nun aber noch einmal, warum ich die Bilder 1:1 ins Flash holen möchte:

Das Bild ist unsichtbar gerastert (auf dem PC sichtbar). Die 
Gleissymbole sind mit einem Gleisplanungsprogramm erstellt worden. Somit 
liegt jedes Symbol an einer definierten Stelle im Diplay (9*13)er 
Raster. Ich kann nun (ohne Umrechnungsaufwand) schnell den ProgrammCode 
erstellen, der über die Cursorposition die Mitte der Rasterzelle 
ermittelt (ohne Kompressionsrückrechnung etc.) Somit kann ich wahlfrei 
eine Zelle im Display "switchen". Würde ich Kompression nutzen, müsste 
ich von der (0,0) Zelle erst die Kompression auf die Zelle (x,y) 
rückrechenen. Den Aufwand will ich auf die Schnelle nicht. Vielleicht 
später einmal, wenn Langeweile aufkommt ...!

Bei einer 4 Farben Darstellung bilde ich jetzt nur noch die Schienen 1:1 
ab und die Symbole (Signal, Weiche, etc.) werde ich im "Lernmodus" an 
die entsprechende Rasterstelle "kleben". Die Position speichere ich dann 
im EEPROM ab. Umgekehrt: Bildaufbau der Gleise über Flash, Symbole mit 
Position aus EEPROM an die Stelle laden.

Übrigends: Das einzige Freeware Proggi, das wirklich auf GIF 
Farbtabellen beliebiger (minimaler) Anzahl Farben speichern kann, ist 
GIMP.
IrvanView zählt zwar die Farben, zeigt auch 4 an, speichert aber 
mindestens 16 Farben in der Farbtabelle. Paint.Net auch nicht besser ..! 
Das hat mich heute Nacht 6 Stunden gekostet, um dieses Problem zu lösen. 
So'n Mist.

Nun muss ich aber die Routinen umschreiben, die das Gleisabbild auf das 
Display bringen - wg. geänderter Farbtabellen.

Vielen Dank noch mal und Grüsse

von Rolf (Gast)


Lesenswert?

Ich würde eine SD Karte nehmen und dort die Bilder ablegen.
Das ist doch ein D072 board von Display3000 oder?  Dann hast du ja auch 
die Windowssoftware zum Grafikkomprimieren und die 
Dekomprimierungsroutinen in C oder Bascom. Ein solcher Gleisplan kann 
als GIF sicherlich um 90% komprimiert werden - da max. 256 Farben(oder 
weniger) und du bist bei vielleicht 2 KByte pro Grafik. Davon kannst du 
in einen Atmega128 haufenweise ablegen.

Oder als bin-Dateien (bereits mit dem GLCD_Convert vorbereitet) auf die 
SD Karte legen, dann kannst du den Gleisplan jederzeit ändern, ohne die 
Software neu anfassen zu müssen.

Das Lesen von einer SD Karte und das gleichzeitige ! Schreiben auf dem 
Display geht nicht, da beide die SPI Schnittstelle nutzen. Also musst du 
die Daten von der SD Karte blockweise einlesen (z.B. immer 1000-2000 
Pixel) und im RAM zwischenspeichern, dann den RAM Block dekomprimieren 
und auf das Display senden - dann weiter lesen usw. Wenn du ein 
Display3000 Board mit einen Atmega2561 hast, dann hast du ja auch 8 
Kbyte RAM - damit kannst du solche Bilder immer locker in einem Rutsch 
einlesen und auf das Display schicken, aber in diesem Fall hier sollte 
selbst ein Atmega128 mit ausreichen - notfalls eben in 2 Schüben 
einlesen und senden.

Rolf

von Rolf (Gast)


Lesenswert?

ups, zu langsam.... da hat doch Charly schon gepostet während ich 
geschrieben habe.

von Karl H. (kbuchegg)


Lesenswert?

Charly Grosse wrote:

> Ich habe mich (vorerst) entschieden, die Farbtiefe der Gifs von 256 auf
> 4 zu reduzieren (unter Nutzung von Farbpaletten).
> Damit komme ich auf ca. 5KB pro Bild.

Immer noch zu viel.
Dein Beispiel lässt sich in ein paar Zig-Bytes codieren.



> Die
> Gleissymbole sind mit einem Gleisplanungsprogramm erstellt worden.

Macht ja nichts. Du musst dich nur von der Vorstellung trennen,
dass ein Gleiplan ein Bild darstellt. Ein Gleisplan kann ja auch
eine Anleitung sein, wie aus den Primitivsymbolen das Bild zu
entstehen hat. Wahrscheinlich arbeitet dein Gleiplanungsprogramm
genau nach diesem Muster. Eigentlich ist es sogar sehr wahrscheinlich,
dass es genau nach diesem Muster arbeitet.

Dein Texteditor speichert ja auch kein Bild eines Textes, sondern
für jeden Buchstaben einen Code. Erst bei der Anzeige wird für
jeden Code eine kleine Bitmap angezeigt, die den Buchstaben
darstellt. Der Vorteil davon: Durch Austauschen der Bitmaps kann
man einen ganz anderen Font für denselben Text benutzen

> liegt jedes Symbol an einer definierten Stelle im Diplay (9*13)er
> Raster. Ich kann nun (ohne Umrechnungsaufwand) schnell den ProgrammCode
> erstellen, der über die Cursorposition die Mitte der Rasterzelle
> ermittelt (ohne Kompressionsrückrechnung etc.) Somit kann ich wahlfrei
> eine Zelle im Display "switchen".

Das könntest du auch so. Du musst dich nur auf eine einhetliche
Zellgröße einigen und dann deine Cursorposition durch die Zellgröße
dividieren. Schon hast du das Symbol in deiner Matrix, welches
manipuliert werden muss.

> Würde ich Kompression nutzen, müsste
> ich von der (0,0) Zelle erst die Kompression auf die Zelle (x,y)
> rückrechenen. Den Aufwand will ich auf die Schnelle nicht. Vielleicht
> später einmal, wenn Langeweile aufkommt ...!

Vergiss Kompression.
Hier geht es nicht um Bildkompression! Hier geht es darum, dass
dein Gleisplan zb so aussieht:

00 00 00 01 02 02 02 ....
00 00 00 03 00 00 00 ....

Und der Code 01 bedeutet zb. Kurve von senkrecht nach wagrecht, von
untenkommend nach rechts. In deinem Bild also:


                     *****
                    *
                   *
                  *

Während der Code 02 ein waagrechtes Gleis darstellt


                  *********

Die Kombination 01 02 wird dann als Bild abgebildet


                   ****************
                  *
                 *
                *

Im Grunde definierst du dir deinen eigenen 'Font', der bestimmt
welchem Code welches Bildchen entspricht und bei der Ausgabe eine
entsprechende Ersetzung macht. Eine Weiche umstellen ist dann ganz
einfach den entsprechenden Code gegen einen anderen Code austauschen
und dir Renderfunktion aufrufen.

von Rolf (Gast)


Lesenswert?

Jo, KH Buchegger zeigt die perfekte Variante: Durch das Ablegen von 
Vektoren und Varianten (Kreuzung, Weiche, Biegung etc.) kann man einen 
solchen Gleisplan auf wenige Bytes reduzieren. Faktisch muss dazu dann 
noch ein kleines Windowsprogramm geschrieben werden, mit dem man genau 
diese Elemente benutzerfreundlich platziert und abspeichert. Und er hat 
recht, vermutlich exisitert das bereits sogar so im Gleisplaner. Du 
müsstest nur das Dateiformat auslesen und konvertieren. Oder, wenn die 
Datei sowieso schon klein und effizient ist, diese einfach direkt 
einlesen, interpretieren und die Grafik aufbauen).

Im Speicher des Atmegas hast du dann nur noch die kleinen Bitmaps für 
die einzelnen Elemente wie Biegungen, Kreuzungen etc. liegen und setzt 
dann das Bild daraus zusammen.

Rolf

von John S. (student)


Lesenswert?

Dateiformat vom meinem Gleisplaner ist leider binär (von anderen 
wahrscheinlich auch).

Werde mich wieder melden - Grüsse

von Roger S. (edge)


Lesenswert?

Die tile engine erstmals erwaehnt von Johannes und von Karl heinz sehr 
gut erklaert, ist ideal fuer dein Projekt.

Mit den codes hat die engine implizit die Positionen der steuerbaren 
Elemente, sprich du musst deine Weichen und Signale nicht mehr 
einlernen.
Das Rumfahren mit dem Cursor kannst du dir auch schenken, stattdessen 
navigierst du direkt von Weiche/Signal zur naechsten.
Zoomen/Scrollen der map ist auch fast geschenkt, Uebersicht z.B. mit 
kleineren tiles rendern.

Die Technik ist uebrigens sehr alt und bewaehrt, findet vor allem bei 
Computerspielen anwendung.

Cheers, Roger

von gast (Gast)


Lesenswert?

Der vollständigkeit halber:
http://de.wikipedia.org/wiki/Tile

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.