Datum:
Hi. Der Eine oder Andere ist vllt. schon auf die relativ neuen Instruktionen im AVR Instruction Set gestoßen: LAC – Load And Clear LAS – Load And Set LAT – Load And Toggle XCH – Exchange Diese Operationen ermöglichen eine simple, effiziente und sehr elegante Implementierung von Synchronisierungsoperationen, z.B. zwischen "main()" und ISRs. AVR Studio 5 kennt diese Instruktionen aber (zumindest im gcc-Inline-Assembler) noch nicht - obwohl der Disassembler sie korrekt darstellt. Es scheint keine Übersicht zu geben, welche AVRs diese Befehle unterstützen und welche nicht. Deshalb bin ich auf die Idee gekommen, ein bisschen zu testen: Ein ATmega1284P (Bj. 50/2010) unterstützt die Befehle jedenfalls weder im Simulator noch auf der echten Hardware. Bei einem ATxmega128A3 funktionieren sie dagegen zumindest im Simulator. Mich würde interessieren, auf welcher AVR-Hardware die Befehle außerdem noch implementiert sind - evtl. eben auch undokumentiert. (Atmels Doku hängt ja manchmal etwas hinterher...) Deshalb lade ich alle herzlich ein, auf den AVRs, die sie gerade zur Hand haben, einmal zu probieren, ob's geht oder nicht. Um die Instruktionen auch ohne Assembler-/Compiler-Unterstützung nutzen zu können, habe ich ein paar cpp-Macros gebastelt:
#define ASM_LAC_OPCODE(reg) ((0b1001001000000110) | (reg << 4)) #define ASM_LAS_OPCODE(reg) ((0b1001001000000101) | (reg << 4)) #define ASM_LAT_OPCODE(reg) ((0b1001001000000111) | (reg << 4)) #define ASM_XCH_OPCODE(reg) ((0b1001001000000100) | (reg << 4)) #define xstr(s) str(s) #define str(s) #s #define __ASM_WORD(opcode) ".word " xstr( opcode ) " \n" #define ASM_LAC(reg) __ASM_WORD(ASM_LAC_OPCODE(reg)) #define ASM_LAS(reg) __ASM_WORD(ASM_LAS_OPCODE(reg)) #define ASM_LAT(reg) __ASM_WORD(ASM_LAT_OPCODE(reg)) #define ASM_XCH(reg) __ASM_WORD(ASM_XCH_OPCODE(reg)) |
(für "reg" wird die Nummer des gewünschten Registers übergeben: 0 für r0, 1 für r1, ..., 31 für r31) Mit diesen lässt sich im gcc-Inline-Assembler ein entsprechender Opcode einbauen, z.B.:
asm volatile ( "mov r0, r24 \n" ASM_XCH(0) "mov r25, r0 \n" : : : "r0", "r25" ); |
was übersetzt wird zu:
mov r0, r24 xch r0 mov r25, r0 |
Ein einfacher Funktionstest könnte dann so aussehen:
volatile uint8_t flag; ... uint8_t valIn; uint8_t valOut; flag = 0xf0; valIn = 0x0f; // Muss != flag sein! asm volatile ( "mov r0, %[valIn] \n" ASM_XCH(0) "mov %[valOut], r0 \n" : [valOut] "=&r" (valOut) : [valIn] "r" (valIn), [flag] "z" (&flag) : "r0" ); if ( valOut == valIn ) { // Schade, nichts passiert :-/ } else { // Glueckwunsch: Die Operation wird unterstuetzt! :) } |
Ich bitte um Feedback, falls jemand weitere Informationen zur Verfügbarkeit dieser interessanten Befehle auf AVR-Hardware hat! :) Viele Grüße Hanno
Datum:
Hanno schrieb: > AVR Studio 5 kennt diese Instruktionen aber (zumindest im > gcc-Inline-Assembler) noch nicht - obwohl der Disassembler sie korrekt > darstellt. Die binutils unterstützen diese Instruktionen noch nicht. Wenn der Disassembler sie darstellen kann (avr-objdump), dann hat A wohl Unterstützigs dafür eingebau — was etwa 1 Zeile pro Befehl in include/opcode/avr.h werden dürfte. Die Codierung ist die gleiche wie für ASR, ROR, LSR, COM, DEC, INC, NEG, POP, PUSH. > Mich würde interessieren, auf welcher AVR-Hardware die Befehle außerdem > noch implementiert sind M.W. Xmega. > Um die Instruktionen auch ohne Assembler-/Compiler-Unterstützung nutzen > zu können, ... Wenn sie disassembliert werden können, also im BFD implementiert sind und avr-objdump sie kennt, sollte avr-as sie doch auch assemblieren können? > Ein einfacher Funktionstest könnte dann so aussehen: > > volatile uint8_t flag; > ... > uint8_t valIn; > uint8_t valOut; > > flag = 0xf0; > valIn = 0x0f; // Muss != flag sein! Warum das? Es muss doch auch funcktionieren, wenn beide gleich sind. > : [valOut] "=&r" (valOut) Nein, hier kein early-clobber! So: > : [valOut] "=r" (valOut) Sinnvoll wäre eine Unterstützung in Form von Built-ins wie __builtin_avr_atomic_exchange() der auf die entsprechende Funktion abbildet falls vorhanden und ansonsten eine kleine Instruktionssequenz einfügt. Damit wären die Built-ins auf allen AVRs verfügbar, analog zu __builtin_avr_fmul die auch da sind, wenn es kein FMUL-Befehl gibt. Ausserdem könnte der Compiler optimieren, wenn Befehl/Maske/Adresse für SBI bzw. CBI passt. @Admin: Das passt besser nach "GCC".
Datum:
Nanu. Ist das nicht schonmal diskutiert worden? Beitrag "AVR: Undokumentierte LAT Instruktion?" Danach sind lediglich andere Mnemonics verwendet worden, aber die Befehle selbst sind, nach deren Operationscode, nicht neu.
Datum:
Hm. Scheint doch nicht das selbe zu sein. Die Operationscodes sind unterschiedlich.
Datum:
>> valIn = 0x0f; // Muss != flag sein! > Warum das? Es muss doch auch funcktionieren, wenn beide gleich sind. Natürlich! - Aber wenn beide Werte gleich sind, hat XCH keine sichtbaren Auswirkungen und man kann nicht testen, ob es unterstützt wird oder nur als unbekannter Opcode übersprungen wurde :)
Datum:
Hanno schrieb: > Ein ATmega1284P (Bj. 50/2010) unterstützt die Befehle jedenfalls weder > im Simulator noch auf der echten Hardware. Stehen ja auch nicht in dessen Datenblatt. Die standard AVRs werden, wie es scheint, nicht mehr weiterentwickelt. Also brauchst Du Dir keine Sorgen um die neuen Befehle zu machen. Ich finde es nicht besonders clever von Atmel, neue Features in MCs einzubauen, die nicht pin- und spannungskompatibel zu den etablierten AVR-Serien sind. Peter
Datum:
Peter Dannegger schrieb: > Ich finde es nicht besonders clever von Atmel, neue Features in MCs > einzubauen, die nicht pin- und spannungskompatibel zu den etablierten > AVR-Serien sind. Wieso? Die Xmega waren noch nie binärkompatibel zu den klassischen AVRs. Wenn du von "Classic" nach "Xmega" wechselst, muss eh aller C-Code neu übersetzt werden bzw. der asm-Code angepasst werden... Und mit der Begründung hätten AVRs heute immer noch kein MUL-Befehl.
Datum:
>> Ein ATmega1284P (Bj. 50/2010) unterstützt die Befehle jedenfalls weder >> im Simulator noch auf der echten Hardware. > Stehen ja auch nicht in dessen Datenblatt. Stimmt natürlich. - In der Instruction Set Doku steht aber bei denen auch nicht der Hinweis, dass die nicht auf allen AVRs verfügbar sind. Anders also als z.B. für MUL & Andere. Soviel zur Atmel-Dokumentation. Jedenfalls hatte ich gehofft, dass die Kommandos vllt. ohne gesonderte Doku in neuere (mega-)AVRs eingeflossen sind. - Sowas passiert ja schonmal, wenn neuere und ältere Produktreihen in der Entwicklung/Fertigung konsolidiert werden, um Kosten zu sparen.
Datum:
Johann L. schrieb: > Die Xmega waren noch nie binärkompatibel zu den klassischen AVRs. Das neu Compilieren stört mich nicht. Aber daß ich neue Schaltungen und neue Platinen entwickeln und testen muß, ist sehr ärgerlich. Wir haben nur kleine Serien, da wirken sich solche Kosten erheblich aus. Wenn ein neuer MC nach außen kompatibel wäre, würde das die Kosten und auch das Risiko erheblich senken. Falls der neue MC dann doch nicht geht, kann man ihn einfach wieder durch den alten ersetzen und muß nicht nen Haufen bestückter Platinen wegschmeißen. Peter
Datum:
Peter Dannegger schrieb: > Johann L. schrieb: >> Die Xmega waren noch nie binärkompatibel zu den klassischen AVRs. > > Das neu Compilieren stört mich nicht. Aber daß ich neue Schaltungen und > neue Platinen entwickeln und testen muß, ist sehr ärgerlich. > Wir haben nur kleine Serien, da wirken sich solche Kosten erheblich aus. ah, Du meinst mit "neuen Features" also solche, die die physikalischen Eigenschaften betreffen, nicht "interne" Features wie die o.g. neuen Instruktionen?
Datum:
Ich meine natürlich neue interne Features (Peripherie, Instruktionen), wie es früher bei den AVRs erfolgte, z.B.: ATtiny15 -> ATtiny85 ATtiny26 -> ATtiny861 ATmega8 -> ATmega328p ATmega16 -> ATmega1284p ATmega128 -> ATmega2561 Kunden sind naturgemäß nie zufrieden und wollen zusätzliche Funktionen. Und wenn man dazu auf der Platine nur nen anderen Chip bestücken muß, ist das ein riesen Vorteil gegenüber alles komplett neu zu machen. Auch gewinnt man damit Zeit, der Kunde erhält erstmal nur das Gerät mit dem neuen Chip und das Firmwareupdate mit den Zusatzfunktionen wird nachgereicht. Ist ein Hersteller aber nicht mehr kompatibel, verliert er die Kundenbindung. Wenn ich erst ne neue Schaltung machen muß, dann kann ich auch gleich einen völlig anderen MC nehmen. Und so wirds bei uns wohl auch laufen, NXP Cortex M3 ist angedacht. Peter
Datum:
So verständlich deine Forderungen auch sein mögen, sie passen nicht mehr zum gegenwärtigen Zeitgeist. Die Entwicklungszyklen werden immer kürzer, so auch der gepflegte lifecycle. Produkte werden mit heißer Nadel rausgehauen, Hauptsache es besteht Hoffnung, dass sie die Gewährleistungsfristen mit annehmbaren Risiken überstehen. Danach soll der Kunde neue und bessere Versionen des Produkts kaufen. Geworben wird mit servicefreundlichem Replacement. Ein Produkt, dass mehrere Jahre unbeschadet übersteht ist nicht mehr gewollt. Ein Qualitätsmanagement ist erstrangig dazu da, das Produkt gerade noch so ausreichend zu produzieren, dass juristische Risiken des Herstellers minimiert werden können. All dies hat natürlich auch Auswirkungen auf die Beschaffung von Bauteilen. Die Produktvielfalt explodiert, während die Verfügbarkeit immer kürzer wird.
Datum:
Peter Dannegger schrieb: > Wenn ein neuer MC nach außen kompatibel wäre Das stehst du als Hersteller irgendwann nicht mehr durch. Der Wunsch nach neuen Features kollidiert dann so stark mit dem nach der Rückwärtskompatibilität, dass die Auflösung nur in "mach was völlig Neues" bestehen kann. Das hat Atmel mit dem Xmega letztlich getan. Der Grund dafür ist, dass man für die Weiterentwicklung unbedingt kleinere Strukturgrößen im Prozess braucht (schließlich willst du ja nicht den exorbitanten Preis größerer Chips bezahlen), dass aber Prozesse mit kleinerer Strukturgröße notgedrungen nicht mehr so spannungsfeste Bauteile bringen. Was denkst du, warum die Core- Spannungen aktueller Desktop-CPUs irgendwo im Bereich von 1 V angekommen sind? Weil die Prozesse so klein sind. OK, man hätte die Masse- und Betriebsspannungspins noch irgendwie pinkompatibel lassen können, da gebe ich dir Recht. Vielleicht auch noch JTAG, aber schon PDI als Ablösung für ISP ist ja hinreichend anders. deka-dent schrieb: > Produkte werden mit heißer Nadel > rausgehauen, Hauptsache es besteht Hoffnung, dass sie die > Gewährleistungsfristen mit annehmbaren Risiken überstehen. Mit Verlaub, aber das, was du da von dir gibst, ist reines Gesülze und hat mit der Realität eines Halbleiterherstellers herzlich wenig zu tun.
Datum:
Jörg Wunsch schrieb: > deka-dent schrieb: >> Produkte werden mit heißer Nadel >> rausgehauen, Hauptsache es besteht Hoffnung, dass sie die >> Gewährleistungsfristen mit annehmbaren Risiken überstehen. > > Mit Verlaub, aber das, was du da von dir gibst, ist reines Gesülze > und hat mit der Realität eines Halbleiterherstellers herzlich wenig > zu tun. Das bezog sich wohl auf irgendwelche Billig- oder Wegwerf-Produkte, die mit diesen ICs hergestellt werden?
Datum:
Jörg Wunsch schrieb: > Was denkst du, warum die Core- > Spannungen aktueller Desktop-CPUs irgendwo im Bereich von 1 V > angekommen sind? Weil die Prozesse so klein sind. Die sind dort angekommen, weil man dank kleiner Strukturen mit niedrigeren Spannungen arbeiten kann und aufgrund der Verlustwärme arbeiten muss. Mit einem höher auflösenden Herstellungsprozess kann man aber auch grössere Strukturen erzeugen, nur umgekehrt geht es nicht. Die Transistoren der I/O-Pins sind aufgrund der viel grösseren Last in jedem Prozess viel grösser als rein interne mit nur lokaler Verbindung. Zudem sind unterschiedliche Power Supply Domains mittlerweile nicht nur bei PC-Prozessoren verbreitet, sondern auch bei Controllern. Freilich geht der Trend weg von 5V, unübersehbar und überall. Die Frage war also eher, ob man noch 5V-Kompatibilität einbaut oder nicht. Wenn man die verwirft, dann kann man auch den nächsten Schritt gehen und eine einengende Pinkompatibilität aufgeben. Irgendwann muss man es wohl, und das ist der beste Zeitpunkt. Für den Anwender wiederum ist das natürlich der logische Zeitpunkt, um sich auch man anderswo umzusehen. Wenn man sowieso schon ein Redesign braucht.
Datum:
A. K. schrieb: > Zudem > sind unterschiedliche Power Supply Domains mittlerweile nicht nur bei > PC-Prozessoren verbreitet, sondern auch bei Controllern. Richtig, aber wenn du nicht mit externen Schaltreglern anfangen willst, dann verheizt man am Ende einen Haufen Energie in einem Linearregler, wenn die Differenz zu groß wird. Ist also alles irgendwo ein Kompromiss. > Freilich geht der Trend weg von 5V, unübersehbar und überall. Ja, so sehe ich das auch. > Wenn man sowieso schon ein Redesign > braucht. Wobei man es ja nicht zwangsläufig muss, schließlich hat Atmel ja keineswegs die MegaAVR-Linie irgendwie abgekündigt oder dergleichen. Wenn man bei 5 V bleiben will, kann man also durchaus weiterhin so arbeiten wie bisher. Vorteil des Übergangs vom MegaAVR zum Xmega ist, dass man im Wesentlichen mit den gleichen Tools weiterarbeiten kann.
Datum:
Hanno schrieb: > die relativ neuen Instruktionen im AVR Instruction Set > > LAC – Load And Clear > LAS – Load And Set > LAT – Load And Toggle > XCH – Exchange > > [...] Um die Instruktionen auch ohne Assembler-/Compiler-Unterstützung > nutzen zu können, habe ich ein paar cpp-Macros gebastelt: >
#define ASM_LAC_OPCODE(reg) ((0b1001001000000110) | (reg << 4)) #define ASM_LAS_OPCODE(reg) ((0b1001001000000101) | (reg << 4)) #define ASM_LAT_OPCODE(reg) ((0b1001001000000111) | (reg << 4)) #define ASM_XCH_OPCODE(reg) ((0b1001001000000100) | (reg << 4)) #define xstr(s) str(s) #define str(s) #s #define __ASM_WORD(opcode) ".word " xstr( opcode ) " \n" #define ASM_LAC(reg) __ASM_WORD(ASM_LAC_OPCODE(reg)) #define ASM_LAS(reg) __ASM_WORD(ASM_LAS_OPCODE(reg)) #define ASM_LAT(reg) __ASM_WORD(ASM_LAT_OPCODE(reg)) #define ASM_XCH(reg) __ASM_WORD(ASM_XCH_OPCODE(reg)) |
> Ich bitte um Feedback, falls jemand weitere Informationen zur > Verfügbarkeit dieser interessanten Befehle auf AVR-Hardware hat! :) Inzwischen sind die Befehle in den binutils verfügbar. Bei Interesse kann ich einen Link auf eine Windows-Toolchain posten mit • avr-gcc 4.7.1 • binutils 2.23 • AVR-libc 1.8.1 Nach den Patches zu urteilen dürften auch neuere Versionen der Atmel-Tools diese Instruktionen kennen — zumindest die binutils. Damit sieht der Code dann zum Beispiel so aus:
#include <avr/io.h> static inline __attribute__((__always_inline__)) uint8_t xch (uint8_t volatile *p, uint8_t x) { __asm volatile ("xch %a1,%0" : "+r"(x) : "z"(p) : "memory"); return x; } int main (void) { return xch (&PORTB.DIR, 0); } |
Der erzeugte Code mit -Os -mmcu=atxmega16a4
main: ldi r24,0 ldi r30,lo8(32) ldi r31,lo8(6) /* #APP */ ; 6 "" 1 xch Z,r24 ; 0 "" 2 /* #NOAPP */ ldi r25,0 ret |
Und das Disassembly:
0000018a <main>: 18a: 80 e0 ldi r24, 0x00 ; 0 18c: e0 e2 ldi r30, 0x20 ; 32 18e: f6 e0 ldi r31, 0x06 ; 6 190: 84 93 xch Z, r24 192: 90 e0 ldi r25, 0x00 ; 0 194: 08 95 ret |
Datum:
A. K. schrieb: > Für den Anwender wiederum ist das natürlich der logische Zeitpunkt, um > sich auch man anderswo umzusehen. Wenn man sowieso schon ein Redesign > braucht. Ich bin auch ein Anhänger des ATMega und wollte auch den Schritt zum XMega gehen. Stattdessen bin ich dann beim PIC24 gelandet, der meines Erachtens ein wirklich sehr guter (16Bit) µC ist.