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


von Simon K. (simon) Benutzerseite


Lesenswert?

So,

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

Habs auch direkt mal ausprobiert. Das kommt schon mal dabei heraus:
1
Building file: ../Main.c
2
Invoking: AVR Compiler
3
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"
4
../Main.c:22: warning: large integer implicitly truncated to unsigned type
5
Finished building: ../Main.c

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

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

Ein paar Definitionen:
1
/* Low Fuse Byte */
2
#define FUSE_CKSEL0 ~_BV(0)  /* Select Clock Source */
3
#define FUSE_CKSEL1 ~_BV(1)  /* Select Clock Source */
4
#define FUSE_CKSEL2 ~_BV(2)  /* Select Clock Source */
5
#define FUSE_CKSEL3 ~_BV(3)  /* Select Clock Source */
6
#define FUSE_SUT0   ~_BV(4)  /* Select start-up time */
7
#define FUSE_SUT1   ~_BV(5)  /* Select start-up time */
8
#define FUSE_CKOUT  ~_BV(6)  /* Clock output */
9
#define FUSE_CKDIV8 ~_BV(7) /* Divide clock by 8 */
10
#define LFUSE_DEFAULT (FUSE_CKSEL0 & FUSE_CKSEL2 & FUSE_CKSEL3 & FUSE_SUT0 & FUSE_CKDIV8)
11
12
/* High Fuse Byte */
13
#define FUSE_BODLEVEL0 ~_BV(0)  /* Brown-out Detector trigger level */
14
#define FUSE_BODLEVEL1 ~_BV(1)  /* Brown-out Detector trigger level */
15
#define FUSE_BODLEVEL2 ~_BV(2)  /* Brown-out Detector trigger level */
16
#define FUSE_EESAVE    ~_BV(3)  /* EEPROM memory is preserved through chip erase */
17
#define FUSE_WDTON     ~_BV(4)  /* Watchdog Timer Always On */
18
#define FUSE_SPIEN     ~_BV(5)  /* Enable Serial programming and Data Downloading */
19
#define FUSE_DWEN      ~_BV(6)  /* debugWIRE Enable */
20
#define FUSE_RSTDISBL  ~_BV(7)  /* External reset disable */
21
#define HFUSE_DEFAULT (FUSE_SPIEN)
22
23
/* Extended Fuse Byte */
24
#define FUSE_BOOTRST ~_BV(0)
25
#define FUSE_BOOTSZ0 ~_BV(1)
26
#define FUSE_BOOTSZ1 ~_BV(2)
27
#define EFUSE_DEFAULT (FUSE_BOOTSZ0 & FUSE_BOOTSZ1)

und _BV ist das klassische
1
#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 ;)

von Simon K. (simon) Benutzerseite


Lesenswert?

Hm, wohin soll ich mich sonst wenden? ;)

von Hobbyprogger (Gast)


Lesenswert?

Na rate mal...

von Andreas K. (a-k)


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,

von Andreas K. (a-k)


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.

von Simon K. (simon) Benutzerseite


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!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.