Forum: Mikrocontroller und Digitale Elektronik Bootloader Atmega644 Interrupts und die Probleme


von Daniel H. (Gast)


Lesenswert?

Abend,

sitze jetzt schon Tage an dem Bootloader aber leider will das alles 
nicht so wie ich will ;).

Egal was ich auch tue ich hab das gefühl der Bootloader wird nicht nach 
dem Reset gestartet und die Interrupts funktionieren auch nicht wie sie 
sollen.

Fuses:
BootSZ auf 4096Words gestellt
laut Datenblatt beginnt mein Bootloader damit bei 0x7000h.

BootRST ist ein Haken drinne damit er auch mit dem Bootloader startet.

Compiler:
Optimization auf (-O0) gestellet also keine Optimierung
damit hier nix scheif läuft

Linker:
Folgende zusatz Argumente für den Linker
-Wl,--section-start=.text=0x7000

Hex File danach überprüft sieht gut aus. Auch ein Auslesen
des Controllers zeigt das alles richtig geflasht wurde.

Code:
#include <avr/io.h>
#include <stdbool.h>
#include <util/delay.h>
#include <avr/interrupt.h>

//#include "bootloader.h"
//#include "uart.h"

#ifdef atmega644p

#endif

uint8_t wait;
uint8_t temp;

int main()
{
  wait = 0;

    /* Interrupt Vektoren verbiegen */

    char sregtemp = SREG;
    cli();
    temp = MCUCR;
    MCUCR = temp | (1<<IVCE);
    MCUCR = temp | (1<<IVSEL);
    SREG = sregtemp;


  DDRB = 255;
  PORTB = 255;

  _delay_ms(1000);

  PORTB = ~(1);

  _delay_ms(1000);

  TCCR0B |= (1<<CS00) | (1<<CS02);

  TIMSK0 |= (1<<TOIE0);

  sei();

  _delay_ms(1000);

  PORTB = ~(2);

  while(1)
  {

  }
}

ISR(TIMER0_OVF_vect)
{
  wait++;

  PORTB = ~wait;
}

Kurzes Programm das einfach nur über ein Timer Interrupt ein paar Leds 
blicken lassen soll.

Problem:
1)Die erste LED geht an sobald der Global Interrupt aktiviert wird und
der erste Interrupt kommt fängt das Programm von vorne an.

2)Flashe ich eine andere Aplikation auf Adresse 0 startet das Programm 
immer von dieser. Egal was ich auch bei dem Fuse BOOTRST einstelle.
(Hab natürlich drauf geachtet das ich nicht den Flash lösche wenn ich 
dsa 2 Programm rein flashe. Beim Auslesen aus dem Controller sieht man 
auch schön beide Programme)

Anmerkung:
Flashe ich das ganze an Adresse 0 ohne die Interrupt Vektoren zu 
verändern läuft alles wie es soll (war ja klar).

Jemand eine Idee?

Gruß
Daniel

von Stefan E. (sternst)


Lesenswert?

Daniel H. schrieb:
> Folgende zusatz Argumente für den Linker
> -Wl,--section-start=.text=0x7000

Falsche Adresse. Hier ist die Byte-Adresse nötig.

von Daniel H. (Gast)


Lesenswert?

Hi Stefan,

äähhhmmm irgendwie steh ich gerade auf dem Schlauch.

Wie meinst du das mit Byte-Adresse?

0x7000 gibt doch ein Hex wert an oder?

Gruß
Daniel

von Stefan E. (sternst)


Lesenswert?

Der Programmspeicher des AVR ist in Words organisiert, daher sind die 
Adressen im Datenblatt Word-Adressen.
Die GCC-Tools sind alle Byte orientiert und erwarten daher eine 
Byte-Adresse.

Falls der Groschen dann immer noch nicht gefallen ist:
Rechne mal 0x7000 um in Dezimal und vergleiche das mit der Gesamtgröße 
des Flash (in Bytes).

von Daniel H. (Gast)


Lesenswert?

Hi Stefan,

Ok hab es soweit verstanden also Word-Adress 0x7000 * 2 (2 Byte = 1 
Word) komme ich auf Adresse 0xE000 das in Dezimal umgerechnet = 57344. 
Das macht Sinn.

Danke schon mal für den Hinweis.

Leider ändert sich an dem verhalten des Prgramm nichts. Es ist jetzt an 
der richtigen stelle im Flash jedoch brennt immer noch nur 1 LED und das 
Programm startet von vorne.

Gruß
Daniel

von Stefan E. (sternst)


Lesenswert?

> Optimization auf (-O0) gestellet also keine Optimierung

Damit wird bei dem hier
1
    MCUCR = temp | (1<<IVCE);
2
    MCUCR = temp | (1<<IVSEL);
ganz sicher nicht das erforderliche Timing erreicht. Also sind die 
Vektoren nicht in den Bootloaderbereich verschoben, und beim ersten 
Interrupt gibt es einen Crash.

von Daniel H. (Gast)


Lesenswert?

Hi Stefan,

das ok das hab ich auch noch geändert und siehe da es geht :).

Vielen Dank für die hilfe und ein schönes Wochenende

Gruß
Daniel

PS: hab die Optimierung auf (-O2) jetzt gestellt und es geht.

von Purzel H. (hacky)


Lesenswert?

Inwiefern lohnen sich Interrupts im Bootloader ?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Milli Oschi schrieb:
> Inwiefern lohnen sich Interrupts im Bootloader ?

Macht die Programmierung komfortabler und ermöglicht es, im Bootloader 
Strom zu sparen, da nur agiert werden muss, wenn draußen einer klopft 
;-). Es gibt noch mehr Gründe Interrupte dem Polling vorzuziehen.

von Anon Y. (avion23)


Lesenswert?

Daniel H. schrieb:
> PS: hab die Optimierung auf (-O2) jetzt gestellt und es geht.

Die delay routinen und viele libs sind auf -Os optimiert. -O0 verursacht 
bei mir oft Probleme, mit -O2 wäre ich auch vorsichtig.

von Thomas E. (thomase)


Lesenswert?

Knut Ballhause schrieb:
> im Bootloader Strom zu sparen, da nur agiert werden muss
Wie funktioniert das?

mfg.

von Knut (Gast)


Lesenswert?

Müsste wait nich auch noch volatile sein?


Knut

von Stefan E. (sternst)


Lesenswert?

Knut schrieb:
> Müsste wait nich auch noch volatile sein?

Nicht bei dem gezeigten Code.

Beim eigentlichen, kompletten Code ... wer weiß, dem Namen nach durchaus 
möglich.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Thomas Eckmann schrieb:
>> im Bootloader Strom zu sparen, da nur agiert werden muss
> Wie funktioniert das?

Na, der Controller geht in den Sleep, wenn er nichts machen muss. Bei 
einem aktuellen Projekt braucht mein Bootloader gerade mal 1mA auf einem 
Mega168 und kann mit 57kBaud Daten über das UART verarbeiten. Der Mega 
läuft mit 8Mhz intern im Idle und ist blitzschnell aktiv, wenn er 
muss...

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.