Forum: Compiler & IDEs Doppelbelegung SBIT bei IAR


von Thomas Z. (usbman)


Angehängte Dateien:

Lesenswert?

Ich versuche im Moment meinen UDisk Code auch nach IAR ew8051 zu 
portieren, allerdings möglichst auf der gleichen Code Basis. Es sind 
sowieso schon zu viele ifdefs drin...
Beitrag "Re: uC für 0,20€ CH552 / CH554 von WCH Billig Micro mit USB Funktion, Chip vorstellung"
Ein entsprechendes Header File hab ich geschrieben und ist im Anhang. 
Das passt auch soweit.
Neben der union Deklaration habe ich zusätzlich auch die SBIT Identifier 
per define drin. Der Hintergrund ist einfach dass mein Quellcode so 
nicht verändert werden muss. Das funktioniert solange die SBITs nicht 
doppelt belegt sind.
1
...
2
If (UIF_DETECT) //same bitpos as UIF_BUS_RESET
3
{
4
   ....
5
}
Wenn ich das UIF_DETECT durch UIF_BUS_RESET ersetze läuft der Compiler 
durch. Das will ich aber nicht da die Bedeutung des Bits an der Stelle 
eben nicht USB Reset ist sondern im Hostmode das Connect Bit. Ein Blick 
ins outputfile des Precompiler zeigt dann auch das Problem:
1
if ((USB_INT_FG_bit . (USB_INT_FG_bit . UIF_BUS_RESET  )))
Klar dass der compiler da Fehler meldet. Kennt jemand eine Lösung für 
das Problem.
Thomas

von Peter D. (peda)


Lesenswert?

Nun soll sich wohl jeder erstmal alle benutzten Macros zusammen suchen 
oder wie?

von Yalu X. (yalu) (Moderator)


Lesenswert?

UIF_BUS_RESET ist im Header-File gar nicht definiert. Meinst du
UIF_BUS_RST?

Die Zeile

1
    #define UIF_DETECT   (USB_INT_FG_bit.UIF_BUS_RST)

ersetzt du einfach durch

1
    #define UIF_DETECT   UIF_BUS_RST

Dann funktioniert auch

1
If (UIF_DETECT) ...

Du könntest aber auch den Bitfeldern (die du ja sowieso nicht direkt,
sondern nur über die Makros benutzt) andere Namen geben, bspw. so:

1
typedef struct {
2
    unsigned char b0 : 1;
3
    unsigned char b1 : 1;
4
    unsigned char b2 : 1;
5
    unsigned char b3 : 1;
6
    unsigned char b4 : 1;
7
    unsigned char b5 : 1;
8
    unsigned char b6 : 1;
9
    unsigned char b7 : 1;
10
} bits;
11
12
// ...
13
14
SFR union
15
{
16
  unsigned char USB_INT_FG;            // USB interrupt flag
17
  bits USB_INT_FG_bit;
18
}@ 0xD8;
19
    #define UIF_BUS_RST  (USB_INT_FG_bit.b0)  
20
    #define UIF_DETECT   (USB_INT_FG_bit.b0)
21
    #define UIF_TRANSFER (USB_INT_FG_bit.b1)
22
    #define UIF_SUSPEND  (USB_INT_FG_bit.b2)
23
    #define UIF_HST_SOF  (USB_INT_FG_bit.b3)
24
    #define UIF_FIFO_OV  (USB_INT_FG_bit.b4)
25
    #define U_SIE_FREE   (USB_INT_FG_bit.b5)
26
    #define U_TOG_OK     (USB_INT_FG_bit.b6)
27
    #define U_IS_NAK     (USB_INT_FG_bit.b7)

Die Struktur bits muss nur einmal für alle Register definiert werden,
was die Länge des Header-Files deutlich verkürzt.


Oder so:

1
typedef struct {
2
    unsigned char b0 : 1;
3
    unsigned char b1 : 1;
4
    unsigned char b2 : 1;
5
    unsigned char b3 : 1;
6
    unsigned char b4 : 1;
7
    unsigned char b5 : 1;
8
    unsigned char b6 : 1;
9
    unsigned char b7 : 1;
10
} bits;
11
12
#define SBIT(reg, bit) (((volatile bits *)&reg)->b##bit)
13
14
// ...
15
16
SFR unsigned char USB_INT_FG @ 0xD8;
17
18
#define UIF_BUS_RST  SBIT(USB_INT_FG, 0)  
19
#define UIF_DETECT   SBIT(USB_INT_FG, 0)
20
#define UIF_TRANSFER SBIT(USB_INT_FG, 1)
21
#define UIF_SUSPEND  SBIT(USB_INT_FG, 2)
22
#define UIF_HST_SOF  SBIT(USB_INT_FG, 3)
23
#define UIF_FIFO_OV  SBIT(USB_INT_FG, 4)
24
#define U_SIE_FREE   SBIT(USB_INT_FG, 5)
25
#define U_TOG_OK     SBIT(USB_INT_FG, 6)
26
#define U_IS_NAK     SBIT(USB_INT_FG, 7)


PS: In dieser Zeile ist dir übrigens ein Underscore verrutscht:

1
    #define U_IS_NAK     (USB_INT__FGbit.U_IS_NAK)

Es sollte wohl so heißen:

1
    #define U_IS_NAK     (USB_INT_FG_bit.U_IS_NAK)

: Bearbeitet durch Moderator
von Thomas Z. (usbman)


Lesenswert?

Yalu X. schrieb:
> #define SBIT(reg, bit) (((volatile bits *)&reg)->b##bit)

Vielen Dank Yalu, das Makro gefällt mir noch am besten. Passt auch gut 
zu den anderen Compileren, das werde ich einbauen und testen.
Es sind auch noch ein paar wenige andere Fehler im h File zb SBUF. Ist 
halt mein erster Kontakt mit IAR.

Thomas

: Bearbeitet durch User
von Thomas Z. (usbman)


Lesenswert?

Es wäre so elegant gewesen... geht aber nicht da Pointer im sfr Bereich 
vom Compiler nicht erlaubt sind. Das gilt übrigens genauso für SDCC und 
Keil. Ist ein Architektur Ding. Bleibt also nur die lange Variante.
Dein SBIT Makro arbeitet korrekt wie es soll.

Der Code compiliert nun mit minimalen Änderungen. Jetzt muss ich nur 
noch herausbekommen wie ich die Startadresse auf etwas anderes als 0 
gesetzt bekomme.
Keil und SDCC sind irgendwie übersichtlicher.

Thomas

von Thomas Z. (usbman)


Lesenswert?

Insgesamt muss ich sagen dass man schon etwas Zeit investieren muss bis 
man den Dreh mit den Optionen und Einstellungen raus hat. Ich hab auch 
das Gefühl dass die IDE manchmal seltsame Dinge tut wenn man an den 
Optionen dreht.
Fakt ist dass die IDE abstürzt wenn man ein Clean macht und im Editor 
noch ein File offen hat was durch Clean gelöscht wird.
Zum linken an eine andere Addresse als 0 muss man den startup Code 
ändern. Dort wird mit einem Makro überprüft ob der ResetVector bei 0 
liegt. Dieses Makro muss man deaktivieren, den Rest kann man dann im 
Linker Controlfile einstellen.
Zur Code Größe kann ich keine genauen Angaben machen, da ich das Demo 
Limit erreiche. Vom Gefühl her würde ich aber sagen, dass IAR etwas 
schlechter als Keil ist aber besser als SDCC.

Thomas

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.