www.mikrocontroller.net

Forum: Compiler & IDEs Ein paar Fragen zu avr/fuse.h


Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So,

nun hab ich mir dieses neue feature mal angeschaut.
http://www.nongnu.org/avr-libc/user-manual/group__...

Habs auch direkt mal ausprobiert. Das kommt schon mal dabei heraus:
Building file: ../Main.c
Invoking: AVR Compiler
avr-gcc -Wall -Os -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields -pedantic -mmcu=atmega168 -DF_CPU=12500000UL -MMD -MP -MF"Main.d" -MT"Main.d" -c -o"Main.o" "../Main.c"
../Main.c:22: warning: large integer implicitly truncated to unsigned type
Finished building: ../Main.c

Wobei wir beim ersten Problem wären. Warum gibt es eine Warnung?
/* Setup fuses for Mega168 in case the
 * ELF file is used for programming */
FUSES =
{
.low = LFUSE_DEFAULT,
.high = HFUSE_DEFAULT,
.extended = EFUSE_DEFAULT
};

Die Zeile der Warnung ist die erste Initialisierungs-Zeile. Beginnend 
mit  ".low". Und er taucht auch nur dort auf.

Ein paar Definitionen:
/* Low Fuse Byte */
#define FUSE_CKSEL0 ~_BV(0)  /* Select Clock Source */
#define FUSE_CKSEL1 ~_BV(1)  /* Select Clock Source */
#define FUSE_CKSEL2 ~_BV(2)  /* Select Clock Source */
#define FUSE_CKSEL3 ~_BV(3)  /* Select Clock Source */
#define FUSE_SUT0   ~_BV(4)  /* Select start-up time */
#define FUSE_SUT1   ~_BV(5)  /* Select start-up time */
#define FUSE_CKOUT  ~_BV(6)  /* Clock output */
#define FUSE_CKDIV8 ~_BV(7) /* Divide clock by 8 */
#define LFUSE_DEFAULT (FUSE_CKSEL0 & FUSE_CKSEL2 & FUSE_CKSEL3 & FUSE_SUT0 & FUSE_CKDIV8)

/* High Fuse Byte */
#define FUSE_BODLEVEL0 ~_BV(0)  /* Brown-out Detector trigger level */
#define FUSE_BODLEVEL1 ~_BV(1)  /* Brown-out Detector trigger level */
#define FUSE_BODLEVEL2 ~_BV(2)  /* Brown-out Detector trigger level */
#define FUSE_EESAVE    ~_BV(3)  /* EEPROM memory is preserved through chip erase */
#define FUSE_WDTON     ~_BV(4)  /* Watchdog Timer Always On */
#define FUSE_SPIEN     ~_BV(5)  /* Enable Serial programming and Data Downloading */
#define FUSE_DWEN      ~_BV(6)  /* debugWIRE Enable */
#define FUSE_RSTDISBL  ~_BV(7)  /* External reset disable */
#define HFUSE_DEFAULT (FUSE_SPIEN)

/* Extended Fuse Byte */
#define FUSE_BOOTRST ~_BV(0)
#define FUSE_BOOTSZ0 ~_BV(1)
#define FUSE_BOOTSZ1 ~_BV(2)
#define EFUSE_DEFAULT (FUSE_BOOTSZ0 & FUSE_BOOTSZ1)

und _BV ist das klassische
#define _BV(bit) (1 << (bit))

Erste Frage: Wodurch kommt nun die Warnung? Das muss ja etwas mit dem 
&-Operator zu tun haben. Gibts da wieder eine der "versteckten" Integer 
Promotions von GCC? ;) Das kannte ich bisher nur von dem ~-Operator, der 
ja hier auch benutzt wird. Allerdings ist mir dann schleierhaft, wieso 
bei den anderen Zeilen keine Truncation-Warnung kommt.

Zweite Frage: Welches Programmiertool soll denn benutzt werden um die 
.ELF Datei zu programmieren? AVRDude, das bei WinAVR on-board ist, hat 
da ja keine Unterstützung (zur Zeit).
Ich könnte mir aber eine Implementierung für AVRDude vorstellen:
Je nachdem welcher Memory beschrieben wird mit dem -U Befehl, holt sich 
AVRDude die passende Section aus dem ELF File. Und die Namen (bzw. 
Adressen?) der Sections könnten am besten in der globalen 
Konfigurationsdatei von AVRDude definiert sein.

So, danke schon mal an die AVR-GCC Profis ;)

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, wohin soll ich mich sonst wenden? ;)

Autor: Hobbyprogger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na rate mal...

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist kein Fehler von dir, sondern von <avr/fuse.h>

~_BV(0) = ~0x01 = -2
~_BV(6) = ~0x40 = -65
~_BV(7) = ~0x80 = -129

Und wenngleich alle 3 Versionen nicht in ein vorzeichenloses Byte 
passen, ist der Compiler tolerant genug, die Varianten bis -127 ohne 
Fehlermeldung zu verdauen. Bei -129 ist allerdings diese Toleranz 
erschöpft.

Es taucht nur bei .low auf, weil nur dort ~_BV(7) verwendet wird.

Workaround:
.low = 0xFF & LFUSE_DEFAULT,

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Korrekterweise hätte der Autor von <avr/fuse.h> statt
  #define FUSE_CKSEL0      ~_BV(0)
Definitionen der Form
  #define FUSE_CKSEL0      (0xFF^_BV(0))
oder notfalls auch
  #define FUSE_CKSEL0      ((unsigned char)~_BV(0))
verwenden sollen.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Kaiser wrote:
> Korrekterweise hätte der Autor von <avr/fuse.h> statt
>   #define FUSE_CKSEL0      ~_BV(0)
> Definitionen der Form
>   #define FUSE_CKSEL0      (0xFF^_BV(0))
> oder notfalls auch
>   #define FUSE_CKSEL0      ((unsigned char)~_BV(0))
> verwenden sollen.

Ah da liegt der Hund begraben. Danke dir für die Ausführungen!

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.