bootloader Verwendung

Die Programmierung des c't-Bot
huetz

bootloader Verwendung

Beitrag von huetz » 01 Okt 2008, 14:18

Hallo, ich versuche derzeit den bootloader zu verwenden und habe dabei folgendes Problem:

Wenn ich versuche den bootloader zu kompilieren, dann erhalte ich in eclipse folgende Fehler-

- make: *** [ct-Bot.elf] Error 1
- unrecognized option '-Wl,--section-start=.bootloader=0x7C00'
- use the --help option for usage information

und eine Warning:

-Wl,--section-start=.bootloader=0x7C00 startet "

Was mache ich denn verkehrt? Ich habe die Option im GCC-Linker eingetragen.

huetz

Beitrag von huetz » 01 Okt 2008, 14:53

problem gelöst, ich hab die options an der falschen stelle eingetragen... :/

huetz

Beitrag von huetz » 01 Okt 2008, 15:11

Das ganze führt mich nun zu einem Verständnisproblem. Ich habe nun auf meinem Bot eine Firmware mit Bootloader. Wie schreibe ich nun ein Programm, dass ich auf den Bot flashen kann, ohne den Bootloader wieder zu überschreiben? Im Grunde muss ja nun immer die alte Firmware drauf bleiben und der bootloader sorgt dafür, dass der neue code an die richtige Stelle kommt.

Wenn ich aber nun mein Programm ändere, ich dem ich eben dafür gesorgt habe, dass der bootloader aktiviert wird, und dies dann über wlab z.b. flashe, überschreibe ich dann nicht alles was vorher drauf war?

Kann mir da jemand ne Erklärung liefern wie das nun von statten geht? Wie spiele ich code auf den bot wenn ich einen bootloader verwende?

eax
Friends of Robby
Friends of Robby
Beiträge: 755
Registriert: 18 Jan 2006, 16:16
Wohnort: Karlsruhe

Beitrag von eax » 02 Okt 2008, 18:32

huetz hat geschrieben:Im Grunde muss ja nun immer die alte Firmware drauf bleiben und der bootloader sorgt dafür, dass der neue code an die richtige Stelle kommt.
Nein, es muss nur der Bootloader drauf bleiben, die eigentliche Firmware wird dann vom Bootloader ersetzt, er selbst bleibt dabei natürlich erhalten.

Wenn die Fuse-Bits auf Bootloader eingestellt sind, wird der Adressraum des Flashspeicher im Controller logisch in zwei Teile geteilt, auf dem ATmega32 z.B. einer von 0 KB bis 31 KB für das Programm und einer von 31 KB bis 32 KB für den Bootloader. Nach jedem Reset lädt der Controller den Programmcode an Adresse 0x7c00, startet also den Bootloader. Der wartet 5 Sekunden auf ein Signal von avrdude, kommt keines, springt er zu Adresse 0x0.
huetz hat geschrieben:Kann mir da jemand ne Erklärung liefern wie das nun von statten geht? Wie spiele ich code auf den bot wenn ich einen bootloader verwende?
Du schaltest einmal im Code das #define für den Bootloader an und flasht den dann erzeugten Code auf den Bot wie bisher. Dann machst du das #define für den Bootloader wieder aus (bleibt ab jetzt immer aus), drückst am Bot auf den Reset-Knopf und startest innerhalb von 5 Sekunden den Flashvorgang via Bootloader.

Weitere Infos stehen in Documentation/Bootloader.html und auf der Wiki-Seite "Flash".

Grüße,
Timo

huetz

Beitrag von huetz » 05 Okt 2008, 19:12

Danke für die Anwort! :)

Ich hab da nun noch ein Problem beim flashen über WLAN. Ich will den bot über wlan flashen mit Hilfe von avrdude 5.5. Zum Flashen gebe ich folgende Kommandozeile ein:
avrdude -p m32 -c avr109 -P net:IPADRESS:10002 -U flash:w:FILENAME:i -u -vvvv
Die einzelnen Optionen des avrdudes hab ich schon verstanden, ich bekomme jedoch dann folgende Fehlermeldung:
Connecting to programmer: .avrdude: ser_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding
Ich verstehe nicht was dort das Problem ist. Ich verstehe nicht, was es mit dem avr109 auf sich hat, bzw was das ist. Ich habe einmal die Rückmeldung erhalten, dass es vllt auch ein avr910 auf dem bot sein soll, jedoch weiss ich das nicht. Kann mir das auch wer erklären was das ist und was ich falsch mache?

Außerdem habe ich noch eine weitere Frage: Muss ich den Bot nach dem aufspielen der Firmware mit Bootloader immer erst resetten, bevor ich ihm neuen Code einspielen kann? Wenn ja, ist dieser reset auch irgendwie von außen möglich oder geht das nur per knopfdruck? In meinem Projekt sollen die bots halt per wlan geflasht werden und niemand soll da dran etwas einstellen müssen, wenn man ihn flasht. Ist das dann überhaupt möglich?

Benjamin.Benz

Beitrag von Benjamin.Benz » 06 Okt 2008, 08:50

... Muss ich den Bot nach dem aufspielen der Firmware mit Bootloader immer erst resetten, bevor ich ihm neuen Code einspielen kann?
Nach dem aufspielen der Firmware beendet sich der Bootloader und springt das normale Programm an. Um wieder neue Firmware einzuspielen muss der Bootloader wieder laufen. Der einfachste Weg dafür ist einn Reset.
Wenn ja, ist dieser reset auch irgendwie von außen möglich oder geht das nur per knopfdruck?
Es spricht rein gar nichts dagegen, dem Bot ein neues Command beizubringen, das ihn dazu veranlasst, selbst einen Software-Reset auszulösen. Am saubersten dürfte das wohl gehen, wenn man den Watchdog-Timer an und alle Interrupts aus macht und dann den Bot in eine Endlosschleife schickt. Dann löst der Watchdog-Timer einen sauberen Reset aus.

MfG Benjamin Benz

huetz

Beitrag von huetz » 06 Okt 2008, 10:19

Ersteinmal Danke für die Hilfe, ohne diese würde ich glaube ich gar nicht weiter kommen :)

Den Watchdog-Timer zu nutzen wäre eine Möglichkeit, jedoch wenn ich ihn nutze, dann kann ich nicht wirklich von außen einen Reset herbeiführen, wenn ich das möchte. So würde der bot sich ja nur selbst resetten, wenn der Timer abgelaufen ist.

Was ich brauche wäre eine Möglichkeit den bot per Befehl von außen zu resetten, z.b. über einen seriellen Befehl.

Um das ganze mal weiter zu erklären beschreibe ich mal unser Projekt, bzw wo der Roboter da eingesetzt wird. Es handelt sich um ein Hochschul Projekt, welches ich vorbereite. In diesem Projekt sollen die Studierenden in Gruppen ein Webportal erstellen, welches als Programmierportal für den Roboter dient. Die Funktionen des Portals beinhalten außerdem die Möglichkeit Sourcecode hochzuladen (oder kompilierte .hex-files) und diesen Code dann in den ctbot zu übertragen. Um dies einheitlich zu gewährleisten haben wir einen Server aufgesetzt, welcher dieses als Webdienst anbietet.

Der sogenannte Flashserver soll nun über Wlan die Roboter flashen, gleichzeitig filmt eine Webcam den roboter pool. So soll jemand von außen über das Web die bots flashen können und sieht über die Webcams direkt das Resultat.

In diesem Szenario ist es natürlich nicht gut, wenn dann immer jemand auf die Resettaste drücken muss, wenn man einen bot flashen möchte. Daher benötige ich eine Resetmöglichkeit, die ich von außen nutzen kann.

Ich hoffe, dass dies ein wenig mein Problem erklärt :)

Kann mir denn noch jemand zu dem avr109 und avr910 etwas erklären? Was genau ist das? Wozu brauch ich das beim Aufruf des avrdudes? Ist mein beschriebener Aufruf des avrdudes überhaupt korrekt?

huetz

Beitrag von huetz » 06 Okt 2008, 11:43

Ich bin mit meinem Projekt nun ein ganzes Stück weiter gekommen und bin nun in der Lage, den Bot über Wlan zu flashen. Das Problem war, dass ich die 5 Sekunden immer verpasst hatte und somit den Bootloader quasi gar nicht erreicht habe. Ich habe nun die 5 Sekunden auf 10 Sekunden erhöht und schon funktioniert alles wunderbar.

Einzig und allein das Reset Problem besteht dann jetzt noch. Damit ich den Bot flashen kann, muss ich ihn resetten. Dies muss von außen geschehen, jedoch weiß ich nicht wie.

Kann man per telnet dort einen reset auslösen?

huetz

Beitrag von huetz » 06 Okt 2008, 13:55

Ich habe etwas über remote_calls gelesen, mit denen ich ein Verhalten aktivieren bzw. aufrufen kann. Wie genau mache ich einen solchen remote_call? Ich könnte ja z.B. ein Verhalten erstellen, welches den Watchdog Timer einschaltet und ablaufen lässt. So hätte ich quasi eine Reset Möglichkeit geschaffen.

Jedoch finde ich keine Informationen dazu, wie ich diese remote_calls mache.

eax
Friends of Robby
Friends of Robby
Beiträge: 755
Registriert: 18 Jan 2006, 16:16
Wohnort: Karlsruhe

Beitrag von eax » 06 Okt 2008, 17:54

Hi,

1.) Die RemoteCalls rufen vom ct-Sim (oder dem Java-Applet) eine C-Funktion des Bots auf. Diese kann z.B. ein Verhalten starten (der übliche Fall). Das ist im Prinzip so was ähnliches wie RPC. Wie man eine Funktion als RemoteCall registriert, steht in bot-logic/behaviour_remotecall.c. Wie das Ganze funktioniert, steht hier.

2.) Du kannst die Funktion, die den Reset auslösen / Bootloader starten soll, auch auf eine Fernbedienungstaste legen, Fernbedienungstasten können ebenfalls über WLAN getriggert werden.

3.) Anstatt der vorgeschlagenen WatchDog-Methode, gibt es auch noch die Möglichkeit, den Bootloader direkt per Software aufzurufen (wie eine Funktion):

Code: Alles auswählen

{
INTERRUPTS AUS
UART-PUFFER FLUSHEN

void (* start_bootloader)(void) = (void *)0x7c00;	// fuer ATmega32
start_bootloader();

// wird nie erreicht
}
Details zum Bootloader stehen im Prozessordatenblatt, das hier verlinkt ist. Im Datenblatt des ATmega644 sind die Erklärungen deutlich ausführlicher, es empfiehlt sich bei Verständnisfragen also, dieses zu lesen.

4.) Ein Problem hat die ganze Angelegenheit: Der Bot bekommt seine Befehle von außen über einen TCP/IP-Kanal, also verbindungsorientiert. Daher kann avrdude keine TCP-Verbindung zum Bot aufbauen, wenn das Steuerprogramm, das den Reset-Befehl gesendet hat (z.B. ct-Sim) schon eine Verbindung aufgebaut hat.
Möglichkeit 1: Sim beendet die Verbindung und baut sie anschließend neu auf (einfach, aber nicht so elegant).
Möglichkeit 2: Datentransfer von avrdude durch den Sim zum Bot tunneln (deutlich eleganter, weil bestehende Verbindung zum Wiport mitbenutzt werden kann).
Möglichkeit 3: Dem Sim / Applet beibringen, was avrdude sonst tut, avrdude ist ja Open Source (optimale Lösung).

Grüße,
Timo

huetz

Beitrag von huetz » 06 Okt 2008, 18:26

Das ist mal ne sehr hilfreiche Antwort :) Danke sehr!

Soetwas wie den Sim oder das Applet gibt es in meinem Fall nicht, also besteht keine zweite Verbindung neben dem avrdude. Nur dieser baut eine Verbindung auf, welche dann wieder abgebaut wird.

Das Triggern der Fernbedienungstaste über Wlan versteh ich nicht so ganz, wie kann ich mir das vorstellen? Wenn ich den bootloader direkt aufrufen kann, dann ist das natürlich die weitaus bessere Methode, als jedes mal zu resetten. Ich werd mal danach suchen ob ich was zur Fernbedienung finde.

huetz

Beitrag von huetz » 07 Okt 2008, 11:43

eax hat geschrieben: 2.) Du kannst die Funktion, die den Reset auslösen / Bootloader starten soll, auch auf eine Fernbedienungstaste legen, Fernbedienungstasten können ebenfalls über WLAN getriggert werden.

3.) Anstatt der vorgeschlagenen WatchDog-Methode, gibt es auch noch die Möglichkeit, den Bootloader direkt per Software aufzurufen (wie eine Funktion):

Code: Alles auswählen

{
INTERRUPTS AUS
UART-PUFFER FLUSHEN

void (* start_bootloader)(void) = (void *)0x7c00;	// fuer ATmega32
start_bootloader();

// wird nie erreicht
}
Details zum Bootloader stehen im Prozessordatenblatt, das hier verlinkt ist. Im Datenblatt des ATmega644 sind die Erklärungen deutlich ausführlicher, es empfiehlt sich bei Verständnisfragen also, dieses zu lesen.
Genau diese Variante würde ich gern einschlagen, das klingt für mich am sinnvollsten. Da ich mich aber im Code des bots nicht so sehr auskenne wie du, weiß ich nicht was ich genau dafür machen muss. Kann mir da wer helfen? Ich habe außerdem das Problem, dass ich das bis Donnerstag geschafft haben muss, also wäre ich über jede Hilfestellung dankbar!

eax
Friends of Robby
Friends of Robby
Beiträge: 755
Registriert: 18 Jan 2006, 16:16
Wohnort: Karlsruhe

Beitrag von eax » 07 Okt 2008, 18:34

huetz hat geschrieben:Soetwas wie den Sim oder das Applet gibt es in meinem Fall nicht, also besteht keine zweite Verbindung neben dem avrdude. Nur dieser baut eine Verbindung auf, welche dann wieder abgebaut wird.
Ach so, dann ist das mit RemoteCall oder Fernbedienung natürlich hinfällig. Außer du implementierst das ct-Bot-Protokoll in einer eigenen Anwendung, dann ergibt sich aber dasselbe Problem (wenn irgendwer einen Befehl zum Reset gibt, muss er vorher auch eine Verbindung zum Bot haben).

Wenn wirklich ausschließlich avrdude mit dem Bot kommunizieren soll, wäre es wohl am besten, dass der Bot den eingehenden Datenverkehr auswertet und bei Flash-Aufforderung (siehe avr109-Protokoll) den Bootloader startet. Dafür müsste der Kommunikationscode aber komplett umgebaut werden - der Botcode geht bisher immer davon aus, dass er nur mit dem Sim / Applet kommuniziert.
huetz hat geschrieben:Genau diese Variante würde ich gern einschlagen, das klingt für mich am sinnvollsten. Da ich mich aber im Code des bots nicht so sehr auskenne wie du, weiß ich nicht was ich genau dafür machen muss. Kann mir da wer helfen?
Du brauchst eine Funktion, die den Reset auslöst oder den Bootloader aufruft, die steht ja schon oben. Diese Funktion muss der Bot aufrufen, sobald eine Flash-Aufforderung eintrifft. Ich hätte das über Remote-Call oder Fernbedienungscode vom Sim gemacht, bei einer eigenen Anwendung musst du entweder etwas ähnliches selbst implementieren (der Kommunikationscode vom Sim ist in Java geschrieben), oder dem Bot beibringen, dass er erkennt, wann avrdude ihm ein hex-File übertragen möchte. In diesem Fall rufst du die o.a. Funktion dann auf, sobald die einkommenden Daten entsprechend interpretiert wurden. Beides erfordert natürlich einiges an Aufwand, weil es bisher nicht vorgesehen ist - Kommunikation zwischen Bot und Sim ist die im Framework implementierte Variante.
huetz hat geschrieben:Ich habe außerdem das Problem, dass ich das bis Donnerstag geschafft haben muss, also wäre ich über jede Hilfestellung dankbar!
Dann brauchst du hoffentlich nicht besonders viel Schlaf... ;-)
Ich habe vor Donnerstag leider überhaupt keine Zeit mehr, dir da weiterzuhelfen.

Grüße,
Timo

huetz

Beitrag von huetz » 07 Okt 2008, 20:03

Ich habe im Netz eine Arbeit zum Thema ctbot gefunden, in der ein reset command im bot registriert wurde und dann von einem applet aus aufgerufen wird. Dieser Befehl startet dann den WDT, welcher den Bot resettet.

Nur hab ich keine Ahnung was für ein Kommando hier gemeint ist.

Kann man nicht eine Art Kommando registrieren, welches über telnet ausgelöst werden kann? Wenn ein bestimmtes Zeichen über telnet gesendet wird, dass dann einfach eine Funktion aufgerufen wird, in der halt der WDT aktiviert wird.

Zeitlich wird eng, das stimmt schon :) Aber immerhin weiss ich wo das Problem liegt, das ist schon verdammt viel wert :)

huetz

Beitrag von huetz » 08 Okt 2008, 09:34

Ich kann ja per telnet auf den Bot connecten, z.b. auf den im Wiport eingetragenen Port 10001. Kann ich auf diesem Port im Bot code Zeichen entgegen nehmen? Wenn ja, dann könnte ich doch einfach auf den Erhalt eines bestimmten Zeichens hin eine WDT-Funktion starten. Ich hab nur überhaupt keinen Plan wie ich da ein Zeichen entgegen nehme.

Antworten