eine Frage an die AVR Assembler Experten
Ich hab mir von Pollin ein paar der Microcontroller MEGA 2560PRO Boards
bestellt und bin grad am Testen. Ich programmiere in Assembler mit dem
Microship Studio ehemals AVRStudio.
Ich wollte erst mal eine Blink LED über den Timer5 Interrupt blinken
lassen. Das Ein/Ausschalten wird über den OCRA Compare Interrupt
gesteuert.
Im Prinzip funktioniert alles aber...
Nun ist es so, daß der Interrupt aufgerufen und abgearbeitet wird ohne
das ich den globalen Interrupt freigegeben habe (SEI) den OCRA Int hab
ich freigegeben.
Irgend jemand eine Idee? Oder liegts daran daß das Board einen
Bootloader hat und dort werden die INTs bereits enabled?
schon mal Danke für die Hilfe
Ich würde als erstes mit einem fertigen Beispiel beginnen. Das Flashen
ist die erste Hürde.
Und anschließen versuchen das Beispiel selbst zu bilden. Und dann erst
mit neuem Code beginn, wobei man durchaus das Beispiel abwandeln kann.
Hab ich nicht vergessen, nur nicht für nötig gehalten. Die Schaltung
funktioniert und das Programm auch. Nur sind nach dem Reset die
Interrupts freigegeben. Das stört mich im Prinzip nicht ich hätte nur
gern gewusst woran das liegt
Andreas G. schrieb:> Hab ich nicht vergessen, nur nicht für nötig gehalten. Die Schaltung> funktioniert und das Programm auch.
Na dann brauchst/willst du offenbar keine Hilfe.
Der Fehler ist übrigens in der Zeile mit dem Dingsbums und deine LED hat
die falsche Farbe.
Fischpudding schrieb:> Nun ist es so, daß der Interrupt aufgerufen und abgearbeitet wird ohne> das ich den globalen Interrupt freigegeben habe (SEI)
nun es wird wohl so sein, dass das dann jemand schon für dich gemacht
hat.
Bootloader oder InitCode kommen da in Frage.
Stefan ⛄ F. schrieb:> Na dann brauchst du keine Hilfe.
Full Ack.
Aber meine Glaskugel sagt dass der Interrupt zufällig durch
direktes Schreiben auf das entsprechende Register (SREG)
enabled wird. Richtig wäre es eine Read-Modify-Write Operation
zu verwenden die nur das betreffende Bit ändert das man ändern
will.
Nein, die LED hängt an einem normalen Port. Hier mal der Ausschnitt
welcher die LED anschaltet. Dann gibts noch einen Overflow Int, der
schaltet sie dann wieder aus. Im Main gibts keinen SEI Befehl.
1
LED_Int_Service_T5_compare_match:
2
PUSH R16 ; int prefix
3
IN R16, SREG
4
PUSH R16
5
PUSH R17
6
LDS R16, LED_Status ; OR PortK & LED_Status
7
LDS R17, PortK
8
OR R17, R16
9
STS PortK, R17
10
POP R17 ; int suffix
11
POP R16
12
OUT SREG, R16
13
POP R16
14
RETI
Ich denke es ist so wie usbman oben schon geschrieben hat. Bootloader
oder Init-Code. Wobei... Wenn mit dem Init-Code meiner gemeint sein
sollte dann kanns auch nicht sein...
Naja, dachte nur jemand hatte den Effekt schon mal
Stefan ⛄ F. schrieb:> Zeige den ganzen Quelltext, nicht nur den Teil, der den Fehler nicht> enthält.
An meinem Auto geht der rechte Blinker beim Benutzen doppelt so schnell,
woran kann das liegen?
A:
Poste alle Karroserieteile und den Schaltplan des Kabelbaums...
Bei Assembler für AVR kann man, z.B. im Bootloder, einen Interrupt
setzen der dann aktiv wird, wenn irgendeine Bedingung erfüllt wird. Dies
ist wenn man schlampig programmiert und der Bootloader das Hauptprogramm
anspringt.
Poste den Code des Bootloaders...
>Nun ist es so, daß der Interrupt aufgerufen und abgearbeitet wird ohne>das ich den globalen Interrupt freigegeben habe (SEI)
Dann schreib doch ein Mini-Prüfprogramm, das nur das SREG einliest, das
I-Bit ausmaskiert und eine LED einschaltet, wenn es gesetzt ist. Dann
weißt Du, ob es im Bootloader passiert ist oder Du doch woanders suchen
musst.
Hi,
wieviel Byte hast Du für SRAM Label Port-K reserviert?
Wo steht die SRAM Init Routine?
Warum bleibst Du nicht im cseg?
Wieso der Umweg über dseg?
ciao
gustav
Andreas G. schrieb:> Hab ich nicht vergessen, nur nicht für nötig gehalten. Die Schaltung> funktioniert und das Programm auch. Nur sind nach dem Reset die> Interrupts freigegeben. Das stört mich im Prinzip nicht ich hätte nur> gern gewusst woran das liegt
Kann eigentlich nur an eine lausigen Bootloader liegen, der nicht
ordentlich aufräumt, bevor er die Kontrolle an die Anwendung übergibt.
Allerdings: Wie sollte ein Bootloader eine normale Flashprozedur
überleben? Da kann doch nur ein Vollidiot das Chip-Erase vor dem Flashen
ausgeschaltet haben. Oder der Vollidiot hat in voller Absicht den
Bootloader zum Flashen seiner Anwendung benutzt.
Wer käme denn für die Rolle dieses hypothetischen Vollidioten in Frage?
Das war nur ein Test... .DSEG hat im Moment nur ein Byte. Port K ist ein
normaler IO Port der leider ausserhalb des Bereiches liegt den man mit
In/Out ansprechen kann. Ist wohl in den Ram Bereich gemappt. Daher LDS,
STS.
Hab mir mal das I-Flag ausgeben lassen (danke für den Tipp) und ja das
ist beim Startup gesetzt. Komisch das. Naja, wenn man es weis, ist es ja
ok.
Andreas G. schrieb:> Hab mir mal das I-Flag ausgeben lassen (danke für den Tipp) und ja das> ist beim Startup gesetzt. Komisch das. Naja, wenn man es weis, ist es ja> ok.
Nein, ist es nicht. Das hat nach Reset gelöscht zu sein. Ende der
Ansage.
@c-hater,
Naja, der Bootloader überlebt den Flash über USB. Muss er ja auch. Und
ja, der Vollidiot hat den Bootloader zum flashen benutzt. Dann gehts
auch entspannt mit USB. Die normalen 2560 Boards haben einen mega8USB
für die Kommunikation drauf. Dieses nicht nur einen dummen USB/Seriell
Wandler. Und ich hab keinen Bock jedesmal über SPI zu flashen. Keine
Ahnung ob der Ponyprog den 2560 überhaupt kennt
Andreas G. schrieb:> Port K ist ein> normaler IO Port der leider ausserhalb des Bereiches liegt den man mit> In/Out ansprechen kann. Ist wohl in den Ram Bereich gemappt. Daher LDS,> STS.
Hi,
ja, ja "Memory mapped". Der Begriff ist mir im Zusammenhang mit einigen
"Megas" noch in Erinnerung.
Da freute man sich über mehr Features damals, und dann lassen sich die
Programme nicht 1:1 auf die "neueren" Targets portieren.
ciao
gustav
portieren ist einfach. Einfach Assembler anwerfen und alle angemeckerten
In/Out gegen LDS/STS ersetzen. Man verliert da nur, glaube ich, einen
Taktzyklus
Andreas G. schrieb:> portieren ist einfach.
Hi,
klar, wenn man das vorher weiß, wie der "neue" AVR angesprochen werden
will.
Komme deswegen drauf, weil es 'mal bei Einführung von "besseren" AVRµCs
heftige Diskussionen gab damals.
Und ob die Maxime heute noch Gültigkeit hat ?:
Lieber im cseg arbeiten, weil dseg bei den "alten" schon abweichende
Zugriffszeiten hatte. Ganz zu schweigen dann vom noch "langsamerem"
eseg.
ciao
gustav
Dazu muss man kein AVR-Assembler Guru sein, die Grundlagen der
Elektronik reichen, der Effekt ist sozusagen "der Grundzustand".
Nach dem Anlegen der Versorgungsspannung haben alle SRAM-zellen
und Register beliebige Werte und nur im Controller enthaltene
zusätzliche Hardware setzt einige Zellen auf voreingestellte Werte, die
im Datenblatt
aufgeführt werden. Ob das auch bei Reset passiert oder nur bei
Power-On ist harwareabhängig. Wenn im Datenblatt
dazu nichts steht, geht der vorsichtige Mensch davon aus, daß nur der
ProgramCounter auf seinen definierten Startwert gesetzt wird
und alles Andere undefiniert ist.
Ansonsten steht in den beschreibbaren Zellen, was eventuell vorher
gestartete Programme dort hinterlassen haben und nur Du kannst wissen,
was da vor dem Reset alles gelaufen ist.
Natürlich kann man immer von Anderen erwarten, daß sie die Arbeit für
einen
selbst erledigen, aber warum sollten sie das tun? Deshalb die alte
Regel:
If You want to have it done right, You have to do it Yourself.
Einfach "clear global interrupt" und "set stackpointer" als erste
Befehle eintragen. Hilft zuverlässig gegen Überraschungen.
Mit freundlichen Grüßen an alle, die Automatiken für "normal" halten
und den Grundzustand gar nicht mehr kennen
Klaus
Andreas G. schrieb:> Naja, den Stack initialisiere ich immer als erstes. Nur um die> Flags hab> ich mich nie gekümmert.
So mache ich es auch. Ich habe nach einem Reset noch nie erlebt, dass
Bit 7 des SREG nach einem Reset den Wert 1 hat.
Das I-Flag wird beim Reset immer gelöscht. Wäre dies nicht der Fall,
könnte ein Programm schon direkt nach dem Start unterbrochen werden,
noch bevor ein evtl. vorhandener CLI-Befehl ausgeführt wird. Deswegen
ist ein CLI am Programmstart nicht nur überflüssig, sondern auch
unsinnig.
kseege schrieb:> Natürlich kann man immer von Anderen erwarten, daß sie die Arbeit für> einen selbst erledigen, aber warum sollten sie das tun? Deshalb die> alte Regel: If You want to have it done right, You have to do it> Yourself.
Gerade beim ATmega2560 mit seinen ca. 180 I/O-Registern wäre es ziemlich
mühsam, wenn man diese alle beim Programmstart explizit initialisieren
müsste. Da vertraue ich lieber dem Datenblatt:
"During reset, all I/O Registers are set to their initial values"
Yalu X. schrieb:> Deswegen> ist ein CLI am Programmstart nicht nur überflüssig, sondern auch> unsinnig.
Die Annahme ist hier ja, dass der Bootloader das I Bit stehen lässt.
Von da her, ist es evtl. schon sinnvoll, die Interrupts abzuschalten.
Content B. schrieb:> Stefan ⛄ F. schrieb:>> Zeige den ganzen Quelltext, nicht nur den Teil, der den Fehler nicht>> enthält.>> An meinem Auto geht der rechte Blinker beim Benutzen doppelt so schnell,> woran kann das liegen?>> A:> Poste alle Karroserieteile und den Schaltplan des Kabelbaums...
Bessere Analogie:
Bei meinem Auto geht der rechte Blinker nicht, woran liegt das? Anbei
ein Foto vom Rücksitz.
Arduino Fanboy D. schrieb:> Die Annahme ist hier ja, dass der Bootloader das I Bit stehen lässt.> Von da her, ist es evtl. schon sinnvoll, die Interrupts abzuschalten.
Sinnvoller wäre es, nicht das Symptom, sondern die Ursache zu bekämpfen,
also den Bootloader zu fixen.
Fischpudding schrieb:> Ich hab mir von Pollin ein paar der Microcontroller MEGA 2560PRO Boards> bestellt und bin grad am Testen.
Aha, spannend..
Fischpudding schrieb:> Ich programmiere in Assembler mit dem> Microship Studio ehemals AVRStudio.
löblich.
Fischpudding schrieb:> Nun ist es so, daß der Interrupt aufgerufen und abgearbeitet wird ohne> das ich den globalen Interrupt freigegeben habe (SEI) den OCRA Int hab> ich freigegeben.> Irgend jemand eine Idee?
Automagie?
Du sagtest, du bist am Testen..
Hast du keinen Debugger?
Ich bin erstaunt, dass einige sich an dem Bootloader fest gebissen
haben. Man kann wohl davon ausgehen, dass es sich um den Arduino
Bootloader handelt, mit dem die Mega2560 Board ausgeliefert werden.
Nach meinem Kenntnisstand übergibt er die Kontrolle an das Hauptprogramm
mit gesperrten Interrupts, wie sich das gehört. Tatsächlich benutzt er
selbst sogar keine Interrupts. Wer daran zweifelt möge bitte in den
Quelltext schauen
https://github.com/Optiboot/optiboot/tree/master/optiboot/bootloaders/optiboot
Deswegen bleibe ich dabei, dass unser Gast Fischpudding seinen gesamten
Quelltext zeigen soll.
Vielleicht läuft etwas im Stack Amok und zerstört das dorthin gerettete
Flagregister? Ich schiebe das normalerweise einfach in eines der unteren
16 Register, geht schneller und die unteren 16 sind sowieso nur halb
benutzbar.
Christoph db1uq K. schrieb:> ; init stack
Braucht es aber nur bei uralten AVR-Typen. Die neueren, auch der
Mega2560, initialisieren den Stackpointer beim Reset.
Oliver
Christoph db1uq K. schrieb:> Der 6502 legte beim Interrupt-Aufruf immer auch das Flagregister auf den> Stack.
Stack oder Schattenregister wird bei vielen CPU-Architekturen
automatisch genutzt. AVR ist da eher exotisch.