Forum: Compiler & IDEs avr gcc bitfield / packed struct?


von Kay I. (imperator)


Angehängte Dateien:

Lesenswert?

Hi!

.. eine bitfield - Frage ..

ich hab strukturen in einem union:
1
typedef struct{  //FwVersion
2
  uint16_t mayor : 4; //0..15
3
  uint16_t minor :12; //0..4096
4
}__attribute__((__packed__)) FwVersion;
5
typedef struct{  //FwBuild
6
  uint16_t  year  : 7;  //i.e. 19
7
  uint16_t  month : 4;  //i.e.  7
8
  uint16_t  day   : 5;  //i.e.  1
9
}__attribute__((__packed__)) FwBuild;
10
11
typedef union{
12
  uint16_t   U16_data;
13
  uint8_t    U8_data[2];
14
  FwVersion  FW_Version;
15
  FwBuild    FW_Build;
16
}MyUnionStruct;
Die initialisiere ich testweise so:
1
MyUnionStruct foo={
2
  .FW_Version={
3
    .mayor = 1,
4
    .minor = 131,
5
  },
6
};

Wie erreicht man, dass da 1 bzw. 131 im Watch des Debuggers zu sehen 
sind?

Viele Grüße!

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Kay I. schrieb:
> im Watch des Debuggers

Welcher Debugger und welches Frontend? Das scheint kaputt zu sein. Oder 
Bitfields sind dort einfach nicht implementiert.

Übrigens "major" schreibt man mit j und nicht mit y, nur so am Rande.

: Bearbeitet durch User
von Kay I. (imperator)


Lesenswert?

>"major" schreibt man mit j
huch ... :-)

gcc (WinAVR 20100110) 4.3.3
AVR Studio 4.19
JTAG ICE MKII

von Bernd K. (prof7bit)


Lesenswert?

Kay I. schrieb:
> gcc (WinAVR 20100110) 4.3.3
> AVR Studio 4.19

Das ist ja schon ein bisschen angestaubt ums mal gelinde zu sagen. Ich 
glaub in den Anfängen von avr-gcc war da noch viel Bewegung drin und 
etliches war noch nicht optimal. Das meiste ist dort heute wesentlich 
besser als damals.

Ich hab jetzt auf die Schnelle kein AVR-Zeugs mehr hier ums mal schnell 
mit ner aktuellen Toolchain zu testen aber ich weiß aus eigener 
Anschauung daß der gdb zumindest grundsätzlich eigentlich kein Problem 
mit sowas hat, bzw wundert mich warum ausgerechnet die AVR-Variante da 
Probleme haben sollte.

Versuch doch mal wie sich das mit der aktuellen Toolchain verhält.

: Bearbeitet durch User
von Kay I. (imperator)


Angehängte Dateien:

Lesenswert?

ja ... is nicht mehr ganz frisch, jedoch hab ich für dieses Projekt die 
Toolchain beibehalten, da sie reproduzierbar binaries ausgespuckt hat.

hab jedenfalls mal folgendes tool package probiert:
avr-gcc (GCC) 5.3.0
quelle: http://gnutoolchains.com/avr/

bekomme etwas strengere Warnings (kann nur gut sein), die ich dann auch 
gleich mal mit behebe...
der linker kann nicht mehr richtig mit dem bootloader.o linken ... ok 
deaktievieren wir das mal und bauen ohne.

bauen .. klappt
Starte Simulator ... Studio crasht (siehe Anhang)

von Markus F. (mfro)


Lesenswert?

... and now for something completely different:

der "mayor" ist der Bürgermeister (und nicht der "Haupt"-Irgendwas). 
"major" wär' ein deutlich besser geeigneter Variablenname.

von Michael F. (Gast)


Angehängte Dateien:

Lesenswert?

'nabend...

Habe gerade mal copy'n'paste des Code-Schnipsels in die IAR Embedded 
Workbench für AVR (7.20.1) gemacht und dort zeigt der Simulator die 
gewünschten Werte von 1 und 131.

Hab gerade keine AVR Hardware zur Hand, aber wenn der Simulator die 
Elemente anzeigen kann, dann sollte es in Hardware genau so 
funktionieren.

von Jens M. (schuchkleisser)


Lesenswert?

Bin ja in C nicht so ganz fit, aber:
Im Union werden die Variablen doch "übereinander" in den gleichen 
Speicher gelegt?
Dann kommt
- eine 16-Bit Zahl
- zwei 8-bit-Zahlen
- eine "zwei 16-Bit-Zahlen"
- eine "drei 16-Bit-Zahlen"

d.h. für mich
0xaabbccddeeff heißt
- U16data ist 0xaabb
- U8data[0] ist 0xaa
- U8data[1] ist 0xbb
- FwVersion.major ist 0xaabb
- FwVersion.minor ist 0xccdd
- FwBuild.year ist 0xaabb
- FwBuild.month ist 0xccdd
- FwBuild.day ist 0xeeff

Oder?
Da ist Ärger doch vorprogrammiert.
Evtl. sollte es
U16Data[2]
U8Data[4]
uint16 major
uint16 minor
uint16 year
uint8 month
uint8 day
sein.

von Bernd K. (prof7bit)


Lesenswert?

Jens M. schrieb:
> Dann kommt
> - eine 16-Bit Zahl
> - zwei 8-bit-Zahlen
> - eine "zwei 16-Bit-Zahlen"
> - eine "drei 16-Bit-Zahlen"

Nein, schau nochmal genau auf die Definition, dann wird Dir etwas 
ungewöhnliches auffallen was Du zuvor noch nicht gesehen hast:

Es sind Bitfields.

Bitte googeln.

: Bearbeitet durch User
von Jens M. (schuchkleisser)


Lesenswert?

Soweit ich weiß ist nicht unbedingt festgelegt, das die Bits in 
Bitfields eng gepackt sind.
Es gibt genug Beispiele, bei denen z.B. 3 ints 12 Byte belegen, mit 5 
oder 6 Bits pro int bleiben für die struct trotzdem 8 Byte über, d.h. 2 
ints obwohl einer reichen würde.
Genau so gibt es in Tuts und Foren Hinweise, das mehrere uint16 eben x 
mal 16 bit belegen, trotzdem aber nur weniger Bits gültig sind.

Aber wie gesagt, mit unions bin ich auf Kriegsfuss.
Ich mach solche Sachen in ASM, das klappt immer so wie es soll.

Mein Ansatz wäre, im Simulator oder Debugger den RAM zu beobachten und 
eine Magic number in die Variablen zu schreiben. Dann sollte man das 
doch schnell sehen.

von Kay I. (imperator)


Lesenswert?

Michael F. schrieb:
> Habe gerade mal copy'n'paste des Code-Schnipsels in die IAR Embedded ...

Danke für's Ausprobieren ... dann weiß ich schonmal, dass der Code 
grundsätzlich funktionieren kann und dass prof7bit gleich treffsicher 
war.

Der Nachteil: Jetzt müsste ich meine Toolchain dafür anpacken ...

@ alle :
hab zwar auch schon etwas gegoogelt, aber kann mir dennoch jemand eine 
Quelle empfehlen, wie AVR Studio 4.19 zur Zusammenarbeit mit neuerer AVR 
Toolchain bewegt werden kann?


Jens M. schrieb:
> Im Union werden die Variablen doch "übereinander" in den gleichen
> Speicher gelegt?
Ja es ist ein bitfield struct (und zwar packed), dass sich den 
Speicher per Union teilt.
Ist auch so gewollt, denn dieses Union stellt (abhängig von einem 
anderen Identifyier) einen Datenbereich in einem Protokoll dar und die 
Bedeutung dieser Daten kann dann eben variieren, daher dieses Konstrukt.

von Bernd K. (prof7bit)


Lesenswert?

Kay I. schrieb:
> @ alle :
> hab zwar auch schon etwas gegoogelt, aber kann mir dennoch jemand eine
> Quelle empfehlen, wie AVR Studio 4.19 zur Zusammenarbeit mit neuerer AVR
> Toolchain bewegt werden kann?

Warum willst Du diesen steinigen Weg gehen und mit aller Gewalt bei dem 
alten AVR-Studio verbleiben? Das hat möglicherweiose sogar Mitschuld an 
dem Problem weil es vielleicht den debugger nur unvollständig oder 
fehlerhaft benutzen kann? Vielleicht ist es gar nicht der alte Debugger 
sondern das uralte Frontend?

Ich würde einen sauberen Schnitt machen und alles komplett auf aktuelle 
Versionen hochziehen.

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Kay I. schrieb:
> hab zwar auch schon etwas gegoogelt, aber kann mir dennoch jemand eine
> Quelle empfehlen, wie AVR Studio 4.19 zur Zusammenarbeit mit neuerer AVR
> Toolchain bewegt werden kann?

Na ja, dann ist dein google wohl kaputt.

Aber egal, viellicht hilft das hier weiter:

http://stefanfrings.de/avr_tools/

Aber keine Garantie, daß das Steinzeit-Studio mit aktuellen avr-gccs und 
vor allem avr-gdbs klarkommt.

Oliver

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Kay I. schrieb:
> Ist auch so gewollt, denn dieses Union stellt (abhängig von einem
> anderen Identifyier) einen Datenbereich in einem Protokoll dar

In diesem Fall sind Bitfields und die Konvertierung per union etwas 
problematisch, denn das Verhalten hängt wie du gemerkt hast vom Compiler 
ab. Sobald du das auf eine andere Plattform portierst kann das ggf. 
nicht mehr wie gewünscht funktionieren.

Wenn man es so macht:
1
uint8_t* rawData = receive (...);
2
uint16_t major = rawData[0] & 0xF;
3
uint16_t minor = (rawData[0] >> 4) | (((uint16_t) rawData[1]) << 4);

bzw.
1
uint8_t* rawData = receive (...);
2
uint16_t  year  = rawData[0] & 0x7F;
3
uint16_t  month = (rawData[0] >> 7) | (((uint16_t) (rawData[1] & 7)) << 1);
4
uint16_t  day  = rawData[1] >> 3;

funktioniert es unabhängig vom Compiler immer (sofern es uint8/16_t 
gibt). Senden geht dann umgekehrt:
1
uint16_t major = 12; uint16_t minor = 42;
2
uint8_t rawData [2] = {
3
  major | ((minor&0xF) << 4),
4
  minor >> 4
5
};
bzw.
1
uint16_t  year = 1;
2
uint16_t  month = 2;
3
uint16_t  day = 3;
4
5
uint8_t rawData [2] = {
6
  year | ((month&1)<<7),
7
  ((month>>1)&7) | (day<<3)
8
};
(ungetestet)
Mehr dazu: Serialisierung

: Bearbeitet durch User
von A. B. (Gast)


Angehängte Dateien:

Lesenswert?

Ähnliche Problematik:
********************
https://www.avrfreaks.net/forum/atmel-studio-7-cannot-watch-c-static-class-variables-debugger

Die Variable int test wird im Debugger von AVR4.19 und AS6.2 korrekt 
dargestellt

den Workaround
>With a type cast I can watch static class variables now

kann ich noch nicht nachvollziehen.

von Kay I. (imperator)


Lesenswert?

A. B. schrieb:
> Ähnliche Problematik:
> den Workaround
>>With a type cast I can watch static class variables now
> kann ich noch nicht nachvollziehen.

Ich denke, dieses Problem ist etwas anders gelagert als meines hier.

Bernd K. schrieb:
> Warum willst Du diesen steinigen Weg gehen und mit aller Gewalt bei dem
> alten AVR-Studio verbleiben?

Weil AvrStudio4 so schön klein & schnell ist und (bislang) relativ wenig 
Bugs und Limitierungen in meinem Turnübungen zeigte.
Wenn wir das Forum mal nach Vor- Nachteilen des alten und neuen Studios 
befragen + Farvorites ... dann lieber in einem eigenen Thread ;-)

Niklas G. schrieb:
> Wenn man es so macht:
> (...)
> funktioniert es unabhängig vom Compiler immer

Ja .. mein ganzer bisheriger Code sieht so aus.
Ich finde die structs deutlich besser lesbar, weswegen ich neueren Code 
mit dieser Syntax beginnen wollte.

Oliver S. schrieb:
> Na ja, dann ist dein google wohl kaputt.
> http://stefanfrings.de/avr_tools/

Vielleicht, jedenfalls verweist die stefanfrings.de Seite auf exact die 
gleiche prebuilt toolchain mit gcc v5.3.0, die auch bei mir Probleme 
macht.

Abhilfe gibt es aber ... schon seit 2013:
Beitrag "Avr Studio 4 und die neue AVR Toolchain - So funktionierts!"

man muss dem compiler "-gstrict-dwarf" mitgeben.
Damit ließen sich auch meine Debugger-Crashes abschalten.

Leider bekomme ich immernoch falsche struct-Inhalte im Debuuger 
angezeigt (wie im Anfangs-Post).

von Simon (Gast)


Angehängte Dateien:

Lesenswert?

Habs mal im Atmel Studio 7 getestet.
Als Toolchain wird WinAVR-20100110 benutzt.

von Kay I. (imperator)


Lesenswert?

Simon schrieb:
> Habs mal im Atmel Studio 7 getestet.
> Als Toolchain wird WinAVR-20100110 benutzt.

Danke Simon!

Wenn es mit gleicher Toolchain und anderer IDE funktioniert, liegt der 
Fehler wohl vermutlich im AVRStudio4.19 ...

ok, dann muss ich wohl auf ein schickes Debugging verzichten.

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.