Hallo,
ich habe ein Problem bei der Umsetzung eines Codes vom IAR zum GCC.
Im IAR sieht es so aus:
1
__regvar__no_initvolatileunion{
2
ucharR_flag0;
3
struct{
4
uchar
5
bFlag_Packet_Transimit:1,
6
bFlag_Calibration_Status:1;
7
};
8
}@0x0f;
Im Prinzip wird doch dort das Register R15 gelocked, bis ein
entsprechender Funktionsaufruf stattfindet der dieses Register dann
nutzt. Was ich aber nicht verstehe ist dass eigentlich keine Instanz
definiert ist.
Kann mir einer erklären was diese Funktion genau macht und wie ich sie
auf dem GGC umsetzen kann?
Vielen Dank!
__regvar deutet zwar auf eine 'Variable in einem Register' hin,
allerdings ist mir nicht ganz klar, warum ausgerechnet r15 da so einen
Sonderfall haben soll. Die Bezeichnungen der Member deuten für mich eher
darauf hin, dass es sich hier um ein Statusregister einer externen
Komponente handelt, die irgendwie in den Adressraum eingeblendet wird.
Wenn das so nicht zu klären ist, wird man wohl nicht umhin kommen, den
verwendenden Code zu studieren, wobei u.U auch die ganze Hardware
drumherum, auf die hier IMHO Bezug genommen wird, berücksichtigt werden
muss.
Zeig doch mal etwas mehr Code drumherum. Vielleicht bringt das etwas
mehr Licht in die Sache.
Hi, danke für die schnellen Antworten!
Im restlichen Code wird nur die Variable "bFlag_Packet_Transimit" aus
dem union verwendet. Und die wird eigentlich nur als Schleifenbedingung
genutzt.
Siehe hier:
1
#if debug_Master
2
if(bFlag_Packet_Transimit)
3
{
4
output_ledRed^=true;
5
A71_Fifo_Write(&send[0]);
6
PORTB|=(1<<3);
7
RF_Setup_transmiter();
8
while(GPIO1_WTR){};
9
10
PORTB&=~(1<<3);
11
12
bFlag_Packet_Transimit=false;
13
send_count=10;
14
}
Dazu der Timer Interrupt der die Variable wieder setzt:
1
#pragma vector = TIMER1_COMPA_vect
2
__interruptvoidTimer1_CompareA_Entry(void)
3
{
4
if(send_count)
5
{
6
if((--send_count)==0x00)
7
bFlag_Packet_Transimit=true;
8
}
9
}
Also nur ein festes Zeitintervall fürs Daten senden über einen
Interrupt.
OK.
Sieht für mich so aus, als ob ich mit der Annahme eines memory mapped
Devices falsch liege.
Sieht so aus, als ob da wer auf Biegen und Brechen den Compiler dazu
brignen will, ein paar Flags in Register zu halten.
Ich denke die vernünftigste Entsprechung ist
1
volatileuint8_tbFlag_Packet_Transimit;
2
volatileuint8_tbFlag_Calibration_Status;
und den Rest überlässt man besser dem Compiler.
Wird bFlag_Calibration_Status ähnlich verwendet?
Ja,
bflag_Calibration_Status wird ähnlich verwendet.
Hab gerade noch mal in den "System Header" Dateien des IAR Projekts
gestöbert. Die hatte ich für den GCC nicht übernommen, weil ich da
lieber die altbekannten nutzen wollte.
>ein paar Flags in Register zu halten.
Ein paar ist gut....;-)
Da sieht es überall so aus:
Das sieht mir nach unions aus, die einen einfacheren bitweisen Zugriff
auf die PORT und PIN Register ermöglichen sollen.
Vom PeDa gibt es da eine schöne Technik, die zumindest in der Verwendung
auf in etwa dasselbe hinauslaufen sollte. Leider hab ich da jetzt keinen
Link dazu.
Felix schrieb:
> Im restlichen Code wird nur die Variable "bFlag_Packet_Transimit" aus> dem union verwendet.
Das heißt, die erzeugen damit sowas wie eine "Bit-Variable".
Möglicherweise gestatten sie (als Spracherweiterung) den Zugriff
auf den Feldnamen einer nichtinstanziierten union, solange der
Name halt im entsprechenden Namensraum eindeutig ist. GCC bietet
eine leicht ähnliche Erweiterung an, bei der man innerhalb einer
union auf struct fields zugreifen kann, ohne dass die struct
selbst einen Namen bekommen hat:
Danke für die ganzen Antworten!!!
Die beschriebene Routine von Jörg funktioniert, hab aber die ganzen
Union Deklarationen weg gelassen und "normale" Variablen benutzt. Das
Modul läuft weiterhin ohne Probleme, jetzt auch mit dem GCC ;-).
War für mich einfach übersichtlicher weil ich es so gewohnt bin und nen
Vorteil durch diese Union Geschichte gab es jetzt hier nicht.
Die vereinfachte Bitweise Zugriffstechnik von PeDa würd mich aber
interessieren. Vielleicht hat ja noch jemand den Link?
Gruß