Forum: Mikrocontroller und Digitale Elektronik Invalid Opcode schon zu Beginn des Programms


von Peter (Gast)


Lesenswert?

.include "m16def.inc"
.org 0x000 rjmp start

start:



Hoi Leute, kann mir mal sagen was da nen invalid Opcode auslöst beim 
simulieren?

"AVR Simulator: Invalid opcode 0xffff at address 0x000001"

Das mit dem Sprung am Anfang muss man doch machen um über die 
Interruptvektorliste drüber zu kommen, da lieg ich doch richtig, oder?



Peter

von johnny.m (Gast)


Lesenswert?

Wenn Du das tatsächlich so wie oben assembliert hast: Der "invalid 
opcode" ist der unbeschriebene (also mit 0xffff gefüllte) Flash an der 
Stelle der Marke "start", an die das Programm springen soll...

von johnny.m (Gast)


Lesenswert?

BTW: Wenn Du keine Interrupts benutzt, brauchst Du kein rjmp im 
Reset-Vektor. Dann kannste das Programm auch direkt von Adresse 0 an 
schreiben.

von Peter (Gast)


Lesenswert?

hm ... habs jetzt schon raus g

allerdings tritt mir jetzt an stelle 0x16 der Invalid Opcode auf

.cseg
.org 0x00
  jmp RESET ; Reset Handler
  reti ; IRQ0 Handler
  reti ; IRQ1 Handler
  reti ; Timer2 Compare Handler
  reti ; Timer2 Overflow Handler
  reti ; Timer1 Capture Handler
  reti ; Timer1 CompareA Handler
  reti ; Timer1 CompareB Handler
  reti ; Timer1 Overflow Handler
  reti ; Timer0 Overflow Handler
  reti ; SPI Transfer Complete Handler
  reti ; USART RX Complete Handler
  reti ; UDR Empty Handler
  reti ; USART TX Complete Handler
  reti ; ADC Conversion Complete Handler
  reti ; EEPROM Ready Handler
  reti ; Analog Comparator Handler
  reti ; Two-wire Serial Interface Handler
  reti ; IRQ2 Handler
  reti ; Timer0 Compare Handler
  reti ; Store Program Memory Ready Handler


RESET:



die retis stehen jetzt nur so drin damit er net rummeckert ..

von Mike R. (thesealion)


Lesenswert?

Wie wäre es, wenn du die Zeilen nach deiner letzen Sprungmarke auch noch 
schreiben würdest?

Er meckert nämlich über die Zeile, die du immer brav ausläßt.

von Peter (Gast)


Lesenswert?

Wie ist das eigentlich wenn man keine Interrupts benutzt? Der uC springt 
doch dann trotzdem z.b. bei auftretendem INT0 am passendem port, zur 
Adresse 0x0001 und wenn er da nix vorfindet (wie z.B. rjmp INT0handler), 
wie geht er damit um?

von Mike R. (thesealion)


Lesenswert?

Wenn du keine Interrupts benutzt/freigibst, dann können auch keine 
auftreten.

von Stevko (Gast)


Lesenswert?

Tja Peter,

es ist doch ein Mega_16(.include "m16def.inc")!
Da wird mit einem "reti" nicht viel. Entweder 2x reti
oder im Datenblatt ab Seite 45.

Gruß
  Stevko

von Karl heinz B. (kbucheg)


Lesenswert?

> zur Adresse 0x0001 und wenn er da nix vorfindet (wie z.B. rjmp
> INT0handler),

Er findet immer was vor.
Dort ist Speicher und die Speicherzelle hat einen Inhalt.
Egal ob du selbst da was hineinschreibst oder ob da vom
Vorgänger noch zufällig was anderes drin steht.

Der µC macht seinen Zyklus, komme was da wolle:

 1) Speicher an der Stelle Program Counter ansprechen
 2) Wert von dort holen
 3) Program Counter erhöhen
 3) Den Wert als Befehl auffassen und dekodieren
 5) ev. zusätzliche Bytes über den Program Counter
    holen und den Program Counter erhöhen
 6) Den Befehl abarbeiten
 7) Weiter bei 1

Den µC interessiert es nicht die Bohne, wer welchen Inhalt
in die Speicherzellen geschrieben hat. Solange dort Speicher
ist, liefert er auch einen Wert und den fasst er als Befehl
auf und arbeitet ihn ab.


von antworter (Gast)


Lesenswert?

@Peter:

Wenn es am Anfang schon so "kracht" ist eventuell für Dich der Einstieg 
mit C geeigneter.

(nicht böse gemeint)

von Profi (Gast)


Lesenswert?

"Solange dort Speicher ist, liefert er auch einen Wert und den fasst er 
als Befehl auf und arbeitet ihn ab."

Auch wenn dort kein Speicher ist, ergeben die Pegel an (offenen) 
Leitungen Werte, die er ausführen würde.



Wie wäre es, wenn Du vor das Label RESET: einen org 0x0050 schreibst?

Außerdem wäre ein Listing aussagekräftig. Was steht den an der Adresse 
RESET: ?

von johnny.m (Gast)


Lesenswert?

@Profi:
Eben das ist doch sein Verständnis-Problem: Da steht gar nichts (außer 
dem FFFF..., das ein gelöschter Flash-Speicher nunmal hat). Und FFFF ist 
nun mal kein gültiger Befehl.

@Peter:
Wenn man etwas simulieren möchte, dann muss auch etwas da sein, das man 
simulieren kann!
Schreib mal hinter das "RESET:" ein "jmp RESET". Dann dürfte es 
zumindest keine Fehlermeldung mehr geben, auch wenn der Code dann immer 
noch ziemlich sinnfrei ist.

von Peter (Gast)


Lesenswert?

Es ging eben nur um den Fehler, nicht um den Sinn des Codes. Trotzdem 
danke, habs schon herausgefunden.

von johnny.m (Gast)


Lesenswert?

Ach ja, und Stevko hat natürlich auch recht: Wenn Du einen Mega16 
benutzt, dann musst Du auch beachten, dass die Interrupt-Vektoren da 
(wie bei allen AVRs mit mehr als 8 KB Flash) 32 Bit breit sind. Also vor 
jedes reti ein nop oder anstelle von "nop reti" ein "jmp RESET" oder 
(wenn Du eh keine Interrupts verwendest) die Vektortabelle ganz 
weglassen.

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.