mikrocontroller.net

Forum: Compiler & IDEs uint64_t und Bits 33-64 lesen bzw. setzen


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe ein Problem mit dem uint64_t Datentyp. Mein Testprogramm sieht 
so aus:

#include <inttypes.>
#include <stdio.h>

#define SET_BIT64(port, bit)   ((port) = (uint64_t)((uint64_t)(port) | (uint64_t)(1ULL << (bit))))
#define IS_BIT_SET64(port, bit) ((uint64_t)((uint64_t)(port) & (uint64_t)(1ULL << (bit))) ? 1 : 0)

void dbg(unsigned long long b) {
  for (int i = 0; i < 64; ++i) {
    if (IS_BIT_SET64(b, i)) {
      printf("X");
    } else {
      printf(".");
    }
  }
  printf("\n");
}

void test() {
  unsigned long long test;

  for (int i = 0; i < 64; ++i) {
    SET_BIT64(test, i);
    dbg(test);
  }
}

int main(int argc, char **argv) {
  test();
  return 0;
}

Es werden nur die Bits 0-31 richtig gesetzt bzw. ausgelesen. Die Bits 
33-64 funktionieren nicht. Woran könnte das liegen?

Vielen Dank schon einmal für eine hilfreiche Antwort.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde jetzt mal mindestens die Hälfte der casts aus den Makros 
rauswerfen und mir die Fehlermeldungen bzw. Warnungen des Compilers 
genau(!) ansehen. Im höchsten Warninglevel.
Einige der Casts sind redundant. Wenn du casten muss, dann fang 'innen' 
in den entsprechenden Ausdrücken an. Dann ergibt sich auch der Rest 
automatisch, weil der Compiler nie von sich aus einen größeren Datentyp 
auf einen kleineren zurückcastet. So ein Cast-Rundumschlag, wie du ihn 
veranstaltet hast, ist meistens kontraproduktiv und verdeckt oft 
essentiell wichtige Warnungen.

Edit:
Mit deinen Datentypen sollte in den Makros eigentlich überhaupt kein 
Cast notwendig sein. Das (korretkerweise benutzte) 1ULL sollte 
eigentlich schon vollständig ausreichen um die Ausdrücke komplett auf 
unsigned long long zu zwingen.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, danke für die Antwort. Wie immer saß das Problem nicht im, sondern 
vor dem Computer. Ich hatte ein Problem mit dem Makefile, das den Code 
nicht neu uebersetzt hat. Nach einem "make clean" und einem neuen Build 
hat es so funktioniert, wie ich es erwartet habe. shame on me

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn möglich, sollte man 64Bit nicht verwenden.

Der AVR-GCC hat keine optimierte 64Bit-Library, sondern macht das 
äußerst umständlich.
Ich würde micht nicht wundern, wenn Dein Mini-Programm allein schon 8kB 
Code erzeugt.

Deutlich schnelleren und kleineren Code erreichst Du mit einem Array aus 
kleineren Typen, z.B.:

uint8_t var64[8];


void set64bit( uint8_t *p, uint8_t num )
{
  *(p+(num>>3)) |= 1 << (num & 0x7);
}

uint8_t test64bit( uint8_t *p, uint8_t num )
{
  return *(p+(num>>3)) & (1 << (num & 0x7));
}


Peter

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Von avr-gcc war zwar nix zu lesen, aber wenn's darum geht, hat Peter 
recht. 64-Bit Typen werden im AVR-Backend von GCC nicht unterstützt, 
sondern werden im maschinenunanhängigen Teil zu 8-Bit Operationen 
ausgetextet.

Des weiteren ist anzumerken, daß in test() die Variable test (sic!) 
nicht initialisiert wird. Obwohl nachfolgend alle Bits gesetzt werden, 
würd ich nicht dafür garantieren, daß ein optimierender GCC hier immer 
den erwarteten Code macht.

Johann

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.