größere Daten-Dateien im C-Projekt

#7905315
Lesenswert?

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.

#7905329
Lesenswert?

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.

#7905357
Lesenswert?

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.

Persönliche Seite #7905376
Lesenswert?

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.

(Firma: Schweigstill IT) Persönliche Seite #7905607
Lesenswert?

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;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren