Forum: Compiler & IDEs Rohdaten direkt in Flash übertragen


von Fritz (Gast)


Lesenswert?

Hallo

Ich möchte eine Zahlentabelle die als Binärdatei vorliegt direkt in den 
Flash eines ATtiny2313 übertragen und dort nutzen.

Ich könnte natürlich die Zahlen in eine ASCII Datei konvertieren, 
Beistriche und Klammern setzten und als header einbinden und dann mit 
kompilieren. Das ist aber unelegant und ich möchte das nach Möglichkeit 
vermeiden.

Es handelt sich um 16 Bit unsigned integer Zahlen, die Gesamtlänge ist 
fest vorgegeben.

Im RAM und im EEPROM ist wahrscheinlich zu wenig Platz, deshalb müssen 
die Daten in den Flash. Gibt es eine Möglichkeit die Zahlen einfach 
hinten an das kompilierte Programm an zu hängen?

Zugreifen kann ich dann ja wahrscheinlich mit den Methoden wie hier 
beschrieben: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29

Der Compiler braucht ja nichts von den Daten zu wissen.

Vielen Dank schon mal, mfg Fritz

von Klaus W. (mfgkw)


Lesenswert?

avrdude kann das doch:
1
  -U <memtype>:r|w|v:<filename>[:format]
2
                             Memory operation specification.
3
                             Multiple -U options are allowed, each request
4
                             is performed in the order specified.

von Klaus W. (mfgkw)


Lesenswert?

achso , eben erst gelesen, dass du sie ja ANHÄNGEN willst.
Dann müsstest du halt deine Daten an das gelinkte Programm
anhängen und dann flashen.
Was insofern doof ist, weil du dann nachdenken musst, wo
diese Daten dann zur Laufzeit zu finden sind.

Ich würde es eher in ein C-Feld verpacken; das Thema wurde
hier glaube ich schon mehrfach debattiert?
Ich habe mir dafür mal ein Progrämmchen gebaut, das eine
beliebige Datei liest und die Initialisierung eines C-Feldes
draus macht, das ich dann wiederum per #include in meinen
Quelltext einfüge.
Aber da scheint jeder seine eigene Variante zu mögen.

von Sven P. (Gast)


Lesenswert?

Man könnte ein Assembler-Symbol draus machen, dort mit der 
entsprechenden GCC-Assemblerinstruktion (welche mir jetzt natürlich 
nicht einfällt, irgendwas von wegen binary-include) den Datenmüll 
einbinden. Dann alles zusammen durch den Linker und fertig.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?


von Fritz (Gast)


Lesenswert?

Cool, so viele Antworten auf einmal!

Danke erstmal.

Wie schon gesagt, die Sache mit dem C Feld ist für mich nur eine 
Notlösung.

Am besten gefällt mir die Methode von Martin Thomas mit avr-objcopy. 
Allerdings ist mir das alles noch eine Spur zu hoch, ich habe ehrlich 
gesagt keine Ahnung von makefiles, ich muss mich da erst einlesen.

Wenn ich das richtig verstanden habe, dann macht mir dieser Befehl aus 
einem binary file ein object file und setzt zusätzlich Marken, die ich 
in meinem Programm verwenden kann um auf die Daten zu zu greifen.

Soweit, so gut, jetzt muss ich nur noch irgendwie das o-file ans 
eigentliche Programm anhängen und zum höchsten aller files, dem hex 
file, "verwurschten", richtig?

mfg Fritz

von Simon K. (simon) Benutzerseite


Lesenswert?

Das Object file kriegt der Linker mit.

von Fritz (Gast)


Lesenswert?

Hallo

So ich hab jetzt endlich Zeit gehabt mir das makefile Fragment zu Gemüte 
zu führen.
1
$(OBJDIR)/%.o : %.bin
2
        @echo Converting $<
3
        @$(OBJCOPY) -I binary -O elf32-avr \
4
        --rename-section .data=.progmem.data,contents,alloc,load,readonly,data \
5
        --redefine-sym _binary_$*_bin_start=$* \
6
        --redefine-sym _binary_$*_bin_end=$*_end \
7
        --redefine-sym _binary_$*_bin_size=$*_size_sym \
8
        $(<) $(@)
9
        @echo "extern const char" $(*)"[] PROGMEM;" > $(*).h
10
        @echo "extern const char" $(*)_end"[] PROGMEM;" >> $(*).h
11
        @echo "extern const char" $(*)_size_sym"[];" >> $(*).h
12
        @echo "#define $(*)_size ((int)$(*)_size_sym)" >> $(*).h

Aber so einige Sachen sind mir noch unklar:

1. Was bedeutet das $(OBJDIR) vor %.o? Ist da ein eigener Ordner für .o 
files vorgesehen oder wie?

2. Wenn ich diese Regel in mein makefile einfüge kommt das doch in 
Konflikt mit der Regel die es dort für .o files schon gibt, nähmlich zu 
kompilieren, oder? Wie kann ich dieses Fragment jetzt in mein makefile 
integrieren?

3. Die 4 Zeilen am Schluss definieren offenbar ein headerfile. Was ist 
das für ein headerfile und was muss ich damit machen? In dem wird 
offenbar ein array deklariert, dass meine Daten enthält, sowie dessen 
Ende und Länge. Aber warum steht auch hinter Ende und Länge ein [], das 
sind doch keine arrays?

4. Was ist $(*) und $* und was ist der Unterschied?

Vielen Dank schon mal.

mfg Fritz

von Hrm (Gast)


Lesenswert?

Also ehrlich: C ist eine Notlösung, aber wie man das mit objcopy macht 
verstehst Du nicht und ein Makefile kannst Du nicht lesen?

Dann ist die "Notlösung" wohl eher das Du die Daten als Binärdaten 
vorliegen hast. Es ist aus meiner Sicht eher eine "Notlösung" die Daten 
an Compiler und Linker vorbei ranzuklatschen.

Aber gut, wat dem eenen sin Uhl....

von Michael U. (amiga)


Lesenswert?

Hallo,

Hrm schrieb:
> Also ehrlich: C ist eine Notlösung, aber wie man das mit objcopy macht
> verstehst Du nicht und ein Makefile kannst Du nicht lesen?
>
> Dann ist die "Notlösung" wohl eher das Du die Daten als Binärdaten
> vorliegen hast. Es ist aus meiner Sicht eher eine "Notlösung" die Daten
> an Compiler und Linker vorbei ranzuklatschen.
>
> Aber gut, wat dem eenen sin Uhl....

:-))

ich habe schon eine Wave-Datei per php-Script auf meinem Webserver in 
eine asm-include-Datei konvertiert weil gerade nichts anderes zur Hand 
war.

PS: war eine Notlösung, hat ca. 20min gedauert, keine 5 Tage ;-) und 
liegt immernoch dort parat...

Gruß aus Berlin
Michael

von Stefan E. (sternst)


Lesenswert?

Fritz schrieb:

> 1. Was bedeutet das $(OBJDIR) vor %.o? Ist da ein eigener Ordner für .o
> files vorgesehen oder wie?

Ja. Wenn es bei dir anders ist, muss du das entsprechend ändern.

> 2. Wenn ich diese Regel in mein makefile einfüge kommt das doch in
> Konflikt mit der Regel die es dort für .o files schon gibt, nähmlich zu
> kompilieren, oder?

Nein, denn es ist eine ".bin nach .o"-Regel. Ich nehme mal nicht an, 
dass deine zu kompilierenden Files auch die Endung .bin haben, oder?

> 3. Die 4 Zeilen am Schluss definieren offenbar ein headerfile. Was ist
> das für ein headerfile und was muss ich damit machen?

"Müssen" musst du gar nichts damit. Es ist nur ein Beispiel, wie du dann 
die Symbole verwenden kannst.

> In dem wird
> offenbar ein array deklariert, dass meine Daten enthält, sowie dessen
> Ende und Länge. Aber warum steht auch hinter Ende und Länge ein [], das
> sind doch keine arrays?

Objcopy definiert nur Symbole, also quasi nur Adressen. Welchen Typ die 
Daten an dieser Adresse haben obliegt der Interpretation des Anwenders.
1
extern const char BEISPIEL_size_sym[];
Bedeutet hier einfach nur: Unbestimmte Anzahl Bytes an der Adresse 
BEISPIEL_size_sym. Das darauffolgende #define interpretiert dann diese
"Bytes unbestimmter Anzahl" als int. Man könnte auch gleich schreiben:
1
extern const int BEISPIEL_size_sym;

Da deine Daten 16 Bit unsigned Zahlen sind, kannst du für die Daten auch 
schreiben:
1
extern const uint16_t BEISPIEL[] PROGMEM;
Aber Vorsicht: das size-Symbol bleibt natürlich die Größe in Bytes.
BTW: Haben diese Zahlen denn auch die richtige Endianness?

> 4. Was ist $(*) und $* und was ist der Unterschied?

Das ist die Namensbasis, für die die Regel gerade angewendet wird. Wenn 
gerade BEISPIEL.bin in BEISPIEL.o überführt wird, ist es "BEISPIEL". Die 
Klammern dienen dazu, den $-Part von nachfolgenden Buchstaben eindeutig 
zu trennen.

von Fritz (Gast)


Lesenswert?

Vielen Dank @ Stefan Ernst!!

Für die ausführliche Beantwortung aller meine Fragen, das hat mir sehr 
geholfen :)

zwecks Endianness: ich habe mich mittlerweile dazu entschlossen 8 Bit 
Zahlen zu verwenden, damit ist das hinfällig.

Vielen Dank nochmal, falls mir noch was einfällt meld ich mich wieder.

mfg Fritz

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.