Hi
Ich versuche zurzeit eine andere Möglichkeit zum Bootloader zu springen
als jedesmal die Stromversorgung zu kappen. Ich nutze den Avrootloader
Beitrag "AVR-Bootloader mit Verschlüsselung" und resette über den Watchdog
bei einem empfangenen Zeichen über rs232.
Ich beschreibe mal die Problematik:
- Avr mit Strom versorgen
->Bootloader wartet 0.25s und startet Programm
->Programm läuft wie gewohnt
- Über die PC-Software den Bootloader verbinden
->Avr resettet sich und springt in Bootloader
- Disconnect des Bootloaders
->Blinken der LED-Anzeige ->Avr resettet sich die ganze Zeit
main.c
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<avr/pgmspace.h>
4
#include<avr/wdt.h>
5
6
#include"keys.h"
7
#include"display.h"
8
#include"animation.h"
9
#include"uart.h"
10
11
#define F_CPU 6144000
12
13
charbuffer[5];
14
15
intmain(void)
16
{
17
//Watchdog deaktivieren
18
cli();
19
wdt_disable();
20
wdt_reset();
21
uart_init(UART_BAUD_SELECT(38400,F_CPU));
22
uart_puts_P("Init Display\r\n");
23
display_init();
24
uart_puts_P("Init Keys\r\n");
25
keys_init();
26
sei();
27
animation_init();
28
for(;;)
29
{
30
if(animation_update_required)
31
animation_update();
32
if(keys_changed)
33
{
34
animation_next();
35
keys_changed=0;
36
}
37
if((unsignedchar)uart_getc())
38
{
39
cli();
40
wdt_enable(0);
41
for(;;)asmvolatile("nop");
42
}
43
}
44
}
Kann es sein das sich der Watchdog mit den obrigen Zeilen nicht
ausschalten lässt? Eine fehlende ISR kann es ja nicht sein, da es, wenn
der Watchdog noch nicht gestartet worden ist, noch funktioniert.
Hier noch die Konfiguration des Bootloaders:
1
.equ UseWDR = 1 ; set to 0/1 to de/activate WatchDog
2
.equ UseAutobaud = 1 ; set to 0/1 to de/activate Baudrate Detection
3
.equ UseVerify = 1 ; set to 0/1 to de/activate Verify FLASH Command, FLASH write/erase includes implicit verify, can be deactivated
4
.equ UseE2Write = 1 ; set to 0/1 to de/activate EEPROM Write Command
5
.equ UseE2Read = 1 ; set to 0/1 to de/activate EEPROM Read Command
6
.equ UseSRAM = 0 ; set to 0/1 to de/activate SRAM Commands
7
.equ UseCrypt = 0 ; set to 0/1 to de/activate cryptography
8
.equ UseCryptFLASH = 0 ; set to 0/1 to de/activate only use cryptography for writing to FLASH
9
.equ UseCryptE2 = 0 ; set to 0/1 to de/activate only use cryptography for writing to EEPROM
10
.equ UartInvert = 1 ; set to 1 to invert UART levels, for RS232 drivers such as MAX232
11
12
.equ RX_PORT = PORTD ; Receive Port and Pin
13
.equ RX = PD0
14
.equ TX_PORT = PORTD ; Transmit Port and Pin
15
.equ TX = PD1
16
17
.set XTAL = 6144000 ; only important for BootDelay if Autobaud is used
18
.set BootDelay = XTAL/4 ; 250ms
19
.set BootBaudrate = 38400 ; only used if no Baudrate Detection activated, XTAL is important
20
.set BootVersion = 2 ; Version 2
21
.set BootCodeSize = 502 ; compile and set to value in [.cseg] Used, compile again
Michael H. schrieb:> Ist der Bootloader vielleicht zu langsam, um den Watchdog innerhalb von> 15ms zurückzusetzen?> Nimm doch anstattwdt_enable(0); einfach malwdt_enable(WDTO_500MS)
Der müsste eigentlich damit arbeiten. Denn er braucht 250ms und kommt
durch. Nachdem reset müsste die Zeit zurückgesetzt sein (auf 15ms),
deswegen sollte es nicht helfen. Aber probieren werde ich es mal.
Ganz vergessen, ich nutze den Atmega48.
EDIT: Gleiches Phänomen.
Könnte man den Controller auch anderst resetten? Irgendwie muss man
doch in den Bootloader springen können. Aber ein rjmp wäre wohl nicht
die elegante Lösung.
Samuel K. schrieb:> Könnte man den Controller auch anderst resetten?
Wenn du noch einen Port frei hast, kanns du den Reset auch damit einfach
auf GND ziehen. Der Rest geht dann von selbst.
Samuel K. schrieb:> Aber ein rjmp wäre wohl nicht>> die elegante Lösung.
Warum denn nicht?
Setz' einfach einen Funktionspointer auf den Anfang der Bootsection.
mfg.
Thomas Eckmann schrieb:> Warum denn nicht?
das klappt nicht: pointer stimmen nicht, register werden nicht
zurückgesetzt, usw...
ein watchdog-reset muss funktionieren.
Samuel K. schrieb:> ->Avr resettet sich und springt in Bootloader
soweit alles klar
> - Disconnect des Bootloaders
was heißt "disconnect"? hat er die applikation geladen?
> ->Blinken der LED-Anzeige ->Avr resettet sich die ganze Zeit
welche led-anzeige? wo ist der code dazu?
Michael H. schrieb:> Thomas Eckmann schrieb:>>> Warum denn nicht?>> das klappt nicht: pointer stimmen nicht, register werden nicht>> zurückgesetzt, usw...
Aber sicher klappt das.
mfg.
Michael H. schrieb:>> - Disconnect des Bootloaders> was heißt "disconnect"? hat er die applikation geladen?
Mit disconnect trenne ich den Bootloader von der PC-Software. Der
bootloader startet dann deas eigentliche Programm. Ein neues Programm
muss man gar nicht laden, man kann einfach verbinden und die Verbindung
wieder trennen (das mache ich zum Test).
>> ->Blinken der LED-Anzeige ->Avr resettet sich die ganze Zeit> welche led-anzeige? wo ist der code dazu?
2*7Segmente. Das ist alles Interrupt gesteuert. Genauso wie die
Tastenabfrage. Aber wenn es beim ersten mal klappt müsste es doch dann
auch funktionieren.
Ich kann den Code vom Display mal posten aber versprech dir nicht so
viel davon, ich hatte keinen Port mit 7 freien Pins und deswegen ist es
eine blöde Bitschieberei. Der Asm-Code ist exterm uneffektiv. Aber bei
50Fps macht das nichts aus.
display.c
1
#include"display.h"
2
3
constuint8_tfont[]PROGMEM={
4
0b00111111,// 0
5
0b00000110,// 1
6
0b01011011,// 2
7
0b01001111,// 3
8
0b01100110,// 4
9
0b01101101,// 5
10
0b01111101,// 6
11
0b00000111,// 7
12
0b01111111,// 8
13
0b01101111};// 9
14
15
volatileuint8_tdata[DIGITS];
16
volatileuint8_tdigit;
17
volatileuint8_tdigit2;//= 2^digit
18
19
20
#define PD2_7 (~(( 1 << PD0 ) | ( 1 << PD1 )))
21
#define PB0_1 ((1 << PB0) | (1 << PB1))
22
23
voiddisplay_init(void)
24
{
25
//Ausgange definieren
26
DDRD|=PD2_7;//PORTD als Ausgang schalten bis auf PD0 und PD1
27
DDRC|=1<<PC3;//PC3 als Ausgang schalten (7. Segment)
28
DDRB|=PB0_1;//PB0 und PB1 als Ausgang schlaten (Backplane)
29
30
//Timer2 konfigurieren
31
TCCR2B=(1<<CS22)|(1<<CS20);//Prescaler 256
32
//Multiplex-Frequenz wird durch F_CPU / 256 / Prescaler / DIGITS errechnet
Die animation.c ist ein bisschen länger. Um die als Fehlerquelle
auszuschließen hab ich sie einfach mal auskommentiert, ändert am
Programm ablauf aber nichts.
Michael H. schrieb:> dann widerleg doch bitte die 2 gründe, die ich auf die schnelle>> angeführt habe, warum es eben nicht funktioniert.
Ein Grund reicht. Der zweite ist ja nun Blödsinn: > pointer stimmen
nicht
Wenn du meinen Beitrag aufmerksam gelesen hättest, müsstest du diese
Frage gar nicht stellen.
Denn da steht:
>Setz' einfach einen Funktionspointer auf den Anfang der Bootsection.
Das ist der Resetvektor der Bootsection. Dort steht ein Sprungbefehl auf
die Initialisierung des Bootloaders. Und nach dem er sich neu
initialisiert hat, inklusive Stack, geht es in die main des Bootloaders
und der Controller fühlt sich fast wie neu geboren.
mfg.
Samuel K. schrieb:>>> ->Blinken der LED-Anzeige ->Avr resettet sich die ganze Zeit>> welche led-anzeige? wo ist der code dazu?>> 2*7Segmente. Das ist alles Interrupt gesteuert. Genauso wie die
ach, die led-anzeige taucht im code als "display" auf... etzad! das hat
mich etwas verwundert.
ich wollte mir grad das watchdog-handling im bootloader anschauen - kann
es sein, dass du eine alte version des bootloaders benutzt?
neu wäre:
Beitrag "Re: AVR-Bootloader mit Verschlüsselung"
oder mindestens:
Beitrag "Re: AVR-Bootloader mit Verschlüsselung"
lasst du ein verify laufen?
Michael H. schrieb:> ich wollte mir grad das watchdog-handling im bootloader anschauen - kann> es sein, dass du eine alte version des bootloaders benutzt?
Kann sein, ich habe versucht mir eine neuere rauszusuchen, aber der
Thread ist wirklich unüberschaubar geworden.
Ich teste mal die neue.
Thomas Eckmann schrieb:> Das ist der Resetvektor der Bootsection. Dort steht ein Sprungbefehl auf
es gibt auch noch andere zeiger.
> und der Controller fühlt sich fast wie neu geboren.
interruptflags.
ddr-register.
ein rjmp 0 ist und bleibt blödsinn.
denk einfach mal ein bisschen nach, du findest genügend szenarien, mit
denen solches gemurkse schief geht.
Michael H. schrieb:> ein rjmp 0 ist und bleibt blödsinn.
Wer redet denn von rjmp0?
Erst richtig lesen, dann verstehen, dann nachdenken, dann eventuell was
dazu schreiben. Sonst die Klappe halten.
> denk einfach mal ein bisschen nach, du findest genügend szenarien, mit>> denen solches gemurkse schief geht.
Nur weil du keine Ahnung hast, ist das noch lange kein Gemurkse.
mfg.
Ich hatte Version 2, das ist jetzt V6. Ich glaub meiner war schon ein
bisschen zu alt.
Danke für den Tipp, es funktioniert jetzt.
Da der Mega48 sowieso kein Bootloadersupport bietet, ist es auch egal
wie groß der Bootloader ist? also wenn meiner jetzt 550B groß wäre würde
ich nicht 200B verschwenden, oder?
Noch eine Frage: Warum ist der Bootloader so langsam? Mein Programm ist
gerade knapp 700B groß, trotzdem dauert es fast 1s (bei 38400Baud). Die
Baudrate müsste doch für eine schnelleres Programmieren reichen (zum
Vergleich: Mein Usbasp programmiert den ganzen Atmega48 in 1s).
Thomas Eckmann schrieb:> (Zitat: C'era una Volta il West)
Ein sehr passendes Zitat, denn auch Du erreichst den Pazifik mit Deinem
Funktionspointer auf den Anfang der Bootloader-Section nicht - oder
zumindest nur mit großen Umwegen.
Den Funktionspointer könnte man nur verwenden, wenn der Bootloader den
Controller "zu Fuß" auf einen definierten Zustand zurücksetzt. Das ist
ziemlich viel Aufwand, den man sich sparen kann, wenn man einen Reset
ausführt. Nach einem Reset sind die Register nämlich wirklich
jungfräulich. Welche Werte sie jeweils haben, steht sogar in der
Dokumenation.
Für den Reset den Watchdog zu benutzen ist eine gute Idee, weil das in
jedem Board funktioniert, also ohne dass bestimmte Pins in bestimmter
Weise verdrahtet sein müssen.
Andreas schrieb:> Controller "zu Fuß" auf einen definierten Zustand zurücksetzt. Das ist>> ziemlich viel Aufwand, den man sich sparen kann, wenn man einen Reset>> ausführt. Nach einem Reset sind die Register nämlich wirklich>> jungfräulich. Welche Werte sie jeweils haben, steht sogar in der>> Dokumenation.
Und was ist dabei das Problem?
mfg.
Thomas Eckmann schrieb:> Und was ist dabei das Problem?
Na genau die oben schon genannten:
Flags von irgendwelchen Interrupts oder auch die DDR Register.
Dumm wäre auch wenn ein Timer in dieser Zeit überläuft. Was passiert
dann?