Datum:
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:
const uint8_t roDrive_content[]={ 0x68, 0x61, 0x6C, 0x6C, 0x6F, 0x2E, 0x74, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x65, 0x6C, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x69, 0x78, 0x2E, 0x74, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x69, 0x65, 0x73, 0x20, 0x69, 0x73, 0x74, 0x20, 0x65, 0x69, 0x6E, 0x20, 0x6B, 0x6C, 0x65, 0x69, 0x6E, 0x65, 0x72, 0x20, 0x74, 0x65, 0x73, 0x74, 0x00, 0x6C, 0x73, 0x0A, 0x0A, 0x00, 0x6E, 0x69, 0x78 }; /* file system contents: filename: hallo.txt size:25 memory start: 128 memory end: 153 filename: help size:4 memory start: 154 memory end: 158 filename: nix.txt size:3 memory start: 159 memory end: 162 */ |
Für den Zugriff auf diese File-System habe ich einen (fast) io.h kompatiblen Treiber geschrieben:
extern void mx_perror (char *str);
extern mx_FILE* mx_fopen (char *fileName,char *acessType);
extern int16_t mx_fgetc (mx_FILE *fp);
extern mx_DIR_t* mx_opendir (char * str);
extern struct mx_dirent* mx_readdir (mx_DIR_t *dir);
extern void mx_initFileSystem(void);
|
Das Ganze findet sich hier: http://www.hobby-roboter.de/forum/download/file.php?id=132
Datum:
Angehängte Dateien:Der Trend geht zu Python ... Im Anhang mein erstes Python-Script, welches alle Dateien im Odner "files" in das oben beschrieben file.c umwandelt.
Datum:
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.
Datum:
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.
Datum:
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.
Datum:
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.