Hallo Zusammen,
bisweilen ist es von Nutzen, wenn man in einem Mikrocontroller Daten aus
einem Filesystem nutzen kann.
Ich habe ein Programm geschrieben, welches den Inhalt eines Directories
in ein Byte-Array umwandelt. Dieses Array kann in ein C-Programm
eingebunden werden.
Das Ganze sieht dann so aus:
So ein paar Kleinigkeiten:
. 'true' und 'false' gibt es in <stdbool.h>.
. Es ist <string.h>, nicht "string.h", und <stdio.h>, nicht "stdio.h".
. Anstelle von <inttypes.h> wolltest du vermutlich <stdint.h>, denn dort
sind uint8_t etc. deklariert. Auch da heißst es <stdint.h> und nicht
"stdint.h".
Aus deinem Blog entnehme ich, dass die Sache wohl auf AVR laufen soll.
Sollte das tatsächlich der Fall sein, dann hat dein Dateisystem
insgesamt den ganz furchtbar blöden Nachteil, dass es stets doppelt so
viel Speicher im Zielsystem verbraucht, als nötig. Das Dateisystem liegt
im Programmspeicher (Flash) und wird beim Start in den Arbeitsspeicher
(SRAM) geladen -- tödlich!
Geschickter wäre, wenn du einen Blick auf <avr/progmem.h> werfen
würdest.
Schließlich könntest du den Zugriff ganz in <stdio.h> integrieren -- die
Routinen hast du ja bereits fertig. Lediglich den fopen()-Aufruf
müsstest du überarbeiten.
Hallo Sven,
Danke für die Hinweise :-)
>So ein paar Kleinigkeiten:>. 'true' und 'false' gibt es in <stdbool.h>.
Das wusste ich nicht. Das Programm entwickle ich immer mit dem GCC auf
dem PC ( meisten Linux ). Ich hoffe, stdbool gibt es überall.
>. Es ist <string.h>, nicht "string.h", und <stdio.h>, nicht "stdio.h".
wird geändert.
>. Anstelle von <inttypes.h> wolltest du vermutlich <stdint.h>, denn dort>sind uint8_t etc. deklariert. Auch da heißst es <stdint.h> und nicht>"stdint.h".
Hmm, das ist bei mir historisch entstanden. Irgendwo hatte ich mal
dieses Include gesehen und seit dem beibehalten. Ich werde es ändern.
>Aus deinem Blog entnehme ich, dass die Sache wohl auf AVR laufen soll.>Sollte das tatsächlich der Fall sein, dann hat dein Dateisystem>insgesamt den ganz furchtbar blöden Nachteil, dass es stets doppelt so>viel Speicher im Zielsystem verbraucht, als nötig. Das Dateisystem liegt>im Programmspeicher (Flash) und wird beim Start in den Arbeitsspeicher>(SRAM) geladen -- tödlich!>Geschickter wäre, wenn du einen Blick auf <avr/progmem.h> werfen>würdest.
Ich habe mir sagen lassen, das eine neuere Funktion des avr-gcc den
Zugriff auf das Flash automatisch richtig macht. Ab welcher Version das
gilt, weiss ich allerdings nicht.
Die Schnittstelle des Filesystems ist so vorbereitet, dass der Zugriff
über die Memory-Adresse byteweise geschieht. Die Verwendung der
<avr/progmem.h> Funktionen ist also ohne Probleme möglich.
Das Filesystem soll universell auf Microcontrollern einsetzbar sein. Als
erstes ziele ich auf die AVRs, die STM32F4 Discovery-Boards liegen aber
schon hier rum. Dort macht es ja auch mehr Sinn, in 1MB Flash lassen
sich schon ein paar Dateien packen.
>Schließlich könntest du den Zugriff ganz in <stdio.h> integrieren -- die>Routinen hast du ja bereits fertig. Lediglich den fopen()-Aufruf>müsstest du überarbeiten.
Das wäre vielleicht eine Idee. Ich weis aber nicht, wie es geht und ich
vermute, dass der Integrationsaufwand für die unterschiedlichen
Platformen steigt.
chris schrieb:> Hallo Sven,>> Danke für die Hinweise :-)>>So ein paar Kleinigkeiten:>>. 'true' und 'false' gibt es in <stdbool.h>.> Das wusste ich nicht. Das Programm entwickle ich immer mit dem GCC auf> dem PC ( meisten Linux ). Ich hoffe, stdbool gibt es überall.
Das wurde mit dem C-Standard von 1999 aufgenommen. Sollte jeder aktuelle
Compiler besitzen. Außer natürlich Microsoft, die sind 1989
stehengeblieben... Dort müsste es aber beim C++-Compiler dabei sein.
>>. Es ist <string.h>, nicht "string.h", und <stdio.h>, nicht "stdio.h".> wird geändert.
Hintergrund ist, dass mit den Winkeln ('<', '>') u.a. in den
Systemheadern gesucht wird, das ist typischerweise dann '/usr/include/'.
Mit Anführungszeichen referenzierst du Header, die zu deinem aktuellen
Projekt gehören.
>>. Anstelle von <inttypes.h> wolltest du vermutlich <stdint.h>, denn dort>>sind uint8_t etc. deklariert. Auch da heißst es <stdint.h> und nicht>>"stdint.h".> Hmm, das ist bei mir historisch entstanden. Irgendwo hatte ich mal> dieses Include gesehen und seit dem beibehalten. Ich werde es ändern.
Ist auch effektiv nicht falsch, denn <inttypes.h> bindet ihrerseits
<stdint.h> ein. Allerdings gehören die Datentypen selbst zu <stdint.h>
und <inttypes.h> liefert dann noch eine Reihe Makros dazu, etwa zur
Konvertierung und so. Man will/soll ja auf kürzestem Wege zum Ziel
kommen, daher ist es sinnvoller, auch das zu schreiben, was gemeint
ist :-)
>>Aus deinem Blog entnehme ich, dass die Sache wohl auf AVR laufen soll.>>Sollte das tatsächlich der Fall sein, dann hat dein Dateisystem>>insgesamt den ganz furchtbar blöden Nachteil, dass es stets doppelt so>>viel Speicher im Zielsystem verbraucht, als nötig. Das Dateisystem liegt>>im Programmspeicher (Flash) und wird beim Start in den Arbeitsspeicher>>(SRAM) geladen -- tödlich!>>Geschickter wäre, wenn du einen Blick auf <avr/progmem.h> werfen>>würdest.>> Ich habe mir sagen lassen, das eine neuere Funktion des avr-gcc den> Zugriff auf das Flash automatisch richtig macht. Ab welcher Version das> gilt, weiss ich allerdings nicht.
Ja, die Zeiger werden auf drei Bytes verlängert und funktionieren dann
quasi wie früher Segment:Offset. Anhand der höchsten paar Bits kann dann
entschieden werden, wohin (RAM/ROM) der Zeiger zeigt.
Dazu musst du die Daten dann aber trotzdem noch explizit ins ROM (err,
Flash) verschieben. Der GCC hat dazu irgendein Attribut, glaube ich.
>>Schließlich könntest du den Zugriff ganz in <stdio.h> integrieren -- die>>Routinen hast du ja bereits fertig. Lediglich den fopen()-Aufruf>>müsstest du überarbeiten.>> Das wäre vielleicht eine Idee. Ich weis aber nicht, wie es geht und ich> vermute, dass der Integrationsaufwand für die unterschiedlichen> Platformen steigt.
Ist recht simpel. Du musst lediglich eine fopen-Routine umsetzen. Die
beschränkt sich einfachstenfalls auf ein Makro, dem du eine
Lese-Zeichen- und eine Schreibe-Zeichen-Funktion übergibst. In deinem
Fall nur eine Lese-Zeichen-Funktion.
Dadurch hast du dann gleich das ganze Repertoire mit scanf() erschlagen.
Der Effizienz halber wirst du ja ohnehin irgendwie auf
Präprozessor-Schalter setzen müssen. Allein schon wegen der Sache mit
ROM und RAM. Da könnte man das dan gut unterbringen.
Hallo Sven,
hier habe ich die meisten von dir vorgeschlagenen Änderungen gemacht:
http://www.hobby-roboter.de/forum/download/file.php?id=133
Das File System habe ich für den Arduino portiert. Es war mehr Arbeit
als ich dachte, weil ich Probleme mit dem Zusammenkompilieren der
Arduino cpp-Files und meinen in C-geschriebenen Routinen hatte. Das
Debugging gestaltet sich auf dem Arduino auch etwas schwieriger als auf
dem PC.
Nichts desto trozt läuft es jetzt. Das Ganze ist für die Arduino IDE 1.0
und müsste für die älteren IDEs mit den *.pde files neu kompiliert
werden. Das Besondere an der IDE 1.0 ist, dass die Files im Klartext
vorligen. Das Main-File hat die Endung *.ino statt *.cpp.