Mahlzeit! Ich bin gerade dabei, für meine Diplomarbeit ein LEON3-System (www.gaisler.com) auf einen FPGA zu basteln und dafür irgendwelche Software zu programmieren. Nach 7 Monaten (!) harter Arbeit bin ich endlich soweit, dass meine Tool Chain steht. Ich habe auf meinem FPGA-Board den LEON laufen und konnte schon einfache C-Programme ausführen, die durch direkte Register-Adressierung auf verschiedenen Ports (zB UART, Text-basierter VGA-Ausgang) Zeichen ausgeben. Nun soll ich jedoch die mitgelieferten C-Libraries (spezielles GCC für den LEON gibts dazu) verwenden, um nicht mehr direkt in Register zu schreiben sondern Funktionen wie printf zu nutzen. printf("Hello World\n") hat schonmal funktioniert... das wird dann auch auf UART ausgegeben. Aber wie komme ich jetzt an die anderen Ports? Irgendwie kann man ja wohl Streams umleiten, davon verstehe ich aber absolut nichts. Mir fehlen einfach zu viele Grundlagen in Sachen C-Programmierung um irgendwelche Toturials o.ä. im www zu verstehen. Auch den entsprechenden Artikel hier http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Die_Nutzung_von_printf verstehe ich gar nicht... Ich weiß, wie schwer es für euch ist, mir eine passende Antwort zu geben, da ich ja selbst kaum eine Frage formulieren kann... Vielleicht kann mir ja einfach jemand den richtigen Weg zeigen, damit ich den ganzen Kram mit StdIO verstehe. Ich hoffe ihr habt ein bisschen Mitleid übrig für absolute Newbies. Danke euch!!!
Du brauchst 7 Monate harte Arbeit um das erste Programm auf dem Ding laufen zu lassen?! Da wundert es mich nicht, das du es nicht schaffst die Worte "C stdio stream umleiten" bei google einzugeben. Aber das ist nicht dein größtes Problem. Es wird für dich wahrscheinlich nicht so leicht zu verstehen sein, aber glaub mir, um C programmieren zu können muss man es wirklich vorher lernen. Kaum zu glauben, ist aber so. Mit ein bisschen Glück kannst du dann sogar die Tutorials verstehen, die hier zu finden sind. Ich denke aber du hast noch ein anderes großes Problem. Es wird dir bisschen komisch vorkommen, aber die anderen Leute können wirklich nicht deine Gedanken lesen. Was meinst du z.B. mit "den anderen Ports"? Einen zweiten UART, TCP/IP oder CAN? Wenn du einen UART meinst, dann ist es relativ einfach. Allerdings braucht man da auch Ahnung von C.
Hi! Das so eine Antwort kommt hab ich schon erwartet, deswegen hab ich mich ja im Vorraus für meine Unwissenheit entschuldigt... Ich weiß, dass hier niemand hellsehen kann. Also google hab ich auch schon benutzt, sogar genau so, wie du es vorschlägst;) Aber wie gesagt, wenn einem komplett die Grundlagen fehlen, versteht man da halt nicht wirklich viel. Das Problem ist halt einfach, dass mein Prof davon ausgeht, dass ich C programmieren kann. Schliesslich gabs da im 1. Semester eine Vorlesung zu. Da haben wir allerdings nur einfache Programme ins Visual Studio getippt und uns gefreut, dass irgendwas in der Konsole von Windows ausgegeben wurde... Was ich die letzten 7 Monate gemacht habe, kann ich ja mal kurz erklären: Zunächst brauchte ich ein Linux-Betriebssystem für die Tool Chain. Linux hatte ich vorher nie benutzt... Dann die Geschichte mit Makefiles usw... wie schon in der GCC-Tutorial beschrieben, ist das für einen Visual-Studio- und Windows-Benutzer alles sehr verwirrend am Anfang. Sämtliche Dokumentation zum LEON setzen halt auch schon sehr viele Grundlagen vorraus, die ich mir erstmal erarbeiten musste. Anfangs hat man schliesslich nur einen riesen Haufen VHDL-Dateien und ein paar Makefiles. Also brauchte es schonmal knapp ein halbes Jahr, bis der LEON auf dem FPGA war und Lebenszeichen von sich gab. Aber ich wette, Du hättest das an 2 Tagen geschafft, oder? Wie auch immer, es ist halt einfach so, dass mein Prof von mir Sachen erwartet, für die mir bei weiten zu viele Grundlagen fehlen. Leider hat er von der Sache auch keine Ahnung und stellt sich das alles ganz einfach vor (genau wie Du ^^). Und ich versuche jetzt halt irgendwie den Einstieg zu schaffen. Vielleicht hat ja doch noch jemand Lust, mit mir heraus zu finden, WO ich überhaupt einsteigen muss... Also nochmal Danke!!!
Ich denke mal, das hier so zwischen null bis kaum einer was mit LEON anfangen kann. Wenn Du also LEON spezifische IO-Funktionen nutzen willst, mußt Du in die LEON-Doku schauen. Vielleicht steht ja auch was in den h-Files (z.B. stdio.h), aber das ist in der Regel sehr kryptisch, wirklich nur was für C-Programmierer. Ich stimme auch zu, C lernt man nicht mal so eben schnell. Eine Sprache allein nützt auch garnichts, man muß außerdem die Herangehensweise an eine Programmieraufgabe lernen, also wie man eine Aufgabe plant, strukturiert und implementiert. Peter
Hallo Peter, erstmal Danke für Deine Antwort. Du versuchst wenigstens wirklich zu helfen :) Es ist klar, dass ich nicht "mal eben" C-Programmierung lernen kann. Prinzipiell würde ich aber schon behaupten, dass ich systematisch an Programmier-Aufgaben herangehen kann. Jedoch habe ich embedded-Systeme bisher nur in ASM programmiert und Hochsprachen wie C oder JAVA nur für kleine Windows-Applikationen benutzt. Für mich ist es einfach sehr schwer, die Brücke zwischen hardwarenaher und abstrakter Programmierung zu finden. Zumindest hab ich ja schonmal herausgefunden, wie ich in C direkt Register des LEON anspreche. Aber ich soll jetzt eine Abstraktionsebene höher gehen. Die Dokumentation zum LEON sagt zum StdIO nur das hier: BCC applications uses Newlib, which is a posix compatible C-library with full math support. However, no file or other I/O related functions will work, with the exception of I/O to stdin/stdout. Stdin/stdout are mapped on UART A, accessible via the usual stdio functions. Das hilft mir nicht wirklich weiter... Evtl. kann mir jemand eine gute Doku zur "Newlib" empfehlen, wo meine Fragen (teilweise) beantwortet werden?! In der stdio.h hab ich schonmal nachgeschaut, aber wie Du schon sagtest: alles sehr kryptisch... Soweit ich das sehe, werden da nur jede Menge Konstanten festgelegt. Ich stelle mir das eigentlich so vor (wahrscheinlich völlig falsch...): Mein UART liegt auf der Adresse 0x80000100. Jetzt müsste doch irgendwo sowas stehen wie stdio=0x80000100. Das würde ich verstehen :) Aber so einfach ist es ja nicht. Also wo wird sowas idR festgelegt? Ist das irgendwo in der stdio.h versteckt??? Ich kann mich nur nochmal für meine wahrscheinlich sehr blöden Fragen entschuldigen. Aber irgendwo muss ich ja anfangen...
Im Prinzip funktioniert das so ähnlich. Du musst der Standardausgabe ein neues Handle zuweisen. Es gibt dann eine Funktion in der Bibliothek, die die Ausgabe von Daten über diese Handles macht und von dir implementiert werden muss.In der Funktion kannst du nun je nach Handle das auf UART0, UART1 oder wo auch immer ausgeben. Unter Windows oder Linux übernimmt sowas das Betriebssystem. Auf einem Controller kann oder muss man das selbst machen. Google findet dazu auch gute Anleitungen.
Robert S. wrote: > However, no file or other I/O related functions will > work, with the exception of I/O to stdin/stdout. Stdin/stdout are mapped > on UART A, accessible via the usual stdio functions. Na das ist ja schon mal ne Aussage. Es bedeutet, daß Du alles außer der UART selber machen mußt. In der Regel ruft printf putchar auf. Man kann also sein eigenes putchar schreiben, was dann z.B. auf ein LCD ausgibt. Auf MCs wird aber meist ein anderes Konzept verwendet: Man benutzt nicht printf, sondern sprintf und schreibt damit in einen Puffer. Und diesen Puffer übergibt man dann der LCD-Ausgabefunktion oder wem auch immer. Damit ist man sehr flexibel. Peter
Beim BCC funktionieren printf u.s.w. auf UART-A automatisch, quasi ab Werk Gaisler. Wie auch in der Doku beschrieben. Er arbeitet mit 38400 Baud (wenn ich nicht irre). > work, with the exception of I/O to stdin/stdout. Stdin/stdout are mapped > on UART A, accessible via the usual stdio functions. Steht ja auch da: with the exception of Die Doku ist leider ziemlich dürftig. Kostet dafür auch nichts. Also dass hier sollte ohne weiteres funktioneren wenn du ein Terminal an den UART klemmst:
1 | #include <stdio.h> |
2 | #include <noch mehr, falls was fehlt> |
3 | |
4 | int main( void ) |
5 | {
|
6 | leonbare_init_ticks(); |
7 | printf("Hello world\n"); |
8 | return 0; |
9 | }
|
Wie du wahrscheinlich weißt, gibt es ein spezielles LEON-Forum bei YAHOO. Dort kann man einiges an Info bekommen. Newlib Doku findest du bei RedHat. Gaisler hat da wenig gemacht. Also Ihre eigene Implentierung ist kaum dokumentiert (leider). Was auch hilft, die Sourcen und Beispiele von Gaisler durchzuwühlen. Sie liefern die Newlib Sourcen ja auch. Da habe ich das meiste finden können. Allerdings ist das sehr mühselig. Es ist noch eine wichtige Funktion im Anfang der Main aufzurufen.
1 | leonbare_init_ticks(); |
Diese initialisiert die Timerlib und die IRQs und noch mehr. Dann kann man einen der beiden Timer schon so nutzen. Der läuft dann, wenn ich jetzt nicht irre, mit 10ms. Damit betreiben sie auch dann u.a. die pthreads-lib. Interrupts nutzt man wie folgt:
1 | catch_interrupt( IRQ-fFunc, uIrq ); // register IRQ function |
2 | leonbare_enable_irq(uIrq); // enable IRQ |
Zwei Makros, die den globalen IRQ EIN/AUS schalten
1 | // Macros to enable/disable the global interrupts /traps)
|
2 | #define CRITICAL_SECTION_START unsigned int old = leonbare_disable_traps();
|
3 | #define CRITICAL_SECTION_END leonbare_enable_traps(old);
|
Das Ganze geht auch unter Windows genauso bequem. Man kann von Gaisler ein Eclipse für Windows mit der kompletten Toolchain und deren Plugin für den LEON runterladen. Alles in einer EXE versteckt. Einfach starten und glücklich sein. Damit hättest du dir 6 Monate für Linux sparen können ;-) Das gleiche Paket gibt es aber auch für Linux von Gaisler (er ist Linux Verfechter) und funktioniert auch sehr gut. So mehr fällt mir jetzt nicht ein. Ist schon 2 Jahre her :-) Wie gesagt: YAHOO-Forum ist dein Ziel.
Ohne jemals mit der genannten Plattform gearbeitet zu haben... Da newlib als libc genannt wurde sollte das Konzept zur Anpassung an die Plattform analog zu anderen Plattformen sein (kenne es selbst nur von diversen ARM-Experimenten). Leider finde ich im Quellcode der newlib (hier 1.16) keine Verzeichnisse mit Namen leon, daher ist es etwas knifflig zu helfen. Wenn die "Umleitung" von stdin/stdout auf einen UART bereits funktioniert, sind einige syscalls zumindest rudimentär bereits in der libc enthalten. Möglicherweise wird es dann etwas kompliziert eigene syscalls, die verschiedene Dateihandles verarbeiten "unterzuschieben". Das geht evtl. mit "undef"-Linker-Optionen oder geänderter Link-Reihenfolge, ist aber mglw. etwas knifflig. Einfacher die newlib so zusammenbauen, dass keine default-syscalls enthalten sind (disable newlib supplied syscalls), zumindest mache ich das so für meinen ARM-Kram. Vorsicht: sehr wahrscheinlich wird dann die vorhandenen Umleitung auf einen UART auch erstmal nicht funktionieren, gibt als eine kleine Durststrecke. Sind keine syscall in der libc, kann man sich diese später projektspezifisch selbst erstellen und linken. Vorlagen für ganz brauchbare und flexible syscall-Implementierungen auf Grundlage der newlib-Schnittstellen: newlib-lpc von Aeolus und libsysbase von DevkitPro. Das Prinzip hinter diesen Codes ist, dass man pro Geräte eine Stuktur mit Funktionspointer zu hardwarespezifischen Funktionen (z.B. Zeichen an UART0 senden, Zeichen von UART1 lesen etc.) füllt. Intern wird eine Liste verwaltet, die Datei-Handle, Gerätebezeichung und Funktionspointer-Strukturen enthält. Die syscalls-Implementierungen (open, read, write, etc.) "finden" darin dann die zum Geräte/Handle passenden Funktionspointer, die auf Funktionen verweisen, welche die hardwarespezifischen Operationen ausführen. Mein Text liest sich komplizierter als es ist... Einfach in den Quellcode der genannten "support-libs" schauen. Die ganze Listenverwaltung ist plattformunabhängiger C-Code, den man wahrscheinlich einfach weitestgehend übernehmen kann. Die hardwarespezifischen Funktionen kann man wahrscheinlich aus dem vorhandenen Code für den einen UART ableiten und anpassen.
mthomas wrote: > Ohne jemals mit der genannten Plattform gearbeitet zu haben... > > Da newlib als libc genannt wurde sollte das Konzept zur Anpassung an die > Plattform analog zu anderen Plattformen sein (kenne es selbst nur von > diversen ARM-Experimenten). Newlib ist eine "modernere" libc. > Leider finde ich im Quellcode der newlib > (hier 1.16) keine Verzeichnisse mit Namen leon, daher ist es etwas > knifflig zu helfen. Hat Gaisler glaube ich selber unter seinen Pfoten. Darum hilft nur, seine mitgeliefeten Sourcen durchzugraben. 900ss
Moin! Erstmal schönen Dank an alle! Jetzt wirds ja doch noch interessant :) Wenigstens bin ich nicht der einzige, der die Gaisler-Doku besch*** findet. Das schöne ist ja auch, dass es außer den Copyrights keinerlei Beschreibungen in den Köpfen der mitgelieferten Libs bzw. Beispielprogramme gibt. Kommentare sucht man meist vergeblich... Also verstehe ich das jetzt richtig, dass es gar nicht möglich ist, das StdOut mal eben umzuleiten?! Ich hatte den Satz der Doku so verstanden, dass zwar nur ausschließlich StdIO-Befehle möglich sind, die ZUR ZEIT auf UART A gemapped sind. Also muss man das doch ändern können!? Das "Hello World" läuft wie gesagt. Und ich habe mir ja schon eigene Funktionen geschrieben, die z.B. ein PS2-Keyboard auslesen oder Zeichen auf VGA ausgeben. Mein Prof meint halt nur, dass es ja möglich sein muss, die mitgelieferten Funktionen zu verwenden... Die Yahoo-Group kenne ich natürlich schon. Hat mir aber bisher auch nicht geholfen. Und auf meine absolute-beginner-Fragen hat da bisher keiner reagiert ggg. Na gut, ich werde nochmal tief in den Libs rumwühlen und versuchen zu verstehen... Nochmal zur Tool Chain: Ich habs natürlich erst mit Windows versucht. Aber ganz so einfach wie "setup.exe und glücklich sein" wars dann doch nicht. Dadurch, dass ich unter Linux jedes Tool manuell installieren musste, hab ich mich wenigstens gleich mit jedem Tool auseinander setzen müssen und weiß jetzt auch, welches wofür gut ist... Bei der Win-Installation hatte ich mit einem Klick alle Tools auf einmal und wußte nicht, wofür man das alles braucht. Von daher hab ich unter Linux schonmal ne Menge gelernt :) Danke euch erstmal!
Gerade d'rüber gestolpert. Vielleicht hilft dir dieser Artikel noch ein wenig. http://venus.billgatliff.com/node/3 Poting and using Newlib. 900ss
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.