mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Fehlermeldung AVR Studio und GCC


Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: abc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anscheinend kennt der 88 den Assemblerbefehl JMP nicht. Richtigen µC-Typ 
im AVR-Studio eingestellt?

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!

JMP gibt es beim ATM88 nicht. Mit RJMP gehts....!!!!!

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht 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“.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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&f...

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.

Autor: Jens Mundhenke (dl4aas) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Pascal,

es ist nicht zufällig eine große switch-Konstruktion, die die Meldung 
erzeugt? Ich habe es schon gehabt, dass der Prozessor die vom Compilter 
gewünschten JMPs nicht beherrschte, wenn der Sprung zu weit wurde..

Gruss
Jens

Autor: abc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wäre dann eher ein "out of reach", tritt vorzugsweise bei RJMP auf.

Autor: Jens Mundhenke (dl4aas) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
abc, da hast Du wohl recht...

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

hier die Funktion die anscheinend Probleme macht:
 
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

#include "aesglobal.h"
#include "bootldr.h"
#include "loader.h"
#include "bus.h"
#include "crc.h"


//=============================================================================
// Starts here!
//=============================================================================

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

    busInit();

    // Loop forever (loops only if Application Section is damaged)
    for (;;)
    {
        // Key pressed? Yes -> run the loader routine
        if (!(PIND & (1 << PD2)))
        {
            loader();
        }

#if defined(CRC_CHECK)
        // Check that the Application Section contents is undamaged
        // by calculating the CRC of the whole memory.
        {
      #ifndef RAMPZ
              uint16_t p = 0x000000;
      #else
              uint32_t p = 0x000000;
      #endif

      uint16_t crc = 0;

            do
            {
      #ifndef RAMPZ
        crc = CRC(crc, pgm_read_byte(p));
      #else
                crc = CRC(crc, pgm_read_byte_far(p));
      #endif
            }
            while (++p < MEM_SIZE);

            // Application Section damaged
            //   -> do not jump to Reset Vector of the Application Section
            if (crc)
            {
                DDRB = 0xff;
                for(;;)
                {
                    PORTB ^= 0xff;
                    _delay_ms(500);
                }
            }
        }
#endif

        asm volatile ("rjmp 0");
    }
}


Mir scheint als der der Sprung and die Adresse 0 nicht 
funktioniert......

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Programm hängt an dieser Stelle:

while (++p < MEM_SIZE);

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht 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
    asm volatile ("rjmp Application");
schreiben.  Und dem Linker die absolute Adresse von Application entweder 
im Linkerscript mitgeben oder auf der avr-ld-Kommandozeile mit
  --defsym Application=0
oder dem Compiler (avr-gcc) mit
  -Wl,--defsym,Application=0
.

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super HC! Funktioniert einwandfrei!


Vielen Dank!

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau mal in den Wiki-Artikel
AVR Bootloader in C - eine einfache Anleitung

Dort steht auch wie es geht ,z.B.
void (*start)( void ) = 0x0000; 

und dann der  Aufruf mit:
start(); 

Die Beispiele sind übrigens alle für den Atmega88 geschrieben...

Autor: Robert K. (murdok)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mario schrieb:
> Schau mal in den Wiki-Artikel
> AVR Bootloader in C - eine einfache Anleitung
>
> Dort steht auch wie es geht ,z.B.
>
> void (*start)( void ) = 0x0000;
> 
>
> und dann der  Aufruf mit:
>
> start();
> 
>
> 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:
#define BOOTLOADER_START_ADDRESS    0xE000
#define jump_to_bootloader()   asm volatile ("jmp %a0 :: "i" \
                                 ((uint32_t)(BOOTLOADER_START_ADDRESS) & 0x0000FFFFuL));

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

Hat hierzu vlt. jemand noch eine Idee?

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
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
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 bestätigst du, die Nutzungsbedingungen anzuerkennen.