mikrocontroller.net

Forum: Compiler & IDEs GCC und LDS/STS auf Attiny10


Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kämpfa gerade mit avr-gcc 4.7.2 und einem Attiny 10. Der Compiler 
weigert sich, die kurzen 8-bit LDS und STS für den Speicherzugriff zu 
nutzen, sondern erzeugt stattdessen einen indirekten Zugriff über das 
Z-Register. Das ist natürlich kompletter Unsinn und bläht den Code 
unnötig auf.

Kann man dagegen etwas tun?

z.B.
      usbTxLen = wantLen;
 3e6:  ed e4         ldi  r30, 0x4D  ; 77
 3e8:  f0 e0         ldi  r31, 0x00  ; 0
 3ea:  30 83         st  Z, r19
statt:
     sts 0x4D,r19

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim    schrieb:
> Kann man dagegen etwas tun?

Atmel nerven.  Der ganze Reduced-Core-Kram liegt derzeit einzig und
allein bei denen.  Den patchen sie selbst in den GCC rein, und meines
Wissens ist er nach wie vor in einem reichlich halbbackenen Zustand.

: Bearbeitet durch Moderator
Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denk das ist unabhängig vom Tiny und müsste sich auch mit normalen 
AVRs nachvollziehen lassen.

Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:
> Ich denk das ist unabhängig vom Tiny und müsste sich auch mit normalen
> AVRs nachvollziehen lassen.

Wenn ich den gleichen Source für einem ATtiny85 compiliere, werden an 
den gleichen Stellen 16-Bit "STS" Befehle erzeugt. Irgendwie sieht mir 
das nach einem schnellen Kompatibilitätsfix aus.

Jörg Wunsch schrieb:
> Atmel nerven.

Werde es mal machen.

: Bearbeitet durch User
Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lustig, es geht gleich weiter. AVR-GCC scheint für den ATtiny 10 andere 
calling conventions als diese hier:

http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_reg_usage

zu verwenden. Auf den normalen Cores können R18/R19 "geclobbered" 
werden, auf dem ATtiny 10 geht der compiler offenbar davon aus, dass 
diese erhalten bleiben. Nur wo ist das dokumentiert?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim    schrieb:
> Lustig, es geht gleich weiter. AVR-GCC scheint für den ATtiny 10 andere
> calling conventions als diese hier:

Nicht ganz überraschend, wenn man bedenkt, dass es R0-R15 nicht gibt.

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim    schrieb:
> Lustig, es geht gleich weiter. AVR-GCC scheint für den ATtiny 10 andere
> calling conventions als diese hier:

Was angesichts des nur halben Registersatzes ja nicht verwunderlich
ist.

> Nur wo ist das dokumentiert?

Atmel fragen. ;-)

Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
> Atmel fragen. ;-)

Gerade geschehen :)

Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, sieht aus, als wenn ich einfach noch mehr Assembler verwenden 
muss.
Schade, ich hatte V-USB auf dem Attiny 10 schon so weit, dass die ersten 
Requests beantwortet wurden.

Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So funktioniert es immerhin als define:
         uint8_t out;
         uint8_t adr=1;

         asm volatile(      
          "         lds  %0,%1 \n\t"        
          : "=&d" (out)
          :  "M" (adr)
         );           

Leider funktioniert es nicht, wenn "adr" ein Pointer auf eine Variable 
im Speicher ist:
main.c:160:10: warning: asm operand 1 probably doesn't match constraints [enabled by default]
main.c:160:10: error: impossible constraint in 'asm'

Wie bringe ich dem Compiler bei, dass die pointer konstant sind?

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
adr ist ja auch keine Compilezeit-Konstrante, &adr ist es, zumindest für 
adr im Static Storage.

: Bearbeitet durch User
Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der code oben compiliert ohne Fehlermeldung.

Dieser aber nicht, trotz pointer auf static.
         uint8_t out;
         static uint8_t adr=1;

         asm volatile(      
          "         lds  %0,%1 \n\t"        
          : "=&d" (out)
          :  "M" ((uint8_t)&adr)
         );   

Ich habe es aber jetzt auch so in den Speicher bekommen. Ich werde erst 
einmal abwarten, was vom Ateml support kommt, bevor ich Arbeit in 
Workarounds investiere.

Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und hier noch ein Aufreger. Cast von statischem 16 pointer auf 8 bit 
const:
#define usbMsgPtr_t uchar *
...
 usbMsgPtr = (usbMsgPtr_t)(&usbDescriptorDevice[12]); 
 340:  40 e2         ldi  r20, 0x20  ; 32
 342:  50 e0         ldi  r21, 0x00  ; 0
 344:  d4 2f         mov  r29, r20

Ich nehme an, das ist ein prinzipielles Problem durch die angenommene 16 
Bit Maschinenwortgröße?

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Tim    schrieb:
>           :  "M" ((uint8_t)&adr)

M ist auch die falsche Constraint, nimm i.

Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geht leider auch nicht. Ich dachte "i" wäre für 6 bit (register) und "M" 
für 8 bit?

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Nein, "i" steht für Immediate, also "s" (symbolic) oder "n" (compile 
time constant).  Folgender Code geht für nicht-Tiny und sollte auch mit 
Tinys gehen:
char fout (void)
{
    char out;
    static char adr = 1;

    asm volatile (
        "lds %0,%1"
        : "=d" (out) : "i" (&adr) : "memory"
    );
    
    return out;
}

: Bearbeitet durch User
Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super, danke! Jetzt geht es!
#define LDS(out,mem) \
    asm volatile ("lds %0,%1"  : "=d" (out) : "i" (&mem));

Das "memory"-clobber keyword kann ich für Ladebefehle aber weglassen, 
oder? Ansonsten würdem im schlechtesten Fall ja Variablen doppelt 
geladen werden.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Lesen eines SFR's kann prinzipiell diese oder gar ein anderes SFR 
verändern.  Wenn nur RAM gelesen wird, kann das memory-clobber weg, und 
auch das volatile kann dann entfallen dürfen.

Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke! Hat im ganzen Code 32 Bytes gespart. Da hat Atmel noch ein paar 
Hausaufgaben.

Es handelt sich übrigens um eine minimal USB-Implementierung auf einem 
ATtiny 10. Wahrscheinlich das komplexeste für den ATtiny10 existierende 
Programm :)

Und es funktioniert sogar:

https://github.com/cpldcpu/u-wire

Autor: Falk B. (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, bei 1 K Flash kann man's auch gleich in ASM machen, da würde ich 
nicht so einen Würg Around mit dem Compiler veranstalten.

Edit: Ich vermisse 100nF am AVR.

: Bearbeitet durch User
Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner schrieb:
> Naja, bei 1 K Flash kann man's auch gleich in ASM machen, da würde
> ich
> nicht so einen Würg Around mit dem Compiler veranstalten.

Klar, aber irgendwie ist es nicht der Sinn der Sache, existierende 
C-Programme in Assembler nachzuprogrammieren. Vor allem das Zuweisen der 
Register und die Optimierung von langen Switch/If-Konstrukten überlasse 
ich gerne dem C-Compiler. Das kann er aber besser, je mehr 
zusammenhängenden Code er sieht.

Ich hoffe ja, das Atmel die bestehenden Bugs im Compiler noch beseitigt, 
damit ich die Workaround wieder entfernen kann.

> Edit: Ich vermisse 100nF am AVR.

Du meinst den Aufbau auf dem Broadboard? Da verbergen sich etliche 
passive Bauteile auf den Rückseiten der Break-Out boards.

Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim    schrieb:
> Lustig, es geht gleich weiter. AVR-GCC scheint für den ATtiny 10 andere
> calling conventions als diese hier:
>
> http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_reg_usage
>
> zu verwenden. Auf den normalen Cores können R18/R19 "geclobbered"
> werden, auf dem ATtiny 10 geht der compiler offenbar davon aus, dass
> diese erhalten bleiben. Nur wo ist das dokumentiert?

Hier die Antwort vom Atmel-Support. Das andere Problem schauen sie sich 
noch an.

As per current implementation (till Tool chain 3.4.3), below is the register conventions used for AVR_TINY devices:

r16 - Fixed/ TMP
r17 - Fixed/ ZERO
r18 - Callee saved
r19 - Callee saved
r20 - arg
r21 - arg
r22 - ret/ arg
r23 - ret/ arg
r24 - ret/ arg
r25 - ret/ arg
r26 - X
r27 - X
r28 - Y/ FP/ Callee saved
r29 - Y/ FP/ Callee saved
r30 - Z
r31 - Z

: Bearbeitet durch User
Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmmm, das scheint wirklich nur die mini-Tinys zu betreffen, etwa:
extern char c, d;

void f1 (void)
{
    c = d;
}

gibt:
f1:
  ldi r30,lo8(d)   ;  5  *movhi/5  [length = 2]
  ldi r31,hi8(d)
  ld r20,Z   ;  6  movqi_insn/4  [length = 1]
  ldi r30,lo8(c)   ;  7  *movhi/5  [length = 2]
  ldi r31,hi8(c)
  st Z,r20   ;  8  movqi_insn/3  [length = 1]
  ret   ;  15  return  [length = 1]


Und auch an anderen Stellen muß Atmel noch nachsitzen:
int f3 (const __flash int *p)
{
    return *p;
}
.s: Assembler messages:
.s:18: Error: illegal opcode elpm for mcu attiny10
.s:19: Error: register not supported
.s:20: Error: illegal opcode sbiw for mcu attiny10
.s:21: Error: illegal opcode elpm for mcu attiny10
.s:22: Error: register not supported

Zudem ist eine Meldung (:20) auch noch falsch: Es wird ADIW erzeugt, 
nicht SBIW.

Autor: Tim  . (cpldcpu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Support hat ganz erstaunt nach Codebeispielen gefragt. Bei einem so 
leicht zu reproduzierenden Problem gibt mir das zu denken :) Ich hatte 
ihnen den Auszug aus dem Listingfile geschickt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.