Forum: Mikrocontroller und Digitale Elektronik Bootloaderprobleme ATmega644p


von Florian H. (hucky20)


Lesenswert?

Hi!

Ich versuche gerade einen Bootloader... Aber Es funktioniert nicht! Hab 
alles bis aufs Grundgerüst runtergebrochen! der inhnat des bin.-files, 
das letztendlich geflasht werden soll steht im Array test[] .  Ist der 
Bootloader fertig mit schreiben und startet er immer wieder neu, obwohl 
er ja zum Application-Teil also Adresse 0 springen soll. hat jemand ne 
Ahnung?

Lineroptions :+= -Wl,-section-start=.text=0x7000
Fuses: bootloadersize auf 4096
       bootrst ist auf 0 (häkchen in avrstudion)

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#include <avr/boot.h>
5
6
7
uint8_t test[]={  0x0C,0x94,0x3E,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,
8
          0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,
9
          0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,
10
          0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,
11
          0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,
12
          0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,
13
          0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,
14
          0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x0C,0x94,0x48,0x00,0x11,0x24,0x1F,0xBE,
15
          0xCF,0xEF,0xD0,0xE1,0xDE,0xBF,0xCD,0xBF,0x0E,0x94,0x4A,0x00,0x0C,0x94,0x5B,0x00,
16
          0x0C,0x94,0x00,0x00,0x87,0xB1,0x8C,0x63,0x87,0xB9,0x4C,0xE3,0x29,0xE1,0x30,0xE0,
17
          0x88,0xB1,0x84,0x27,0x88,0xB9,0x88,0xE8,0x93,0xE1,0xF9,0x01,0x31,0x97,0xF1,0xF7,
18
          0x01,0x97,0xD9,0xF7,0xF5,0xCF,0xF8,0x94,0xFF,0xCF  };
19
20
21
void app_start(void)
22
{
23
  cli(); 
24
  MCUSR= 0; 
25
  asm volatile("jmp 0x0000"); 
26
}
27
28
29
int main()
30
{
31
  //LED blinken
32
  DDRC |= (1<<PC2);   //LED
33
  for(uint8_t t=0; t<10; t++)
34
  {
35
    PORTC ^= (1<<PC2);
36
    _delay_ms(200);
37
  }
38
  uint16_t page;
39
  for(page=0;page<sizeof(test) ;page+=SPM_PAGESIZE)
40
  {
41
42
    eeprom_busy_wait ();
43
    boot_page_erase(page);
44
    boot_spm_busy_wait ();
45
46
47
    for (uint16_t j=0; j<SPM_PAGESIZE; j+=2)
48
    {
49
50
      boot_page_fill(page + j, ((uint16_t)(test[j+1+page*SPM_PAGESIZE]<<8)) + (test[j+page*SPM_PAGESIZE])    );
51
     
52
    }
53
54
    boot_page_write(page);
55
    boot_spm_busy_wait();
56
    boot_rww_enable();
57
  }
58
  //LED blinken
59
  for(uint8_t t=0; t<10; t++)
60
  {
61
     PORTC ^= (1<<PC2);
62
     _delay_ms(500);
63
  }
64
  PORTC &= ~(1<<PC2);
65
  _delay_ms(5000);
66
  app_start();
67
  for(;;);
68
  return 0;
69
}

Grüße Flo

von Matthias (Gast)


Lesenswert?

Wenn dein HAuptprogramm ISRs enthält würde ich Dir vorshclagen, dass Du 
das IVSEL Bit im MCUCR setzen/löschen (siehe Datenblatt).

Wenn man die Reset-Fuse setzt (start im Bootloader, dann werden auch die 
IRQ VEktoren umgebogen auf den Bootloaderbereich!9 Das muss man dann 
wieder
selber hinbiegen, bevor man die Applikation startet...

von Doktor Gnadenlos (Gast)


Lesenswert?

probier mal das für den Sprung in die Applikation

void (* start_application) (void); // Definition Variable als 
Funktionszeiger


start_application = 0x0000; // Adresse fuer Einsprung
start_application();     // und aufrufen

von g457 (Gast)


Lesenswert?

..nur der Vollständigkeit halber: Was ∗genau∗ soll das..

> MCUSR= 0;

erreichen? (JTAG aktivieren? IVSEL auf 0 setzen funktioniert so nicht!)

Normalerweise(tm) lässt man sich für einen sauberen Reset vom Watchdog 
beissen, dabei werden auch die Port-Konfiguartionen/.. auf die 
Standardwerte gesetzt, nicht potentiell auf einen Mischmasch.

von Hc Z. (mizch)


Lesenswert?

Und noch was:

Florian H. schrieb:
> Lineroptions :+= -Wl,-section-start=.text=0x7000
--------------------------------------------^^^^^^

Adressen beim avr-gcc sind *Byte*adressen.  Ich nehme mal an, dass 
deshalb 0xf000 gemeint ist (außer Dein Bootloader belegt mehr als die 
Hälfte des Flash).

von Florian H. (hucky20)


Lesenswert?

Hi so hab das mit IVSEL ausprobiert. Laut Datenblatt:
>to change the IVSEL bit:
>a. Write the Interrupt Vector Change Enable (IVCE) bit to one.
>b. Within four cycles, write the desired value to IVSEL while writing a >zero to 
IVCE.

also Funktion zum Jumpen ist nun:
1
void (* start_application) (void);
2
void app_start(void)
3
{
4
  start_application = 0x0000;
5
  MCUCR |= (1<<IVCE);
6
  asm volatile ("nop");
7
  asm volatile ("nop");
8
  asm volatile ("nop");
9
  asm volatile ("nop");
10
  MCUCR &= ~(1<<IVSEL);
11
  //asm volatile("jmp 0x0000"); 
12
  start_application();
13
}

@ Natthias: hab es mit
1
asm volatile("jmp 0x0000");
und
1
start_application();
wie du gemaint hast probiert! keine Änderung

Fazit: Selbes Verhalten wie vorher!



Gruß Flo

von Florian H. (hucky20)


Lesenswert?

@ Hc Zimmerer:

Die Scheixxe jeeeeehhhhhhhhhhhhhhhhhttttttt!!!


Danke allen!

von Doktor Gnadenlos (Gast)


Lesenswert?

@Hc Zimmerer
Das ist mir auch schon aufgefallen. Eigentlich dürfte der Bootloader gar 
nicht starten. Florian H. schreibt aber, dass der Bootloader sehr wohl 
losläuft, er kommt nur nicht in die Application Section.

von Hc Z. (mizch)


Lesenswert?

Florian H. schrieb:
>>to change the IVSEL bit:
>>a. Write the Interrupt Vector Change Enable (IVCE) bit to one.
>>b. Within four cycles, write the desired value to IVSEL while writing a >zero to
> IVCE.
>
> also Funktion zum Jumpen ist nun:void (* start_application) (void);
1
> void app_start(void)
2
> {
3
>   start_application = 0x0000;
4
>   MCUCR |= (1<<IVCE);
5
>   asm volatile ("nop");
6
>   asm volatile ("nop");
7
>   asm volatile ("nop");
8
>   asm volatile ("nop");
9
>   MCUCR &= ~(1<<IVSEL);

Das ist genau falsch herum verstanden.  Lies Dir b) nochmal durch.  Du 
musst nicht 4 Zyklen warten, sondern innerhalb von 4 Zyklen schreiben.

Übrigens: die Byte-Entsprechung zur Wortadresse 0x7000 ist 0xE000 (um 
meinen Flüchtigkeitsfehler zu korrigieren).

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
Noch kein Account? Hier anmelden.