Bootloaderprobleme ATmega644p

OP #1820979
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
Gast #1821003
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...
Gast #1821041
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
Gast #1821093
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.
OP #1821143
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
Gast #1821151
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.
#1821177
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).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren