Mittlerweile haben die Mikrocontroller ja Speichergrößen im Megabyte-Bereich. Wie bindet man am besten größere Datenmengen wie z.B. Bilder oder Sounds in ein C-Projekt ein? Die Methode Byte-Array scheint mir auf Grund der Dateigröße nicht geeignet.
:
Bearbeitet durch User
Windows wählt den Weg der Ressourcen, eine dazugelinkte RES Datei und Zugriffsfunktionen z.B. für BITMAPs. Diese Struktur gibt es für den uC nicht, könnte man aber hinprogrammieren. Aber wozu, wenn sowieso alles statisch geladen ist, dann tut es auch eine statische Variable.
Christoph M. schrieb: > Wie bindet man am besten größere Datenmengen wie z.B. > Bilder oder Sounds in ein C-Projekt ein? An C23: #embed https://en.cppreference.com/w/c/preprocessor/embed
Dergute W. (derguteweka) >https://www.burtonini.com/blog/2007/07/13/embedding-binary-blobs-with-gcc/ Johann L. (gjlayde) >An C23: #embed >https://en.cppreference.com/w/c/preprocessor/embed Das sind schon mal sehr interessante Links. Ich will Sound-Dateien bei Controllern wie ESP32 oder PiPico einbinden. Bei beiden verwende ich ein Arduino-Framework. Beim PiPico https://github.com/earlephilhower/arduino-pico Dort wird es spannend ob die verwendete gcc-Version schon "C23: #embed" kann und die Dateipfade hinhauen.
Christoph M. schrieb: > Die Methode Byte-Array scheint mir auf Grund der Dateigröße nicht > geeignet. Solange du das Array mit einem Script generierst und dein Build-System die generierte Datei aktuell hält ist's eigentlich egal. Dergute W. schrieb: > https://www.burtonini.com/blog/2007/07/13/embedding-binary-blobs-with-gcc/ Ist schon ein bisschen peinlich dass der Dude es nicht schafft auf der Kommandozeile ein \0 an den Text anzuhängen um aus ihm einen gültigen C String zu machen
1 | printf '\0' >> foo.txt |
Man sollte auch noch sagen dass sein Vorschlag eventuell "_binary_foo_txt_size" zu nehmen meines Wissens nicht mehr in allen Umgebungen funktioniert. Das hat was damit zu tun dass das Symbol, obwohl es als absolut definiert ist, unter manchen Bedingungen trotzdem relocated wird.
Hannes J. schrieb: > Christoph M. schrieb: >> Die Methode Byte-Array scheint mir auf Grund der Dateigröße nicht >> geeignet. > > Solange du das Array mit einem Script generierst und dein Build-System > die generierte Datei aktuell hält ist's eigentlich egal. Ein Problem davon ist dass solche C-Dateien mit riesigen Arrays ziemlich lange zum Kompilieren brauchen, außer man definiert es als String-Literal statt als Array, da muss man aber höllisch mit Escape-Sequencen aufpassen (GIMP macht(e) es z.B. falsch beim XPM-Export). Die Source-Datei ist dann gern um ein Vielfaches größer als die Binärdatei. Der Weg über "ld" oder "objcopy" ist da eleganter und viel schneller, weil die Binärdaten einfach nur kopiert und mit einem ELF-Header versehen werden. Hannes J. schrieb: > Das hat was damit zu tun dass das Symbol, > obwohl es als absolut definiert ist, unter manchen Bedingungen trotzdem > relocated wird. Man könnte "size" auch im Linkerscript des finalen Link-Vorgangs als Differenz von Ende-Anfang definieren, dann wird da nix mehr relokiert.
:
Bearbeitet durch User
Ich würde auch einfach mit "xxd -i" .c Dateien daraus erstelen, und noch passende .h Dataien. Einfach in ein makefile target reinpacken, und das geht alles ganz automatisch (siehe Anhang).
Ein meines Erachtens sehr eleganter Weg, der vor allem ohne irgendwelche Dateikonvertierungen und komische Quelltextkonstrukte auskommt, ist eine Definition im entsprechenden Linkerskript. Das ist meines Erachtens auch deswegen die semantisch korrekte Stelle, da dort ja auch für die kompilierten Anteile und Bibliotheken bestimmt wird, wie sie im Speicher anzuordnen sind. Gerade bei großen einzubindenden Binärdateien will man ja meist ohnehin explizit definieren, wo der Kram landen soll.
1 | /* Direkt am Dateianfang, vor den anderen Definitionen: */ |
2 | TARGET(binary) |
3 | INPUT("path/to/audio_example.bin") |
4 | OUTPUT_FORMAT(default) |
5 | |
6 | ... |
7 | ... |
8 | ... |
9 | /* Eigener Abschnitt mit Zuweisung in den Abschnitt FLASH: */ |
10 | .audio_example (READONLY) : |
11 | { |
12 | . = ALIGN(4); |
13 | audio_example_start = .; |
14 | "path/to/audio_example.bin" |
15 | p_audio_example_end = .; |
16 | . = ALIGN(4); |
17 | } >FLASH |
Der Zugriff aus dem C-Code o.ä. erfolgt dann über die Symbole audio_example_start und audio_example_end; natürlich muss man hierfür entsprechende Deklarationen anlegen.
1 | extern uint8_t audio_example_start[]; |
2 | extern uint8_t * p_audio_example_end; |
:
Bearbeitet durch User
Andreas S. schrieb: > ist eine Definition im entsprechenden Linkerskript Klasse, schreib das mal in den Wiki-Artikel 😉
Christoph M. schrieb: > Die Methode Byte-Array scheint mir auf Grund der Dateigröße nicht > geeignet. wieso nicht? du schreibst ja selber: Christoph M. schrieb: > Speichergrößen im > Megabyte-Bereich. da sind doch die paar Bytes kein Problem
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.