Datum:
Hallo, ich debugge gerade ASM-Code für einen Atmega128 der von einem Vorgänger (Studienarbeit an der Uni) verbrochen wurde. Dokumentation des Codes geht quasi gegen 0 und ich habe die ehrenvolle Aufgabe, nun die Fehlerursache zu finden. Ich bin dabei nun mehrfach auf folgendes Konstrukt gestoßen mit dem ich irgendwie nicht viel anfangen kann:
sts PORTG, r24 sts DDRG, r24 lds r24, PORTG |
Ich meine hierbei das letzte "lds". Dort passiert nach meinem Verständnis ja nichts anderes, als dass der Wert, der von r24 nach PORTG geladen wurde wieder zurück nach r24 geladen wird, die Anweisung könnte man also auslassen da sie ja nichts anderes macht als "r24 = r24", oder sehe ich das falsch? Denn an PORTG anliegende Signale müssten ja mittels
lds r24,PING
|
eingelesen werden, oder? Gruß, Ina
Datum:
Ina schrieb: > die Anweisung könnte > man also auslassen da sie ja nichts anderes macht als "r24 = r24", oder > sehe ich das falsch? Wenn er nicht gerade die verplemperten Taktzyklen für das Timing braucht ;-), ja. Ist ein teurer NOP. > Denn an PORTG anliegende Signale müssten ja mittels > lds r24,PING > > eingelesen werden, oder? So ist es.
Datum:
Darf ich fragen, was der Code überhaupt macht? Ungewöhnlich, dass man mitten im Code das DDR Register umsetzt. Normalerweise stellt man die am Programmanfang einmal korrekt ein, und dann bleibt das auch so. Kann natürlich auch sein, dass der Portpin bewusst zwischen Ein/Ausgang hin und hergeschaltet wird, um an einem Ausgangspin die Zustände High-Low-Tristate zu erreichen. Das kommt aber nicht so oft vor und der abschliessende LDS weckt dann nicht wirklich das Vertrauen in mir.
Datum:
Hallo, diese Stelle taucht nicht mitten im Programm auf sondern beim Progbrammstart, das hatte ich vergessen zu erwähnen. Die "normalen" I/O-Ports werden wie üblich konfiguriert aber bei den Ports die im extended I/O liegen fängt er dann plötzlich mit solchen Geschichten an. An Port G hängt zwar auch ein DSP, aber dadurch dass ja eben nicht PING eingelesen wird kann es ja eben nicht sein, dass dort irgendwelche Signale ausgewertet werden. ich weiß nun nicht wie fit mein Vorgänger in ASM war, vielleicht ist es tatsächlich nur ein teures NOP weil er dachte er müsste zwingend die zwei Zyklen überbrücken bis das STS fertig ist o.ä., ich wollte mich nur nochmal absichern dass mit solch einer Befehlskombination nicht möglicherweise irgendetwas ganz "Abgedrehtes" gemacht werden kann ;) Gruß, Ina
Datum:
Hi
> oder?
Nicht unbedingt. Das Portregister hat auch noch die Aufgabe bei
Eingängen den Pull-Up-Widestand einzuschalten. Also kann es durchaus
sinnvoll sein dieses auszulesen. Für den Zustand der Eingänge wäre
natürlich PING richtig.
MfG Spess
Datum:
Das Umschalten eines Ports oder Teile davon kann schon mal vorkommen, wenn der Port Bidirektionales IO macht. Daß das Register des Ports zurückgelesen wird kann den Grund haben: z.B. ein am Port hängender Transistor zieht den Pin beim H-Zustand "zuweit" runter und der PIN liest dann eine 0 statt einer 1 zurück. Ohne nähere Info zur HW halte ich mich mal mit evtl. bösen Kommentaren zurück. Hier würde ich aber mal nach dem Fehler suchen.
Datum:
spess53 schrieb: > Hi > >> oder? > > Nicht unbedingt. Das Portregister hat auch noch die Aufgabe bei > Eingängen den Pull-Up-Widestand einzuschalten. Also kann es durchaus > sinnvoll sein dieses auszulesen. Schon. Aber in diesem Zusammenhang und unter Berücksichtigung des Faktums, dass immer das gleiche Register r24 involviert ist, macht es nicht wirklich großartig Sinn ldi r24, 0xAA sts PORTG, r24 sts DDRG, r24 lds r24, PORTG was soll in r24 jetzt stehen, ausser 0xAA? Er schaltet die Pins auf 1, dann auf Ausgang. Bis daher ist das noch sinnvoll. Aber wozu das zurücklesen?
Datum:
Man muss nicht immer in merkwürdigem Code nach Sinn suchen, jedoch gäbe es eine Bedingung, d.h. wenn ein Interrupt PORTG verändern kann, bei der dieser Code dann nicht mehr einem einfachen MOV R24, R24 entspricht. Da käme es auf das weitere Code-Umfeld an. Anton schrieb: > Daß das Register des Ports zurückgelesen wird kann > den Grund haben: z.B. ein am Port hängender Transistor > zieht den Pin beim H-Zustand "zuweit" runter und der > PIN liest dann eine 0 statt einer 1 zurück. Nein, den Grund hat's sicher nicht. Wenn der Portpin mit Gewalt gezogen wird, kann man das nicht durch Lesen des Port-Registers raus bekommen, da muss man Pin lesen.
Datum:
Anton schrieb: > zieht den Pin beim H-Zustand "zuweit" runter und der > PIN liest dann eine 0 statt einer 1 zurück. Dann müsste er aber das Pin Register auslesen. Aus dem Port Register kriegt er genau den Wert wieder raus, den er vorher reingeschrieben hat.
Datum:
MWS schrieb: > Man muss nicht immer in merkwürdigem Code nach Sinn suchen, Ist für mich eine Frage der Vertrauensbildung. Kann natürlich auch sein, dass das ein Überbleibsel von früher oder ein Copy&Paste Fehler ist. Macht er denn in weiterer Folge irgendwas mit dem Wert in r24? Das ist für mich bei Analysen meistens ein ganz guter Leitfaden. Die Überlegung: OK, da wird also ein Wert geholt - was macht er damit?
Datum:
Karl Heinz Buchegger schrieb: > MWS schrieb: >> Man muss nicht immer in merkwürdigem Code nach Sinn suchen, > > Ist für mich eine Frage der Vertrauensbildung. Meine Aussage war: manchmal ist Blödsinn einfach nichts weiter als Blödsinn. Karl Heinz Buchegger schrieb: > OK, da wird also ein Wert geholt - was macht er damit? Genau darauf sollte man achten und das schrieb ich: > Da käme es auf das weitere Code-Umfeld an.
Datum:
Manchmal sieht man in C eine verkettete Zuweisung. Dann muß der Compiler die volatile Variable wieder auslesen.
PORTA = PORTB = 0xAA; 72: 8a ea ldi r24, 0xAA ; 170 74: 88 bb out 0x18, r24 ; 24 76: 88 b3 in r24, 0x18 ; 24 78: 8b bb out 0x1b, r24 ; 27 |
Peter
Datum:
Ina schrieb: > ich debugge gerade ASM-Code für einen Atmega128 ... > ich habe die ehrenvolle Aufgabe, nun die > Fehlerursache zu finden. Der Fehler wird sein, daß man 128kB einfach nicht mehr in Assembler programmieren kann. Schmeiß alles weg und schreibs in C. Assembler nehme ich nur für sehr kleine Programme (unter 2kB). Peter
Datum:
Peter Dannegger schrieb: > Manchmal sieht man in C eine verkettete Zuweisung. Dann muß der Compiler > die volatile Variable wieder auslesen. http://www.nongnu.org/avr-libc/user-manual/FAQ.htm...
Datum:
Vielleicht ist es ja auch gar kein originärer Quelltext, sondern versehentlich disassemblierter Datenbereich :-)
Datum:
Hallo, danke für eure Hilfe, es ist allerdings definitiv Code :) Peter Dannegger hat mich aber auf die richtige Spur gebracht.
PORTA = PORTB = 0x01; DDRA = DDRB = 0x01; |
wird z.B. mit AVR Studio 5 tatsächlich zu
ldi r24, 1 out PORTB, r24 in r24, PORTB out PORTA, r24 ser r24 out DDRB, r24 in r24, DDRB out DDRA, r24 |
Ich habe damit wohl meinem Vorgänger Unrecht getan, ich muss jetzt erstmal klären woher dann dieser ASM-Code kommt, bzw. warum mir kein C-Code zur Verfügung gestellt wird. Auf jeden Fall schonmal vielen Dank für eure Hilfe, wieder was gelernt :) Gruß, Ina
Datum:
Nachtrag: DDRA und DDRB werden natürlich auf 0xFF gesetzt, nicht auf 0x01 :D
Datum:
Peter Dannegger schrieb: > Der Fehler wird sein, daß man 128kB einfach nicht mehr in Assembler > programmieren kann. Ähm, naja, also, um zumindest für mich persönlich diese Sache einmal zu klären habe ich vor ca. 12 Monaten ein Projekt begonnen, das inzwischen auch langsam fertig wird. Ich habe hier einen Heimcomputer komplett aus parallel arbeitenden AVRs, mehr als 15 Grafikmodi, Raster-IRQ, SD-Laufwerk, 6502/6510/Z80/6809-Interpreter, alles durchgetaktet, in Echtzeit mit 2MHz bei 24MHz-Systemtakt. Alles komplett durchoptimierter Assemblercode bzgl. Laufzeit und über 128kB dürfte ich locker drüber liegen. Die einzelnen AVRs sind komplett über den gesamten Code Taktgenau synchronisiert um die hohe Geschwindigkeit zu erreichen, absolut unmöglich das per Compiler zu machen. Und das 'Ding' läuft :-) Weiß noch nicht, was ich damit überhaupt anfange und ob ich es evtl. veröffentliche, aber prinzipiell können kann 'man' auch viele zehntausend Zeilen sinnvollen und hochoptimierten Assemblercode schreiben, der Beweis steht hier neben mir. Mag sein bzw. würde mich inzwischen nicht mehr wundern, dass das etwas sehr ungewöhnlich ist, wie bspw. Pi auf über 22.000 Stellen aufsagen, kann ich selbst so wenig, wie die meisten anderen. Aber da kann 'man' ja auch nicht mehr allgemein sagen, 'man' könne es nicht sondern muss sagen 'ich' kann es nicht. Dafür darf man sich dann freuen eine Gemeinsamkeit mit 99,irgendwas Prozent aller Menschen zu haben :-) Ich will auf keinen Fall eine Diskussion zu dem Thema Assembler verursachen, ich wollte nur mal die Gelegenheit wahrnehmen, diese althergebrachte Behauptung mit Fakten zu widerlegen. Jemand sagte zwar mal, dass ein Vorurteil in der heutigen Zeit schwerer zu zertrümmern sei, als ein Atom, aber vielleicht kann ich dieses Dogma ja mal etwas ankratzen. ;-) Ontopic: Es war keine Rede von der Programmgröße auf dem mega128. Und 64.000 Zeilen Code schreiben, dürfte für eine Studienarbeit schon vom reinen Tippen her zuviel Arbeit sein. Und irgendwie wage ich zu bezweifeln, dass die 'freiwillig' Assembler verwenden, wenn's nicht die Aufgabenstellung vorschreibt. Da wird vermutlich ein typischer Anfängerfehler wie PORTG und PING vertauscht oder so drin sein. Grüße Mark
Datum:
Mark L. schrieb: > Ich habe hier einen Heimcomputer komplett aus parallel arbeitenden AVRs, > mehr als 15 Grafikmodi, Raster-IRQ, SD-Laufwerk, > 6502/6510/Z80/6809-Interpreter, alles durchgetaktet, in Echtzeit mit > 2MHz bei 24MHz-Systemtakt. Faszinierend! Respekt!
Datum:
Mark L. schrieb: > Ähm, naja, also, um zumindest für mich persönlich diese Sache einmal zu > klären habe ich vor ca. 12 Monaten ein Projekt begonnen, das inzwischen > auch langsam fertig wird. > Ich habe hier einen Heimcomputer komplett aus parallel arbeitenden AVRs, > mehr als 15 Grafikmodi, Raster-IRQ, SD-Laufwerk, > 6502/6510/Z80/6809-Interpreter, alles durchgetaktet, in Echtzeit mit > 2MHz bei 24MHz-Systemtakt. Alles komplett durchoptimierter Assemblercode > bzgl. Laufzeit und über 128kB dürfte ich locker drüber liegen. Die > einzelnen AVRs sind komplett über den gesamten Code Taktgenau > synchronisiert um die hohe Geschwindigkeit zu erreichen, absolut > unmöglich das per Compiler zu machen. WILL! DAS! DING! SEHEN!!! Unbedingt ;) Ich mache hier übrigens gerade etwas ähnliches - eine kleine Spielekonsole mit 2 ATMega1284P. Einer als Grafikprozessor und einer als "Großhirn". Das Teil schafft eine Grafikauflösung von 160x100 bei 64 Farben :D. Aber bei mir sind nur die Takte der Grafikausgabe handgezählt und auf eine bestimmte Laufzeit getrimmt, der Rest läuft mit einfachen Interrupts ;). Im Großhirn wird dann ein CPU-Emulator laufen - ich peile da so 500k bis 1M Instruktionen pro Sekunde an... Gruß Jonathan P.S.: Sorry für's OT
Datum:
Peter Dannegger schrieb: > Der Fehler wird sein, daß man 128kB einfach nicht mehr in Assembler > programmieren kann. Hmmm ... mit 64kB geht es noch ... > Schmeiß alles weg und schreibs in C. Halte ich für Unsinn! Gruß Jobst