Fehlermeldung AVR Studio und GCC

Gast #1969386
Lesenswert?

Hi,

kann mir jemand erläutern wie ich folgende Fehlermeldung zu verstehen 
habe? Die Meldung erschein beim compilieren eines ATMega88 mit dem AVR 
Studio + GCC:

"/cc7GY9hV.s:124: Error: illegal opcode jmp for mcu atmega88"

Hab schon die Suche bemüht, doch leider nichts passendes gefunden.


Gruß
#1969403
Lesenswert?

Den Opcode „jmp“ gibt es beim ATmega88 nicht.

Hast Du einen Assembler-Source compiliert?  Dann gibt es jmp erst ab 
168.  Ändern in rjmp.

Hast Du C mit Makefile kompiliert?  Dann hast Du vermutlich den 
Prozessor-Typ geändert.  Es muss alles neu kompiliert werden, z.B. durch 
Aufruf von „make -B“.
Persönliche Seite #1969415
Lesenswert?

> "/cc7GY9hV.s:124: Error: illegal opcode jmp for mcu atmega88"
In Zeile 124 von cc7GY9hV.s taucht ein jmp auf.

Das ist für den Atmega88 nicht erlaubt, denn
Datenblatt Atmega88: 31. Instruction Set Summary: jmp(1)
(1): Note: 1. These instructions are only available in ATmega168.

Die offenen Fragen sind:

1. ist der nicht gezeigte C-Quellcode, der nach cc7GY9hV.s übersetzt 
wurde, fehlerhaft?

2. ist die nicht näher bezeichnete Toolchain aus AVR Studio und gcc 
fehlerhaft? Hier gab es einen ähnlichen Fall:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=55290

3. sind die nicht gezeichten Compileroptionen (Projekteinstellungen, 
Makefile) fehlerhaft?

Zur Klärung der Symptome (das ist noch noch nicht die Diagnose oder die 
Kur) würde der Tipp von TimothyEBaldwin aus dem avrfreaks.net Thread 
weiterhelfen.
Gast #1969740
Lesenswert?

Hi,

hier die Funktion die anscheinend Probleme macht:
1
 
2
#include <avr/io.h>
3
#include <avr/pgmspace.h>
4
#include <util/delay.h>
5

6
#include "aesglobal.h"
7
#include "bootldr.h"
8
#include "loader.h"
9
#include "bus.h"
10
#include "crc.h"
11

12

13
//=============================================================================
14
// Starts here!
15
//=============================================================================
16

17
int main(void)
18
{
19
    // enable pullup - give port time to settle
20
    set_bit(PORTD, PD2);
21

22
    busInit();
23

24
    // Loop forever (loops only if Application Section is damaged)
25
    for (;;)
26
    {
27
        // Key pressed? Yes -> run the loader routine
28
        if (!(PIND & (1 << PD2)))
29
        {
30
            loader();
31
        }
32

33
#if defined(CRC_CHECK)
34
        // Check that the Application Section contents is undamaged
35
        // by calculating the CRC of the whole memory.
36
        {
37
      #ifndef RAMPZ
38
              uint16_t p = 0x000000;
39
      #else
40
              uint32_t p = 0x000000;
41
      #endif
42

43
      uint16_t crc = 0;
44

45
            do
46
            {
47
      #ifndef RAMPZ
48
        crc = CRC(crc, pgm_read_byte(p));
49
      #else
50
                crc = CRC(crc, pgm_read_byte_far(p));
51
      #endif
52
            }
53
            while (++p < MEM_SIZE);
54

55
            // Application Section damaged
56
            //   -> do not jump to Reset Vector of the Application Section
57
            if (crc)
58
            {
59
                DDRB = 0xff;
60
                for(;;)
61
                {
62
                    PORTB ^= 0xff;
63
                    _delay_ms(500);
64
                }
65
            }
66
        }
67
#endif
68

69
        asm volatile ("rjmp 0");
70
    }
71
}

Mir scheint als der der Sprung and die Adresse 0 nicht 
funktioniert......
Gast #1969751
Lesenswert?

Sorry, Alarm zurück!

Hab es gerade mal durch den Debugger direkt am Controller laufen lassen.

Das Programm springt anscheinend wirklich nicht an die Adreese 0, 
sondern es wird immer wieder die Main im Bootloader ausgeführt.
#1970220
Lesenswert?

Ich mag mich täuschen, aber ich denke, den Fall hatte ich auch mal und 
das Problem ist, dass die „0“ bei „rjmp 0“ relativ zur Text Section 
(genauer: zum Beginn dieser) ist.  Somit kommt die 
Bootloader-Startadresse raus.

Du musst ein absolutes Symbol definieren und das als Argument zum rjmp 
mitgeben, also
1
    asm volatile ("rjmp Application");
schreiben.  Und dem Linker die absolute Adresse von Application entweder 
im Linkerscript mitgeben oder auf der avr-ld-Kommandozeile mit
1
  --defsym Application=0
oder dem Compiler (avr-gcc) mit
1
  -Wl,--defsym,Application=0
.
#1976598
Lesenswert?

Mario schrieb:
> Schau mal in den Wiki-Artikel
> AVR Bootloader in C - eine einfache Anleitung
>
> Dort steht auch wie es geht ,z.B.
>
1
> void (*start)( void ) = 0x0000;
2
>
>
> und dann der  Aufruf mit:
>
1
> start();
2
>
>
> Die Beispiele sind übrigens alle für den Atmega88 geschrieben...

Diese Methode funktioniert allerdings nur wenn auf 0x0000 gesprungen 
werden soll.

Beim ATmega644 z.B. ist mit aufgefallen, dass mit diesem Code der Sprung 
auf eine Word-Adresse generiert wird. Wenn dann beispielsweise start 
nicht auf 0x0000 zeigt sondern auf 0xE000, wird auf 0x6000 (wordadress) 
gesprungen obwohl er bei 0x7000 landen sollte.

Mein Workaround bisher:
1
#define BOOTLOADER_START_ADDRESS    0xE000
2
#define jump_to_bootloader()   asm volatile ("jmp %a0 :: "i" \
3
                                 ((uint32_t)(BOOTLOADER_START_ADDRESS) & 0x0000FFFFuL));

Leider ohne automatischer Unterscheidung bei Sprungadressen grösser 
0xFFFF.

Hat hierzu vlt. jemand noch eine Idee?

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