Ich habe effektiv drei Sätze von Variablen, die ich an zwei Stellen platzieren kann. Die Sätze 1 und 2 werden nie zusammen verwendet, sodass sie den gleichen Platz einnehmen können. Satz 3 muss eindeutig sein.
Ich weiß, dass ich eine Vereinigung von Strukturen verwenden kann, um das zu bekommen, was ich will, aber das sind eine Menge Daten, die in denselben Bereich gezwungen werden müssen, und es macht die Namen meiner Meinung nach unnötig komplex:
union
{
struct
{
...
} set_1;
struct
{
...
} set_2;
} shared_variables;
Ich kann jeder Variable auch eine bestimmte Adresse zuweisen, aber das lässt dem Linker keine Freiheit, sie zu optimieren:
unsigned char foo_1 @ 0x1A0;
unsigned int bar_1 @ 0x1A1;
unsigned long foo_2 @ 0x1A0; //same address as foo_1
Ich kann jeder Variable einen Abschnittsnamen zuweisen und dem Linker sagen, was er mit den Abschnitten machen soll, aber ich denke immer noch, dass es zu restriktiv ist:
unsigned char __section("set_1") foo_1; //set_1 is 1 byte
unsigned int __section("set_1") bar_1; //set_1 is now 3 bytes
unsigned long __section("set_2") foo_2; //set_2 is 4 bytes
//linker: -L-Ashared_class=<address_range> -L-Pset_1=shared_class -L-Pset_2=shared_class
//actually concatenates them somewhere in the specified range (total 7 bytes), not sure how to overlay them (total 4 bytes)
Gibt es eine Möglichkeit zu sagen: "Es ist mir egal, ob sich dieser Satz von Variablen mit diesem Satz von Variablen überschneidet, aber dieser andere Satz von Variablen muss eindeutig sein", und es einfach dabei belassen?
Ich finde Gewerkschaften vollkommen in Ordnung, um Variablen zu "teilen". Lassen Sie mich dies mit Code erweitern:
typedef struct
{
union
{
struct
{
} set_1;
struct
{
} set_2;
} set_union;
struct
{
} set_3;
} data_set;
... Dies könnte natürlich mit typedefs
on set_1
und deutlich lesbarer gemacht werden set_2
.
Es ist einfach, das Problem „macht die Namen unnötig komplex“ zu lösen.
Erweitern Sie Ihr Beispiel:
union
{
struct
{
int fubar;
...
} set_1;
struct
{
int snafu;
...
} set_2;
} shared_variables;
Eine Lösung ist die Verwendung einiger Makros:
#define a (shared_variables.set_1)
#define b (shared_variables.set_2)
a.fubar = ...;
b.snafu += ...;
Ein Teil des Vorteils dieser Lösung besteht darin, dass der Code immer noch gewöhnliches C ist und nicht von Compiler-spezifischen Funktionen abhängt.
Es besteht eine geringe Möglichkeit, dass der Compiler besseren Code generiert, wenn er die gesamte Zuweisung von Variablen durchführt, anstatt einige der Informationen in den Linker zu schieben. Ich weiß jedoch nicht genug über xc8, um zu sagen, dass dies der Fall ist.
Bearbeiten:
Es scheint in Ordnung zu sein, Variablen auf bestimmte Segmente zu lenken. Dies wirkt sich nur auf die beiden Sätze aus, die sich gegenseitig ausschließen, und nicht auf alle Variablen.
Das Benutzerhandbuch des xc8-Compilers beschreibt auch einen anderen Mechanismus zum Platzieren von Objekten in "5.14.4.8 THE #PRAGMA PSECT DIRECTIVE", der möglicherweise vorzuziehen ist, ABER, ein einziger #pragma
würde alle nachfolgenden Variablen platzieren.
Dies erscheint viel einfacher und weniger fehleranfällig als __section("...")
bei jeder Variablen, verglichen mit einer einzigen #pragma
vor jeder Liste von Variablen.
Es gibt eine spezielle Warnung bezüglich der #pragma
, die wahrscheinlich nicht für sich gegenseitig ausschließende Variablen gilt:
Dieses Pragma sollte nicht für Datensektionen (data oder idata) verwendet werden, die initialisierte Variablen enthalten.
Ich würde jedoch eine Union + zwei Strukturen verwenden, es sei denn, es gibt weitere Einschränkungen.
Edit2:
Wenn die Speicherzuweisung sehr eng ist und es wichtig ist , Variablen in Segmente mit fester Größe zu packen, schreibe ich möglicherweise ein Programm, um den C-Code der Deklaration zu generieren . Ich würde eine Sprache mit guter Textverarbeitung verwenden, um es einfacher zu machen.
psects
Linker-Skripten herumzuspielen. Einen Entwickler zu zwingen, Linker- Skripte zu lesen, um ein Programm zu verstehen, scheint eine schlechte Idee zu sein, und viele sich wiederholende Deklarationen zu verwenden, scheint eine schlechte Praxis zu sein. C. _ "Ich mag den Spezifizierer __section() viel besser". Okay. Na und?
Dzarda
AaronD
David
AaronD
David
AaronD
AaronD