www.mikrocontroller.net

Forum: GCC Atmega88 Bootloader - Code läuft nicht korrekt


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Markus Bühler (do9mbs)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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

Autor: Tom M. (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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.ä.

Autor: Markus Bühler (do9mbs)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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

Autor: Uwe S. (de0508)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo Markus,

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

73, Uwe

Autor: Markus Bühler (do9mbs)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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

Autor: Uwe S. (de0508)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo Markus,

Danke Jetzt ist es klarer.
/* Interrupt Vektoren verbiegen */
uint8_t temp = MCUCR;
MCUCR = temp | (1<<IVCE);
MCUCR = temp | (1<<IVSEL);

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net