Forum: Compiler & IDEs Atmega88 Bootloader - Code läuft nicht korrekt


von Markus B. (do9mbs)


Lesenswert?

Hallo,

wenn ich den folgenden Code kompiliere und linke, läuft alles wunderbar 
... PinD1-7 werden auf high gesetzt, der über die serielle Schnittstelle 
gesendet, und Pin3 auf low gesetzt ... danach ist das Programm fertig!

Wenn ich das Ganze jetzt mit der Linker Option -Ttext=0x1800 linke, 
funktioniert das Ganze nur noch soweit, dass alle Pins von PortD auf 
high gesetzt werden ...

Kann mir hier jemand weiterhelfen? Ich weiß nicht mehr, warum der Code 
nicht ausgeführt wird ...

Die Werte meiner FuseBits:
LowFuse:0xE2
HightFuse:0xD2
ExtFuse:0xF8 (Bootvectorsize=1024Words;Start=0x0C00).

Anhand der Fusebits sollte doch eigentlich alles OK sein? Oder habe ich 
da einen Denkfehler drin?


#define F_CPU 8000000
#define theB_BOOTLOADER_TYPE 99

#if (theB_BOOTLOADER_TYPE==99)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/boot.h>
#include <util/delay.h>
#include "uart.h" //uartlib von Peter Fleury

#define BOOT_UART_BAUD_RATE     9600     /* Baudrate */
#define XON                     17       /* XON Zeichen */
#define XOFF                    19       /* XOFF Zeichen */

int main()
{
  DDRD=0xFF;
  PORTD=0xFF;
  _delay_ms(1000);
    uart_init( UART_BAUD_SELECT(BOOT_UART_BAUD_RATE,F_CPU) );
  sei();

    uart_puts("Testausgabe Bootloader\n\r");


  _delay_ms(1000);
  PORTD=0x14;

  return 0;
}
#endif

von Tom M. (Gast)


Lesenswert?

Ich vermute, dass der uart Interrupt den Crash verursacht. Wo liegen die 
Vektoren bzw. wie sind die Fuses dafür gesetzt? Schau dazu ins 
Datenblatt, dafür gibts ein eigenes Kapitel, und ins Wiki, da gibts nen 
Artikel xu "bootloader in c" o.ä.

von Markus B. (do9mbs)


Lesenswert?

Hallo,

alles klar ... der Fehler sass vorm PC ...
ich habe in der Tat vergessen die Interrupt Vektoren "zu verbiegen" ... 
jetzt funtioniert es ...

Dank!


73 de Markus

von Uwe (de0508)


Lesenswert?

Hallo Markus,

sei so nett und erkläre uns die Lösung, danke.

73, Uwe

von Markus B. (do9mbs)


Lesenswert?

Uwe S. schrieb:
> Hallo Markus,
>
> sei so nett und erkläre uns die Lösung, danke.
>
> 73, Uwe

Ich hatte vergessen die Interrupt Vektoren "zu verbiegen" (Register 
MCUCR).
Wenn das nicht passiert, springt der Code (beim Auftreten eines IRQ's) 
die "normale" IRQ Vektortabelle (ab 0x0000) an. Da das Programm, bedingt 
durch die Linker Option -Ttext=0x01800, nicht an an der Adresse 0x0000 
beginnt, muss hier entsprechend der Bootloadergröße ein Offset addiert 
werden.

Ich hoffe das war einigermassen verständlich ... ansonsten bitte 
nachfragen.


#define F_CPU 8000000

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/boot.h>
#include <util/delay.h>
#include "uart.h" //uartlib von Peter Fleury

#define BOOT_UART_BAUD_RATE     9600     /* Baudrate */
#define XON                     17       /* XON Zeichen */
#define XOFF                    19       /* XOFF Zeichen */

int main()
{
  DDRD=0xFF;
  PORTD=0xFF;
  _delay_ms(1000);

  uint8_t  temp=0;
  /* Interrupt Vektoren verbiegen */
    temp = MCUCR;
    MCUCR = temp | (1<<IVCE);
    MCUCR = temp | (1<<IVSEL);

    uart_init( UART_BAUD_SELECT(BOOT_UART_BAUD_RATE,F_CPU) );
  sei();
    uart_puts("String stored in SRAM_Test\n\r");
  _delay_ms(1000);

  /* Interrupt Vektoren wieder gerade biegen */
    temp = MCUCR;
    MCUCR = temp | (1<<IVCE);
    MCUCR = temp & ~(1<<IVSEL);

  PORTD=0x14;

  return 0;
}

73 de Markus

von Uwe (de0508)


Lesenswert?

Hallo Markus,

Danke Jetzt ist es klarer.
1
/* Interrupt Vektoren verbiegen */
2
uint8_t temp = MCUCR;
3
MCUCR = temp | (1<<IVCE);
4
MCUCR = temp | (1<<IVSEL);
5
6
/* Interrupt Vektoren wieder gerade biegen */
7
temp = MCUCR;
8
MCUCR = temp | (1<<IVCE);
9
MCUCR = temp & ~(1<<IVSEL);

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.