Hallo zusammen, ich poste jetzt doch mal mein Anliegen, obwohl ich glaube, daß mir hier keiner weiterhelfen kann. :-( Folgendes: Ich habe auf einem atmega168 einen funktionierenden avr109 Bootloader mit dem ich Daten an x-belibiger Stelle im Flash speichern und Seitenweise auch wieder löschen kann. Schreibe ich ein Programm an den Anfang des Flash wird das Programm ausgeführt und nach einem Reset komme ich auch wieder in den Bootloader. Will ich jetzt Daten mit mehr als 15 Byte Länge an eine Leere Stelle im Flash schreiben und ich verlasse dann den Bootloader wieder, dann hängt sich der Bootloader auf und ist nicht mehr bedienbar. Das Programm läuft dann auch nicht mehr. Bei weniger als 16Byte klappt das einwandfrei und wenn keine Applikation drauf läuft auch über 15Byte. Mache ich das ganze von Hand über ein Terminal funktionierts auch. Ich bin irgendwie total überfragt??
subguru schrieb: > ich poste jetzt doch mal mein Anliegen, obwohl ich glaube, daß mir hier > keiner weiterhelfen kann. :-( Stimmt, bei so wenig Information ist das unmöglich. Quellcode des Bootloaders Fuse-Setting Wie wird der Bootloader nach nem Reset gestartet? Quellcode der Applikation Wie werden die Flash-Daten geschrieben (aus der Applikation heraus)? Peter
Danke schon mal im voraus! Bootloader ist der wie im Applikation Note AVR109 Self Programming von Atmel mit ein paar Änderungen:
1 | .
|
2 | .
|
3 | void wdt_init(void) __attribute__((naked))_attribute__((section(".init1"))); |
4 | .
|
5 | .
|
6 | // Prolog AVRBOOT to Run Bootloader
|
7 | for(temp_int=0;temp_int<2048;temp_int++){ |
8 | if(UART_STATUS_REG & (1 << RECEIVE_COMPLETE_BIT)){val=UART_DATA_REG;} |
9 | if (temp_int==1){sendchar('\n');sendname();} |
10 | sendchar(' '); |
11 | sendchar(8); |
12 | }
|
13 | |
14 | |
15 | /* Branch to bootloader or application code? */
|
16 | if( val=='F' ) |
17 | {
|
18 | /* Main loop */
|
19 | .
|
20 | .
|
21 | // Page erase.
|
22 | else if(val=='W') |
23 | {
|
24 | // NOTE: Here we use address as a byte-address, not word-address, for convenience.
|
25 | _WAIT_FOR_SPM(); |
26 | #ifdef __ICCAVR__
|
27 | #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
|
28 | #endif
|
29 | _PAGE_ERASE( (address << 1) ); // Word address to bytes |
30 | #ifdef __ICCAVR__
|
31 | #pragma diag_default=Pe1053 // Back to default.
|
32 | #endif
|
33 | |
34 | sendchar('\r'); // Send OK back. |
35 | }
|
36 | .
|
37 | .
|
38 | void wdt_init(void) |
39 | {
|
40 | MCUSR = 0; |
41 | wdt_disable(); |
42 | |
43 | return; |
44 | }
|
Das mit dem Watchdog disablen habe ich hinzugefügt, weil ich von der Applikation heraus mit folgender Funktion einen Reset mache:
1 | // reset
|
2 | void reset_wrapper(uint8_t *buf) |
3 | {
|
4 | _delay_ms(2); |
5 | cli(); |
6 | wdt_enable(WDTO_15MS); |
7 | wdt_reset(); |
8 | |
9 | }
|
Der Bootloader startet nach einem Exit bei void (*funcptr)( void ) = 0x0000; Fuses sind wie folgt: low=C7 high=DF ext=F8 Die Flash Daten schreibe ich über den Bootloader mit der BlockLoad Funktion also z.b mit B 00 10 F kann ich per Hand 16Bytes schreiben über ein C oder Java Prog geht das nicht mehr, nur bis zu 15Byte. Unter Java mach ichs z.b. so:
1 | byte[] addr={0x41,0x11,0x00};// Set 'A'ddress to 2200 |
2 | try { |
3 | outStream.write(addr); |
4 | |
5 | |
6 | byte[] erase={0x57};// 'W' erase |
7 | try { |
8 | outStream.write(erase); |
9 | |
10 | byte[] writemacro={ 0x42,0x00,0x10,0x46}; // B 00 xx F |
11 | |
12 | try { |
13 | outStream.write(writemacro); |
14 | |
15 | byte[] dat={0x2f}; |
16 | |
17 | try { |
18 | outStream.write(dat); // hier 16x |
Der Bootloader quittiert mir das auch alles ordentlich mit 0x0D so wie in der AppNote angegeben.Der Bootloader ist nach dem Schreiben der Daten noch voll funktionsfähig und hat die Daten auch geschrieben. Nach einem 'E'xit ists aber dann vorbei. Wie gesagt per Hand über ein Terminal Prog funkt.
Oh Mann, ich habs ich darf kein '/' also 0x2f als Daten senden. Kann das irgend jemand nachvollziehen weshalb? Sowas ist irgendwie unergründlich.
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.