Probleme mit Bootlader

OP #2292172
Lesenswert?

Hallo,
ich habe scheinbar falsch angefangen zu fragen und da ich den von mir 
erstellten thread nicht löschen kann hier nochmal ein neuanfang mit dem 
gleichen Problem nur nen andren (einfacheren Code), um vielleicht mal 
eine Lösung zu finden.

Das Projekt habe ich als .rar vor AVR-Studio 5 angehängt um es selbst 
simulieren zu können.
(Code ist von 
http://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung#Schritt_1_-_Erstellen_des_Projektes)

genutzt wird der Mega644A @ 16Mhz


Folgendes Problem:

Wenn ich den Code einfach so kompiliere und brenne gibt der µC über UART 
Text aus und nimmt auch Befehle an.

Wenn ich nun aber versuche die Interrupts umzuleiten "-Ttext=7000" für 
maximale Größe Bootgröße und BOOTRST aktiviert, funktioniert nix mehr.

Dies passiert auch, wenn ich nur die Optimierung auf "-O1" stelle, ohne 
das umleiten mit -Ttext.

Woran mag das liegen?

1
/*
2
 * Bootlader_644.c
3
 *
4
 * Created: 02.08.2011 11:36:54
5
 *  Author: iwi
6
 */ 
7

8
#define F_CPU  16000000UL
9

10

11
#include <avr/io.h>
12
#include <avr/interrupt.h>
13
#include <util/delay.h>
14
#include "uart.h"
15
#include <avr/boot.h>
16

17
#define BOOT_UART_BAUD_RATE     9600     /* Baudrate */
18
#define XON                     17       /* XON Zeichen */
19
#define XOFF                    19       /* XOFF Zeichen */
20
 
21
 
22
 
23
int main()
24
{
25
    unsigned int   c=0;        /* Empfangenes Zeichen + Statuscode */
26
    unsigned char  temp,        /* Variable */
27
                    flag=1,        /* Flag zum steuern der Endlosschleife */
28
          p_mode=0;      /* Flag zum steuern des Programmiermodus */
29
          
30
    void (*start)( void ) = 0x0000;     /* Funktionspointer auf 0x0000 */
31
 
32
    /* Interrupt Vektoren verbiegen */
33
    char sregtemp = SREG;
34
    cli();
35
    temp = MCUCR;
36
    MCUCR = temp | (1<<IVCE);
37
    MCUCR = temp | (1<<IVSEL);
38
    SREG = sregtemp;
39
 
40
    /* Einstellen der Baudrate und aktivieren der Interrupts */
41
    uart_init( UART_BAUD_SELECT(BOOT_UART_BAUD_RATE,F_CPU) ); 
42
    sei();
43
 
44
    uart_puts("Bootloader");
45
    _delay_ms(1000);
46
 
47
    do
48
    {
49
        c = uart_getc();
50
        if( !(c & UART_NO_DATA) )
51
        {
52
            switch((unsigned char)c)
53
            {
54
                 case 'q': 
55
         flag=0;
56
                     uart_puts("Verlasse den Bootloader!\n\r");
57
                     break;
58
                  default:
59
                     uart_puts("Du hast folgendes Zeichen gesendet: ");
60
                     uart_putc((unsigned char)c);
61
                     uart_puts("\n\r");
62
                     break;
63
            }
64
        }
65
    }
66
    while(flag);
67
 
68
    uart_puts("Springe zur Adresse 0x0000!\n\r");
69
    _delay_ms(1000);
70
 
71
    /* vor Rücksprung eventuell benutzte Hardware deaktivieren
72
       und Interrupts global deaktivieren, da kein "echter" Reset erfolgt */
73
 
74
    /* Interrupt Vektoren wieder gerade biegen */
75
    cli();
76
    temp = MCUCR;
77
    MCUCR = temp | (1<<IVCE);
78
    MCUCR = temp & ~(1<<IVSEL);
79
 
80
    /* Rücksprung zur Adresse 0x0000 */
81
    start(); 
82
    return 0;
83
}
Angehängte Dateien:
OP #2292582
Lesenswert?

Vielen Dank für den Hinweis. Ich versuche gerade das ganze zu verstehen.

Im Datenblatt ist eine Tabelle:
Table 25-13. Boot Size Configuration(1)
1 1 512 words 4 0x0000 - 0x7DFF 0x7E00 - 0x7FFF 0x7DFF 0x7E00
1 0 1024 words 8 0x0000 - 0x7BFF 0x7C00 - 0x7FFF 0x7BFF 0x7C00
0 1 2048 words 16 0x0000 - 0x77FF 0x7800 - 0x7FFF 0x77FF 0x7800
0 0 4096 words 32 0x0000 - 0x6FFF 0x7000 - 0x7FFF 0x6FFF 0x7000

wenn ich nun "00" setze habe ich ja den größten speicher für den 
Bootbereich. Das müssten denn doch 8kb sein oder?

Ich habe gerade das nächste Beispiel ausprobiert, wo der gesamte 
Bootlader als Beispiel gegeben ist. Wenn ich den BL auf den Chip lade 
läuft er auch soweit. Man kann Zeichen schicken und er reagiert auch 
richtig.

Wenn ich nun aber ein von mir funktionierendes, für den Chip 
kompiliertes , Programm laden möchte (oder hier, das Beispiel für meinen 
kompiliert), zeigt er ca 20 Punkte in Putty dann kommen nur noch #'s . 
Nach kurzer Zeit stopt er dann und wenn man etwas eingibt kommt nur noch 
# als Echo

hier nochmal der Link:
http://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung#Schritt_3_-_Programmieren_des_Bootloaders_2
#2292906
Lesenswert?

Andre Iwers schrieb:
> wenn ich nun "00" setze habe ich ja den größten speicher für den
> Bootbereich. Das müssten denn doch 8kb sein oder?

Das ist richtig.

Wenn ich mir aber das *.lss File aus deinem Debug Folder ansehe, sieht 
man zwar, daß der Code schön bei 0x7000 anfängt aber auch erst bei 
0x8436 endet. D.h. der Code ist über 10KB lang und passt nicht in den 
Bootsektor.

Mein Bootloader, der ähnlich gestrickt ist, wie der im Tutorial, ist 
gerade mal 1K lang. Und zwar Bytes nicht Word.

Also erstmal beste Optimierung rein und dann abspecken.

mfg.
Gast #2296568
Lesenswert?

Normalerweise muss du ja die Bootloader Fuse setzen, das heisst, nach 
einem Reset springt der controller in jedem Fall in den Bootloader.
du musst nun eine funktion in den Bootloader integrieren, die prüft, ob 
der bootloader überhaupt ausgeführt werden soll oder ob das normale 
programm ausgeführt werden soll.
Beispielsweise ob ein Pin low oder high ist.
Sofern das nicht der fall ist, muss du halt noch die Interrupttabelle 
geradebiegen und dann an die Addresse 0 springen.
Dann wird dein normales Programm ausgeführt.

mit grüßen,
Tueftler

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