AVR Shl mit Konstante

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.

AVR Shl mit Konstante

Beitragvon Mathias » 24. Jul 2018, 17:08 AVR Shl mit Konstante

Dieses Miniprogramm spuckt auf dem PC wie erwartet 14 True aus.
Code: Alles auswählen
procedure sendIntValueSPI(Value: uint16);
var
  dw: boolean;
  i: int8;
begin
  Value := $FFFF;
  for i := 11 downto 0 do begin
    dw := (Value and (1 shl i)) > 0;
    Write(dw, ' ');
  end;
end;
 
begin
  sendIntValueSPI(0);
end.


Auf dem Arduino fast der gleiche Code. Aber hier blinkt die LED, welche an PortC Pin3 angeschlossen ist.
Eigentlich müsste sie konstant leuchten, da dw eigentlich immer true sein müsste.

Ersetze ich in der Schleife WritePortB(3, dw); auf WritePortB(3, true); dann leuchtet die LED konstant.
Somit wird die Auswertung von dw auf dem PC anders gehandhabt wie auf dem AVR.

Wo liegt das Problem ? :roll:

Code: Alles auswählen
program Project1;
 
{$O-}
 
  procedure mysleep(t: int32);
  var
    i: Int32;
  begin
    for i := 0 to t do begin
      asm
               Nop;
      end;
    end;
  end;
 
  procedure ModePortB(Pin: byte; Value: boolean);
  begin
    if Value then begin
      DDRC := DDRC or (1 shl Pin);
    end else begin
      DDRC := DDRC and not (1 shl Pin);
    end;
  end;
 
  procedure WritePortB(Pin: byte; Value: boolean);
  begin
    if Value then begin
      PORTC := PORTC or (1 shl Pin);
    end else begin
      PORTC := PORTC and not (1 shl Pin);
    end;
  end;
 
  procedure sendIntValueSPI(Value: uint16);
  var
    dw: boolean;
    i: int8;
  begin
    Value := $FFFF;
 
    for i := 11 downto 0 do begin
      dw := (Value and (1 shl i)) > 0;
      mysleep(10000);
      WritePortB(3, dw);
    end;
  end;
 
begin
  ModePortB(3, True);
  repeat
    sendIntValueSPI(0);
  until 1 = 2;
end.
Zuletzt geändert von Mathias am 24. Jul 2018, 20:28, insgesamt 1-mal geändert.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4107
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Mathias » 24. Jul 2018, 17:18 Re: AVR For-To Falsch

Fehler gefunden, wen ich die Konstante 1 auf UInt16 erzwinge, dann geht es.
Code: Alles auswählen
      dw := (Value and (UInt16(1) shl i)) <> 0;

Anscheinend werden Konstanten von 0-255 auf dem AVR auf 8Bit gesetzt.

Nachtrag:
Ist auf dem PC auch so, aber auf dem PC wird dann shl anders ausgewertet.
Code: Alles auswählen
  WriteLn(SizeOf(1));       // --> 1
  WriteLn(SizeOf(1000));    // --> 2
  WriteLn(SizeOf(100000))// --> 4


Ist dies ein Bug bei AVR oder ist dies so gewollt ?

Noch auf dem AVR getestet, die Kontanten sind gleich gross wie auf dem PC.
Code: Alles auswählen
    b := SizeOf(1);
    str(b, s);
    UARTSendString(s + '  '); // --> 1
 
    b := SizeOf(1000);
    str(b, s);
    UARTSendString(s + '  '); // --> 2
 
    b := SizeOf(100000);
    str(b, s);
    UARTSendString(s + '  '); // --> 4
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4107
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Mathias » 24. Jul 2018, 20:36 Re: AVR Shl mit Konstante

Mit folgendem Mini-Beispiel, sieht man den Fehler gut.
Code: Alles auswählen
var
  i, ii: UInt16;
  s: string;
begin
  UARTInit;
 
  for i := 0 to 15 do begin
    ii := (1 shl i); // einfach
    str(ii:8, s);
    UARTSendString(s);
    ii := (UInt16(1) shl i)// mit UInt16
    str(ii:8, s);
    UARTSendString(s);
 
    UARTSendString(#13#10);
  end;
 
  repeat
    if UARTReadChar = #32 then begin
      UARTSendString('Hello World !'#13#10);
    end;
  until 1 = 2;
end.

Ausgabe:
Code: Alles auswählen
       1       1
       2       2
       4       4
       8       8
      16      16
      32      32
      64      64
   65408     128
       0     256
       0     512
       0    1024
       0    2048
       0    4096
       0    8192
       0   16384
       0   32768
So wie es aussieht wird ein ShortInt (int8) verwendet.
Bei der achten Zeile passiert sowieso was komisches. Irgendwie bringt er noch das Vorzeichen durcheinander.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4107
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Timm Thaler » 24. Jul 2018, 21:31 Re: AVR Shl mit Konstante

Wie sieht denn das Assembler-Listing aus? Mit welcher Optimierung kompilierst Du für Avr?
Timm Thaler
 
Beiträge: 618
Registriert: 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded | 
CPU-Target: Raspberry Pi 3
Nach oben

Beitragvon Mathias » 24. Jul 2018, 22:59 Re: AVR Shl mit Konstante

{O-} Ist im obigen Code sichtbar.
Den Assemblercode muss ich morgen mal angucken.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4107
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon kupferstecher » 24. Jul 2018, 23:11 Re: AVR Shl mit Konstante

Im englischen Forum gab es eine aehnliche Diskussion (Link unten), Problem ist das Vorzeichen welches in i steckt. Nach der verlinkten Diskussion ist shl immer eine logische Operation, nimmt auf das Vorzeichen keine Ruecksicht.

In der 8ten Zeile ist ja i=7, also
(1 shl int8(7) ) das ergibt %10000000, was -128 ist. Wie der Compiler jetzt auf das ausgedruckte Ergebnis kommt, ist mir nicht ganz klar. So wie es aussieht erweitert er das Vorzeichen auf die 16 bit und interpretiert die Zahl dann als unsigned.


http://forum.lazarus.freepascal.org/ind ... 88697.html

Nachtrag: Das ist natuerlich Mist. Der Compiler sollte da nicht signed-Variablen annehmen, wenn die shl-Operation sowieso das Vorzeichen ignoriert.
kupferstecher
 
Beiträge: 142
Registriert: 17. Nov 2016, 11:52

Beitragvon Timm Thaler » 25. Jul 2018, 03:00 Re: AVR Shl mit Konstante

kupferstecher hat geschrieben:Im englischen Forum gab es eine aehnliche Diskussion (Link unten), Problem ist das Vorzeichen welches in i steckt. Nach der verlinkten Diskussion ist shl immer eine logische Operation, nimmt auf das Vorzeichen keine Ruecksicht.


Nee, in i steckt kein Vorzeichen. Das erste "Problem" ist, dass wie in Pascal üblich, 1 nur ein Byte belegt. Wird das geschiftet, geht das solange gut, bis es bei shl 8 überläuft. Dann ist das Lowbyte nur noch Null, das Highbyte wird nicht beachtet. Aber das ist immer bei Operationen so.

Code: Alles auswählen
# [14] ii := (1 shl i); // einfach
   ldi   r19,1
   lds   r18,(U_sPsTEST_ss_I)
   tst   r18
   breq   .Lj7
.Lj6:
   lsl   r19
   dec   r18
   brne   .Lj6
.Lj7:


Wird die 1 vor dem shl auf 2 Byte erweitert, klappt auch das Shift.

Code: Alles auswählen
# [17] ii := (UInt16(1) shl i)// mit UInt16
   ldi   r19,1
   mov   r18,r1
   lds   r20,(U_sPsTEST_ss_I)
   tst   r20
   breq   .Lj9


Das Vorzeichen-Problem ist dann später bei der Zuweisung auf den String. Hier wird fpc_shortstr_word aufgerufen. Allerdings wird hier ii mit Vorzeichen erweitert, obwohl ii unsigned ist. Das ist ein Fall für einen Bugreport, würde ich sagen.

Code: Alles auswählen
   mov   r20,r19
   mov   r18,r1
   sbrc   r19,7
   com   r18
   sts   (U_sPsTEST_ss_II),r20
   sts   (U_sPsTEST_ss_II+1),r18
Timm Thaler
 
Beiträge: 618
Registriert: 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded | 
CPU-Target: Raspberry Pi 3
Nach oben

Beitragvon kupferstecher » 25. Jul 2018, 12:23 Re: AVR Shl mit Konstante

Mathias hat geschrieben:Mit folgendem Mini-Beispiel, sieht man den Fehler gut.

Habs jetzt selber probiert, bei mir funktionierts erwartungsgemäß, d.h. richtig. Ich verwende die FPC-Version 3.1.1 [2018/03/01], getestet mit -O0 , -O1, -O4. Ergebnis jeweils gleich. Die Frage ist jetzt ob du eine neuere oder ältere Version verwendest.

Das ist die Ausgabe:
Code: Alles auswählen
       1       1
       2       2
       4       4
       8       8
      16      16
      32      32
      64      64
     128     128
       0     256
       0     512
       0    1024
       0    2048
       0    4096
       0    8192
       0   16384
       0   32768


Timm Thaler hat geschrieben:Nee, in i steckt kein Vorzeichen.

Doch schon, aber du hast wahrscheinlich recht, dass das Problem hier an der Konstanten liegt, die vorzeichenbehaftet verarbeitet wird.


Das erste "Problem" ist, dass wie in Pascal üblich, 1 nur ein Byte belegt. Wird das geschiftet, geht das solange gut, bis es bei shl 8 überläuft. Dann ist das Lowbyte nur noch Null, das Highbyte wird nicht beachtet. Aber das ist immer bei Operationen so.

Ja, das ist soweit klar. Man kann sicher damit leben, schön ist es aber nicht.

Das Vorzeichen-Problem ist dann später bei der Zuweisung auf den String. Hier wird fpc_shortstr_word aufgerufen. Allerdings wird hier ii mit Vorzeichen erweitert, obwohl ii unsigned ist. Das ist ein Fall für einen Bugreport, würde ich sagen.

Die Variable ii ist doch schon vor der Zuweisung auf den String vom Typ uInt16. Die Vorzeichenerweiterung muss also zur Zeile ii := (1 shl i); gehören. Aber wie gesagt, bei mir funktioniert es, wäre die Frage, ob es ein neuer Bug ist, oder bereits gelöst.
kupferstecher
 
Beiträge: 142
Registriert: 17. Nov 2016, 11:52

Beitragvon Mathias » 25. Jul 2018, 12:54 Re: AVR Shl mit Konstante

Könnte ein neuer Bug sein, da dein fpc vom März ist. Meines ist keine 14 Tage alt.

Ich sehe gerade, du hast eine 128, aber mit den grösseren Werte hast du aber auch Probleme.
Somit ist eine Typenumwandlung sowieso nötig ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4107
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Timm Thaler » 25. Jul 2018, 13:33 Re: AVR Shl mit Konstante

kupferstecher hat geschrieben:Die Variable ii ist doch schon vor der Zuweisung auf den String vom Typ uInt16. Die Vorzeichenerweiterung muss also zur Zeile ii := (1 shl i); gehören. Aber wie gesagt, bei mir funktioniert es, wäre die Frage, ob es ein neuer Bug ist, oder bereits gelöst.


Ja, bei der Zuweisung in ii wird erweitert. Meiner Meinung nach ist das falsch, da auf ein unsigned int nicht mit signed erweitert werden darf.

Meine Version ist "FPC 3.1.1-r38520 [2018/03/13] for avr - embedded", jaja, ich müsste mal updaten.
Timm Thaler
 
Beiträge: 618
Registriert: 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded | 
CPU-Target: Raspberry Pi 3
Nach oben

Beitragvon Mathias » 25. Jul 2018, 16:27 Re: AVR Shl mit Konstante

Meine Version ist "FPC 3.1.1-r38520 [2018/03/13] for avr - embedded", jaja, ich müsste mal updaten.
Momentan ist dies sehr ungünstig, habe gerade meinen AVR-Compiler zerschossen. :twisted:

Ich hatte den ganzen Atmega328 Ordner mal vor längerer Zeit als Backup gezippt. Diesen habe ich entpackt, dafür habe ich folgenden Fehler:
Code: Alles auswählen
Project1.pas(103,28) Error: Assembler avr-as not found, switching to external assembling
:evil:

Der ATTiny-Ordner den ich noch habe, der funktioniert noch, obwohl der eigentlich den av-as auch nicht finden dürfte. :roll:

Wo steckt dieser Assembler ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4107
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Mathias » 25. Jul 2018, 16:46 Re: AVR Shl mit Konstante

Ja, bei der Zuweisung in ii wird erweitert. Meiner Meinung nach ist das falsch, da auf ein unsigned int nicht mit signed erweitert werden darf.

Irgendwie blicke ich nicht mehr durch,

Es sind 2 Fehler vorhanden.
1. Das Vorzeichen.
2. 8Bit Überlauf von shl.

Sind jetzt nun beides Bug, oder nur dies mit dem Vorzeichen ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4107
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon kupferstecher » 25. Jul 2018, 17:36 Re: AVR Shl mit Konstante

Timm Thaler hat geschrieben:jaja, ich müsste mal updaten.

"Never ruin a running system" oder so ähnlich :wink:
Bei mir haben neue Versionen oft auch nicht kompiliert, da bin ich mittlerweile vorsichtig, bzw. behalte immer die letzte funktionierende Version auf der Platte.

Mathias hat geschrieben:Es sind 2 Fehler vorhanden.
1. Das Vorzeichen.
2. 8Bit Überlauf von shl.
Sind jetzt nun beides Bug, oder nur dies mit dem Vorzeichen ?

Der erste definitiv. Zum zweiten kann ich auch nichts sagen. Ich finde es unschön (gelinde gesagt), aber ob es ein Bug ist ist die andere Frage. In der Doku (Reference Guide) hab ich nichts genaueres zu impliziten Umwandlungen gefunden, nur dass FPC das tut, aber nicht wie.
kupferstecher
 
Beiträge: 142
Registriert: 17. Nov 2016, 11:52

Beitragvon kupferstecher » 25. Jul 2018, 17:39 Re: AVR Shl mit Konstante

Mathias hat geschrieben:
Code: Alles auswählen
Project1.pas(103,28) Error: Assembler avr-as not found, switching to external assembling

Wo steckt dieser Assembler ?

Ja, das ist immer ärgerlich...
kann es sein dass die Binutils mit dem falschen Prefix auf deiner Platte sind? Sollte doch avr-embedded-as heißen.
kupferstecher
 
Beiträge: 142
Registriert: 17. Nov 2016, 11:52

Beitragvon Mathias » 26. Jul 2018, 16:40 Re: AVR Shl mit Konstante

Anscheinend werden Konstanten von 0-255 auf dem AVR auf 8Bit gesetzt.

Ich habe dies im Wiki vermerkt: http://wiki.freepascal.org/AVR_Programming/de#Shiften

Wen man voll auf Speicheroptimierung ab ist ist es eigentlich gut, das kleine Konstanten nur 8Bit gross sind.
Aber hier sollte der Compiler eigentlich wissen, das 16Bit erwünscht sind, weil i 16Bit ist.
Code: Alles auswählen
var
  i: UInt16;
  b: UInt8;
begin
  b := 8;
  i := 1 shl b;
Würde man es so schreiben,
Code: Alles auswählen
i := 1 shl b;
sieht es anders aus, weil Werte in Klammern immer zuerst gerechnet werden.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4107
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

• Themenende •

Zurück zu Sonstiges



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste

porpoises-institution
accuracy-worried