Hi!
Ich möchte in meinem Projekt den bereits im AT90USB1287 vorhandenen
Bootloader verwenden. Momentan weiß ich noch nicht wo der her kommt,
aber beim STK525 und seinen mitgelieferten AVRs ist einer drinn, den man
per HWB also Taste an PE2 aktivieren kann.
Ich möchte den Bootloader aber aus der Applikation auf dem AVR direkt
anspringen und damit die Taste überflüssig machen.
Leider schaffe ich es auch nach allem Suchen in diesem Forum nicht.
Die Einsprungssequenz sieht bislang wie folgt aus:
1
{
2
_CLI();
3
_delay_ms(1000);
4
5
MCUCR=(1<<IVCE);
6
MCUCR=(1<<IVSEL);
7
asmvolatile("jmp 0x1E000");
8
}
d.h. damit mir keine Interrupts dazwischen kommen, klemme ich sie ab und
warte auch noch eine Zeit lang, in der aber nichts passieren dürfte.
Dann schalte ich die Vectoren um und springe auf den Reset-Vector im
Bootloader.
Die Lock-/Fusebits sind wie folgt durch ATMEL vorgeliefert und
hoffentlich durch meine Software korrekt ausgelesen:
Lockbits: 0xEC
FB_High: 0x99
FB_Low: 0x5E
Ext_FB: 0xF3
Was mich zu dem Schluss führt, dass der vorhandene Bootloader 8kByte,
bzw. 4kWord groß ist. Das deckt sich auch mit der Aussage des
Datenblattes bzgl. der Bootloaders von Atmel, dass dessen Codegröße mit
5kByte angibt.
{
_CLI();
_delay_ms(1000);
MCUCR = (1<<IVCE);
MCUCR = (1<<IVSEL);
asm volatile ("jmp 0x1E000");
}
Vielen Dank schon mal für Eure Hilfe
Gruß, Ulrich
Schau Dir bitte die Dokumentation der _delay-Funktionen in der
libc-Dokumentation mal an. _delay_ms(1000) geht nur mit Taktfrequenzen
unter 250 kHz, und ich vermute, dass Du eher mit höheren Taktfrequenzen
arbeitest...
Jep, ist korrekt, aber egal, da sich das angesprochene Problem, nämlich
der Sprung in den Bootloader auch ohne, oder mit einem kurzen Delay
nicht bewerkstelligen lässt.
Trotzdem Danke für den Hinweis.
hallo,
ich kenne den bootloader zwar nicht. aber vermutlich wird der eine
bestimmte weile einen port pin abfragen, und bei erkennen einer
bedingung nicht weiter springen, sondern im BL-modus bleiben.
das problem dürfte imho sein, dass deine anwendung den pn nicht setzt.
der bootloader wird also korrekt angesprungen, merkt, dass es nichts für
ihn zu tun gibt, und er springt wieder zurück.
oder gibt es ein debugging, welches den start des BL anzeigt? wenn ja,
wann im code?
bye kosmo
Da bin ich noch nicht richtig durchgestiegen. Auf der einen Seite sagen
die Fuses, dass der Bootloader nicht aktiv ist. Also fällt die Variante
mit dem PE2 als Pin Abfragen flach. Andererseits hat der AT90USB1287
irgendwie eine Sonderfunktion auf diesem Pin, die den Bootloader
aktiviert.
Ich habe am Montag erst mit diesem USB AVRs angefangen. Bie den bislang
gerne und häufig von mir eingesetzten ATmegas gab es keinen
vorinstallierten Bootloader, bzw. es gab keine Notwendigkeit überhaupt
einen BL zu verwenden.
Mit dem AT90USB ist es jedoch genau anders. Der vorinstallierte BL macht
den Chip mit wenigen Handgriffen programmierbar über USB und damit einen
eigenen ISP Port völlig überflüssig.
Im Grunde ist es nicht tragisch, da bei der Erstprogrammierung eh über
diesen Taster oder über einen ISP oder JTAG Programmer gegangen werden
muss, aber es wäre später praktisch, wenn man das System direkt über
seine PC-Seitige Software updaten könnte, ohne Programmer und spezielle
Software.
Naja, und dann ist auch ein Grund, dass der HWB Taster ( der an PE2)
sich bereits nach einer Woche verabschiedet hat. Ich habe aber keine
Lust das Teil deswegen umzutauschen.
Gruß, Ulrich
hallo,
>Andererseits hat der AT90USB1287>irgendwie eine Sonderfunktion auf diesem Pin, die den Bootloader>aktiviert.
steht in der doku, page 357. auf der nachfolgenden seite gibts auch ein
schönes ablauf-diagramm.
was genau funktioniert denn nicht? der installierte BL meldet sich
vermutlich nicht. läuft die application erneut?
bye kosmo
Hi Kosmo!
Danke für den Tip, habe das jetzt mal schnell überflogen mit dem HWBE.
Wenn ich mit obigem Code in den Bootloader springe, dann passiert nichts
mehr, sprich, das System friert ein.
Meine Applikation steuert die LEDs auf dem STK525 für ein paar
rudimentäre Statusausgaben an und man kann erkennen, dass meine SYS-LED,
die durch den Taskmanager getoggelt wird, einfach ihren Stand beibehält.
Es wird also nichts mehr ausgeführt.
Ich versuche gerade mal in den LST files herum zu suchen, was aus meinem
Code an dieser Stelle gemacht wird. Aber ich sehe halt nur meinen Code
und die Adresse 0x1E000 als Ziel. Da ich auf das Demoprojekt für ein CDC
( UART-USB-Bridge) aufsetzte muss ich das externe Makefile verwenden.
Darin war die Ausgabe der LST files abgeklemmt und ich habe das nur
notdürftig aktivieren können. So erhalte ich für Parameter nur dezimale
Zahlen anstatt Hex. Muss da noch mit dem Compiler-Parametern spielen.
Gruß, Ulrich
hallo,
schau doch mal, ob das HWBE auch die interruptvektoren ändert. ich denke
nämlich nicht. falls dem so ist, kommt durch dein umsetzen bei einem irq
totaler müll heraus. in dem fall am besten irq's aus, ivsel so lassen
wie's ist und gucken, was passiert.
bye kosmo
Das war mein erster Angang, einfach nach 0x1E000 springen, vorher nur
noch _CLI(). Geht auch nicht.
Habe mir auch mal ein dump geschrieben. Kann jetzt beliebigen FLASH
auslesen.
Meinen eigenen Code sehe ich auch, aber den Bootloader sehe ich
nirgendwo. weder ein dump 0xe000 noch ein dump 0x1E000 noch irgendwas
dazwischen liefert etwas anderes als 0xffff als Ausgabe. Wie gesagt, ein
dump 0x0 funktioniert einwandfrei, ich sehe meinen eigenen Code.
Den fuses nach zu urteilen ist aber nur ein (E)SPM blockiert, ein (E)LPM
sollte gehen, also müsste ich auch per pgm_read(_byte/_word)( addr) auf
den bootloader lesen zugreifen können.
Der hat aber einen sehr zähen Versteckungsfaktor :)
Gruß, Ulrich
Reset-Vector fuse auf boot-section stellen, in der Applikation Watchdog
aktivieren und per Endlosschleife "zuschlagen" lassen. Methode ist
demonstriert in der Atmel Beispielanwendung und dem Bootloader für den
AVR Butterfly.
Wenn man den Original-Bootloader von ATMEL benutzt, wird das direkte
aufrufen egal in welcher Form nicht funktionieren. Der Bootloader wird
ja immer nach dem Reset gestartet, hier wird getestet ob HWB auf Masse
liegt und wenn ja, wird der Bootloader gestartet.
Ich sehe die einzige Möglichkeit, den Bootloader aus einer Anwendung zu
starten in einer Hardwarelösung (z.B. den HWB-Pin per Portpin und
Flipflop auf Masse legen) oder einfach einen eigenen Bootloader
schreiben (was ich persönlich bevorzuge).
Erwin
Ich habe das erst einmal nicht weiter verfolgt, da der eigentliche
Applikationscode wichtiger war als die Option die Module auch über das
Netz updaten zu können.
Grundsätzlich hatte ich drei Probleme bei der ganzen Bootloader
Geschichte:
1) Memory-Defines:
Wie kann ich dem Compiler (WinAVR) klar machen, dass meine CPU nicht 32k
FLASH hat sondern z.B. nur 31k ( weil 1k fest für den Bootloader
vergeben ist) eines der Segmente wurde nämlich immer am Ende, also
Top-Down im Flash abgelegt und kollidierte damit mit dem gegen schreiben
geschützten Bootloader.
2) Wiederverwendbarkeit:
Ich möchte nicht den Code des Bootloaders in jedes Projekt eibauen. Er
sollte als eigenständige Software funktionieren und getrennt geflasht
werden können. Dazu müsste ich dem Compiler sagen, dass er nun einen
Bootloader erzeugt, der nicht bei 0x0000 anfängt, sondern z.B. bei
0xec00 und nur 0x0400 lang ist.
3) Um das ganze zu testen hatte ich den HWB doppelt genutzt. In der
normalen Software wird der HWB Button abgefragt, und wenn er gedrückt
ist, soll der Bootloader angesprungen werden. Wird der angesprungen,
dann ist der HWB immer noch gedrückt und er Bootloader sollte sich
aktivieren. Das ist mir aber nicht gelungen. Vermutlich, weil ich 1) und
2) schon nicht lösen konnte.
Das ganze ist jetzt schon über ein Jahr her und witziger weise taucht
die Anfrage nach einem Bootloader nun wieder auf. Ist auch logisch, weil
man sonst an über 100 Platinen in einem großen Schrank jeweils den
AVRISP anstöpseln müsste um die Stück für Stück zu aktualisieren. Ist
schon komisch, dass Du diesen Thread ausgerechnet jetzt ausgräbst. Aber
fein, ich warte zusammen mit Dir mal auf die meist sehr hilfreichen
Ideen aus diesem Board.
Gruß, Ulrich
Moin,
ich hab es jetzt endlich hin bekommen.
Ich beschreib mal kurz was ich gemacht habe.
Ich möchte über einen USB-Befehl das Device in den Bootloader versetzen,
ohne das über die Hardware zu machen. Dazu nutze ich den Standard
Bootloader von Atmel. Mit der Software Flip möchte ich die Firmware
flashen. Die Fuses habe ich auf Standard stehen lassen, d.h.
"Hardware Boot Enable" kein Fuse gesetzt,
"Boot Reset vector Enable" kein Fuse gesetzt,
"Boot Flash size=4096 words start address=$F000" Fuse gesetzt.
Die Firmware muss, wie in dem HID-Codebeispiel von Atmel, um folgendes
ergänzt werden.
void (*start_bootloader) (void)=(void (*)(void))0xf000;
if( jump_bootloader == 0x01 )
{
Usb_detach(); //! Detach actual generic HID
application
for(tempo=0;tempo<70000;tempo++);//! Wait some time before
(*start_bootloader)(); //! Jumping to booltoader
}
Im meinem Fall ist es noch wichtig, dass die Timer-Interrupts
deaktiviert werden müssen.
#define Disable_timer_int() ( TIMSK0 = 0x00,\
TIMSK1 = 0x00,\
TIMSK2 = 0x00 )
Das war der ganze Trick.
mfg