Problem mit ATtiny26-Befehl

T

Till Wollenberg

Guest
Hallo!

Ein Problem mit dem Befehl LPM rd, Z+ auf einem ATtiny26 treibt
mich in den Wahnsinn. Offenbar lädt der AVR irgendetwas aus dem
Programmspeicher in das Zielregister, nur nicht die Daten, auf
die Z zeigt.

--- Beispiel ---------------------------------------------------
LDI ZLO, 0x00
LDI ZHI, 0x04

LDI COUNT, 80
bitmappixel: LPM TEMP, Z+ ; (*1)
OUT PORTA, TEMP
; ADIW ZLO, 0x01 ; (*2)

DEC COUNT
BRNE bitmappixel
----------------------------------------------------------------

Dieses Programm soll in einer Schleife nacheinander 80 Bytes,
die im Flash ab 0x200 liegen, an Port A ausgeben. Allerdings
erscheinen dort irgendwelche Bytes aus völlig anderen Teilen
des Flash-Speichers.

Testweise habe ich den Befehl (*1) mal durch ein LPM rd, Z
ersetzt und selbst per ADIW (*2) dafür gesorgt, das Z korrekt
hochgezählt wird. Auf diese Weise funktioniert das Programm
wie gewünscht. Allerdings verbraucht die Schleife so 2 Takte
mehr pro Durchlauf, was bei meinem Projekt nicht tolerierbar
ist.

Auf der Suche nach dem Fehler habe ich das Programm mal im
AVR Studio simuliert: dort verhält sich LPM rd, Z+ "normal"
und zählt Z korrekt hoch.

Ist in diesem Zusammenhang ein Bug des ATtiny26 bekannt? Google
brachte nichts sinnvolles, und ich bin mit meinem Latein am
Ende. BTW: der ľC läuft mit einem externen Quarz bei 16MHz, und
mein Programm macht Gebrauch von Timer, Interrupt und Sleep-Mode,
falls das irgendwie von Bedeutung ist. Der betreffende Programmteil
wird jedoch nicht von Interrupts unterbrochen.

Gruß, Till.

--
e-mail: wollenberg (at) web (punkt) de
 
Till Wollenberg <till@deadspam.com> wrote:

Ein Problem mit dem Befehl LPM rd, Z+ auf einem ATtiny26 treibt
mich in den Wahnsinn. Offenbar lädt der AVR irgendetwas aus dem
Programmspeicher in das Zielregister, nur nicht die Daten, auf
die Z zeigt.

Testweise habe ich den Befehl (*1) mal durch ein LPM rd, Z
ersetzt und selbst per ADIW (*2) dafür gesorgt, das Z korrekt
hochgezählt wird.
Verwechselst Du nicht Wort- und Byteadressen? LPM arbeitet mit
Byteadressierung, auch wenn der Flash beim AVR wortweise organisiert
ist und in vielen Tools (AVR Studio, VMLAB) gern mit Wortadressen
beziffert wird. (GCC & Co. arbeiten übrigens immer mit Byteadressen,
egal ob das Target 8-, 16-, 32- oder 64-bittig adressiert wird.)

Dadurch braucht der ATmega128 auch das blöde RAMPZ und ELPM, obwohl
bei JMP/CALL die Adressen nur 16-bittig sind (da diese Befehle
wortadressiert arbeiten).
--
J"org Wunsch Unix support engineer
joerg_wunsch@interface-systems.de http://www.interface-systems.de/~j/
 
Till Wollenberg wrote:

Hallo!

Ein Problem mit dem Befehl LPM rd, Z+ auf einem ATtiny26 treibt
mich in den Wahnsinn. Offenbar lädt der AVR irgendetwas aus dem
Programmspeicher in das Zielregister, nur nicht die Daten, auf
die Z zeigt.
Wie steht es so schön im "Instruction Set Manual":
"This instruction is not available in all devices. Refer to the device
specific instruction set summary."

Auf der Suche nach dem Fehler habe ich das Programm mal im
AVR Studio simuliert: dort verhält sich LPM rd, Z+ "normal"
und zählt Z korrekt hoch.
Tja...

/Jan-Hinnerk
 
Hallo!

"Jan-Hinnerk Reichert" <hinni@despammed.com> schrieb:

Till Wollenberg wrote:

Ein Problem mit dem Befehl LPM rd, Z+ auf einem ATtiny26 treibt
mich in den Wahnsinn. Offenbar lädt der AVR irgendetwas aus dem
Programmspeicher in das Zielregister, nur nicht die Daten, auf
die Z zeigt.

Wie steht es so schön im "Instruction Set Manual":
"This instruction is not available in all devices. Refer to the device
specific instruction set summary."
In der Instruction Set Summary zum ATtiny26 steht er drin, und
der Simulator des AVR Studio simuliert ihn korrekt, wenn ich als
Device ATtiny26 einstelle.

Falls der ATtiny26 die Instruktion tatsächlich nicht unterstützt,
sollte das doch inzwischen mal jemand bemerkt haben...

BTW: Im Daten"blatt" zum ATtiny26 taucht der Adressierungsmodus
"Code Memory Constant Addressing" via Z-Register auf, nicht aber
der via Z-Register mit Post-Inkrement. Im selben Dokument ist
aber auch von LPM Rd, Z+ die Rede.

Gruß, Till.

--
e-mail: wollenberg (at) web (punkt) de
 
Hallo!

"Joerg Wunsch" <j@ida.interface-business.de> schrieb:

Till Wollenberg <till@deadspam.com> wrote:

Ein Problem mit dem Befehl LPM rd, Z+ auf einem ATtiny26 treibt
mich in den Wahnsinn. Offenbar lädt der AVR irgendetwas aus dem
Programmspeicher in das Zielregister, nur nicht die Daten, auf
die Z zeigt.

Testweise habe ich den Befehl (*1) mal durch ein LPM rd, Z
ersetzt und selbst per ADIW (*2) dafür gesorgt, das Z korrekt
hochgezählt wird.

Verwechselst Du nicht Wort- und Byteadressen? LPM arbeitet mit
Byteadressierung, auch wenn der Flash beim AVR wortweise organisiert
ist und in vielen Tools (AVR Studio, VMLAB) gern mit Wortadressen
beziffert wird. (GCC & Co. arbeiten übrigens immer mit Byteadressen,
egal ob das Target 8-, 16-, 32- oder 64-bittig adressiert wird.)
Das habe ich beachtet. Im Code wird das Z-Register mit 0x0400 geladen,
und in meinem Sourcecode steht ein ".ORG 0x0200" vor dem zu ladenden
Datenblock. In der Simulation des AVR Studios verhalten sich beide
Varianten (LPM Z+ bzw. LPM Z & ADWI) dann auch völlig gleich.

Dadurch braucht der ATmega128 auch das blöde RAMPZ und ELPM, obwohl
bei JMP/CALL die Adressen nur 16-bittig sind (da diese Befehle
wortadressiert arbeiten).
So unsinnig ist das gar nicht. Da die Register eh nur 8 Bit breit
sind, wäre es glatte Verschwendung, wenn man immer nur 1 Wort
adressieren könnte.

Ich werde mal versuchen, mit einem einfacheren Testprogramm Daten
aus dem Flash zu lesen, und diese Digital auszugeben. Dann läßt
sich ev. wenigstens ermitteln, _woher_ der Müll kommt, den LPM Z+
zurückliefert.

Gruß, Till.

--
e-mail: wollenberg (at) web (punkt) de
 
Till Wollenberg wrote:

Hallo!

"Jan-Hinnerk Reichert" <hinni@despammed.com> schrieb:

Till Wollenberg wrote:

Ein Problem mit dem Befehl LPM rd, Z+ auf einem ATtiny26 treibt
mich in den Wahnsinn. Offenbar lädt der AVR irgendetwas aus dem
Programmspeicher in das Zielregister, nur nicht die Daten, auf
die Z zeigt.

Wie steht es so schön im "Instruction Set Manual":
"This instruction is not available in all devices. Refer to the
device specific instruction set summary."

In der Instruction Set Summary zum ATtiny26 steht er drin, und
der Simulator des AVR Studio simuliert ihn korrekt, wenn ich als
Device ATtiny26 einstelle.
Ich habe hier eine ältere Version des Datenblattes von September 2002.
Da steht nur der einfache "LPM" drin. In der aktuellen Version stehen
tatsächlich die Varianten mit "Post-Inc".

Ich hab' das Gefühl, daß da irgendjemand etwas übereifrig bei der
Datenblattrevision war ;-(

Falls der ATtiny26 die Instruktion tatsächlich nicht unterstützt,
sollte das doch inzwischen mal jemand bemerkt haben...
Vielleicht nicht, da im alten Datenblatt ja nicht drinsteht, daß er
tun soll.

Wenn es Dir die Mühe wert ist, frag' bei Atmel nach. Ansonsten würde
ich dem Chip eher vertrauen als einem Simulator...

/Jan-Hinnerk
 
Till Wollenberg <till@deadspam.com> wrote:

Verwechselst Du nicht Wort- und Byteadressen?

Das habe ich beachtet. Im Code wird das Z-Register mit 0x0400 geladen,
und in meinem Sourcecode steht ein ".ORG 0x0200" vor dem zu ladenden
Datenblock.
Eben. Zumindest für meinen Assembler (avr-as, GNU binutils) müßte man
dann auch .org 0x400 schreiben. (D. h., eigentlich würde ich gar kein
..org benutzen sondern einen Label, aber das ist was anderes.)

Wenn Du Dir da sicher bist: nur zu, ich wollte Dich nur drauf hinweisen.

In der Simulation des AVR Studios verhalten sich beide
Varianten (LPM Z+ bzw. LPM Z & ADWI) dann auch völlig gleich.
Traue keiner Simulation, die Du nicht selbst verbrochen hast...

Dadurch braucht der ATmega128 auch das blöde RAMPZ und ELPM, obwohl
bei JMP/CALL die Adressen nur 16-bittig sind (da diese Befehle
wortadressiert arbeiten).

So unsinnig ist das gar nicht. Da die Register eh nur 8 Bit breit
sind, wäre es glatte Verschwendung, wenn man immer nur 1 Wort
adressieren könnte.
Ich denke, daß das Gefummel mit dem RAMPZ deutlich ätzender ist, vor
allem für einen Compiler, wenn er nicht davon ausgehen kann, daß RAMPZ
bereits den korrekten Zustand hat. Da wäre die Verschwendung eines
Registers, indem man nur LPMW RRd, Z realisiert hätte und ggf. den
Inhalt des zweiten Registers danach verworfen, wohl nicht so tragisch
gewesen (im Gegensatz zu Intel leidet AVR gottlob nicht an
Registermangel).

Aber wahrscheinlich hat man beim Design der AVRs nicht an dieses
Dilemma gedacht, das ja nur bei den 128 KB ROM Typen entsteht. Ab 256
KB ROM kommt man um sowas wie RAMPZ nicht herum, aber dort braucht
dann auch ein absoluter JMP/CALL eine größere Adreßbreite.
--
J"org Wunsch Unix support engineer
joerg_wunsch@interface-systems.de http://www.interface-systems.de/~j/
 
Hallo!

"Jan-Hinnerk Reichert" <hinni@despammed.com> schrieb:

Till Wollenberg wrote:

In der Instruction Set Summary zum ATtiny26 steht er drin, und
der Simulator des AVR Studio simuliert ihn korrekt, wenn ich als
Device ATtiny26 einstelle.

Ich habe hier eine ältere Version des Datenblattes von September 2002.
Da steht nur der einfache "LPM" drin. In der aktuellen Version stehen
tatsächlich die Varianten mit "Post-Inc".

Ich hab' das Gefühl, daß da irgendjemand etwas übereifrig bei der
Datenblattrevision war ;-(
Ich habe inzwischen mal mit einen Testprogramm nachgesehen, was der reale
Chip bei einem LPM Rd, Z+ macht: nach Ausführung des Befehls ist ZH immer
0x00, während ZL korrekt inkrementiert wird. Selbst nach 256 LPMs läuft Z
von 0x00FF nach 0x0000 über. Auf diese Weise kann man nur die ersten 256
Bytes des Flash auslesen. Da dort mein Programmcode liegt, habe ich bei
meinen Versuchen immer sehr merkwürdige Bytes ausgelesen. Offenbar ist der
Befehl "halb" im Chip implementiert bzw. halb wieder entfernt worden... :-/

Falls der ATtiny26 die Instruktion tatsächlich nicht unterstützt,
sollte das doch inzwischen mal jemand bemerkt haben...

Vielleicht nicht, da im alten Datenblatt ja nicht drinsteht, daß er
tun soll.

Wenn es Dir die Mühe wert ist, frag' bei Atmel nach. Ansonsten würde
ich dem Chip eher vertrauen als einem Simulator...
Das habe ich getan. Mal schauen, ob Atmel antwortet.

Gruß, Till.

--
e-mail: wollenberg (at) web (punkt) de
 
Hallo!

"Joerg Wunsch" <j@ida.interface-business.de> schrieb:

Till Wollenberg <till@deadspam.com> wrote:

Verwechselst Du nicht Wort- und Byteadressen?

Das habe ich beachtet. Im Code wird das Z-Register mit 0x0400 geladen,
und in meinem Sourcecode steht ein ".ORG 0x0200" vor dem zu ladenden
Datenblock.

Eben. Zumindest für meinen Assembler (avr-as, GNU binutils) müßte man
dann auch .org 0x400 schreiben. (D. h., eigentlich würde ich gar kein
.org benutzen sondern einen Label, aber das ist was anderes.)
Ich verwende tavrasm und habe zur Sicherheit mal im erzeugten Binary
nachgesehen: bei .ORG 0x0200 erscheint der Datenblock wirklich bei
Byteposition 0x0400. Der Assembler erwartet also eine Word-Angabe.

Wenn Du Dir da sicher bist: nur zu, ich wollte Dich nur drauf hinweisen.

In der Simulation des AVR Studios verhalten sich beide
Varianten (LPM Z+ bzw. LPM Z & ADWI) dann auch völlig gleich.

Traue keiner Simulation, die Du nicht selbst verbrochen hast...
Wie wahr. Im Grunde kann der Simulator wahrscheinlich alle Befehle
"nach Datenblatt", und je nach ausgewähltem Device wird mal dieser
und mal jener Befehl ignoriert, weil ihn dieses Device nicht hat.

Gruß, Till.

--
e-mail: wollenberg (at) web (punkt) de
 
Hallo!

* "Till Wollenberg" <till@deadspam.com> schrieb:

Ein Problem mit dem Befehl LPM rd, Z+ auf einem ATtiny26 treibt
mich in den Wahnsinn. Offenbar lädt der AVR irgendetwas aus dem
Programmspeicher in das Zielregister, nur nicht die Daten, auf
die Z zeigt.
[...]
Nachdem ich per Kontaktformular bei Atmel angefragt habe, erhielt
ich heute eine Antwort per Mail. Atmel bedauert, dass der Befehl
versehentlich in die Revision D des ATtiny26-Datenblattes
aufgenommen wurde. Der Controller unterstütze LPM Rd, Z+ definitiv
nicht, und man werde diesen Fehler in Revision E beheben.

Meine Tests ergaben zwar, das LPM Z+ nicht wie vorgesehen arbeitet,
ausgeführt wird er von der CPU jedoch. Allerdings funktioniert er
nur stark eingeschränkt, da ZH bei jedem LPM Z+ auf 0x00 gesetzt
wird, und man somit nur die ersten 256 Bytes des Flash-Speichers
auslesen kann. LPM Rd, Z ist von diesem Fehler nicht betroffen.
Als Workarround empfiehlt sich ein LPM Rd, Z mit anschließendem
ADWI ZL, 0x01.

Gruß, Till.

--
e-mail: wollenberg (at) web (punkt) de
 
Till Wollenberg wrote:

Meine Tests ergaben zwar, das LPM Z+ nicht wie vorgesehen arbeitet,
ausgeführt wird er von der CPU jedoch. Allerdings funktioniert er
nur stark eingeschränkt, da ZH bei jedem LPM Z+ auf 0x00 gesetzt
wird, und man somit nur die ersten 256 Bytes des Flash-Speichers
auslesen kann. LPM Rd, Z ist von diesem Fehler nicht betroffen.
Als Workarround empfiehlt sich ein LPM Rd, Z mit anschließendem
ADWI ZL, 0x01.
Irgendwas muß der Prozessor ja tun. Eine Abfrage auf nicht erlaubte
Befehle vergrößert die Hardware. Also läßt man das Entwickler einfach
undefiniert. Was die Hardware dann letzlich bei undefinierten
Befehlen tut, weiß man vorher nicht; kann man aber natürlich
herausfinden. Man kann ganz grob sagen, daß der Befehl etwas
ähnliches tut, wie andere Befehle mit ähnlicher Binärkodierung.

Zu Zeiten des C64 wurden nicht definierte Befehle gerne benutzt, um
Kopierschutzroutinen zu verschleiern. Man bewegt sich bei sowas aber
auf dünnem Eis, da eine neue Chiprevision anders auf die
undefinierten Befehle reagieren kann.

Da auch andere ATtiny keinen LPM z+ unterstützen, würde ich von einem
Fehler in der Dokumentation (und nicht im Chip) ausgehen.

/Jan-Hinnerk
 
Jan-Hinnerk Reichert <hinni@despammed.com> wrote:

Irgendwas muß der Prozessor ja tun. Eine Abfrage auf nicht erlaubte
Befehle vergrößert die Hardware.
Vor allem: im Gegensatz zu einem Universalprozessor mit aufgeblasenen
Betriebssystem: es gibt keinen trap oder sowas, den der Prozessor dann
auslösen könnte. Die einzige Maßnahme wäre noch ein Hardware-Reset...
--
J"org Wunsch Unix support engineer
joerg_wunsch@interface-systems.de http://www.interface-systems.de/~j/
 

Welcome to EDABoard.com

Sponsor

Back
Top