www.mikrocontroller.net

Forum: GCC Ein paar Fragen zu avr/fuse.h

Autor: Simon K. (simon) Benutzerseite
Datum: 03.07.2008 16:40

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: 04.07.2008 19:55

Hm, wohin soll ich mich sonst wenden? ;)
Autor: Hobbyprogger (Gast)
Datum: 04.07.2008 20:06

Na rate mal...
Autor: Andreas Kaiser (a-k)
Datum: 04.07.2008 20:29

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 Kaiser (a-k)
Datum: 04.07.2008 20:50

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: 05.07.2008 14:35

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 Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
  • Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net