Ich habe angefangen, Firmware für mein Produkt zu schreiben und bin hier ein Anfänger. Ich habe viele Artikel gelesen, in denen es darum ging, keine globalen Variablen oder Funktionen zu verwenden. Gibt es ein Limit für die Verwendung globaler Variablen in einem 8-Bit-System oder ist es ein vollständiges Nein-Nein? Wie soll ich globale Variablen in meinem System verwenden oder vollständig vermeiden?
Ich möchte wertvolle Ratschläge von euch zu diesem Thema entgegennehmen, um meine Firmware kompakter zu machen.
static
Dateibereich ist nicht dasselbe wie "global", siehe meine Antwort unten.Antworten:
Sie können globale Variablen erfolgreich verwenden, sofern Sie die @ Phil-Richtlinien beachten. Es gibt jedoch einige gute Möglichkeiten, um Probleme zu vermeiden, ohne den kompilierten Code weniger kompakt zu machen.
Verwenden Sie lokale statische Variablen für den dauerhaften Status, auf den Sie nur innerhalb einer Funktion zugreifen möchten.
Verwenden Sie eine Struktur, um zusammengehörige Variablen zusammenzuhalten und klarer zu machen, wo sie verwendet werden sollen und wo nicht.
Verwenden Sie globale statische Variablen, um die Variablen nur in der aktuellen C-Datei sichtbar zu machen. Dies verhindert den versehentlichen Zugriff von Code in anderen Dateien aufgrund von Namenskonflikten.
Wenn Sie eine globale Variable in einer Interruptroutine ändern und an einer anderen Stelle lesen, gehen Sie wie folgt vor:
volatile
.ODER
quelle
volatile
Variablen besteht darin, Code, der in einem Ausführungskontext ausgeführt wird, zuzulassen, dass Code in einem anderen Ausführungskontext weiß, dass etwas passiert ist. Auf einem 8-Bit-System kann ein Puffer, der eine Zweierpotenz von maximal 128 Bytes enthalten soll, mit einem flüchtigen Byte verwaltet werden, das die Gesamtlebensdauer der in den Puffer eingegebenen Bytes angibt (Mod. 256) und eine andere gibt die Lebensdauer der herausgenommenen Bytes an, vorausgesetzt, nur ein Ausführungskontext legt Daten im Puffer ab und nur einer entnimmt Daten daraus.Die Gründe, warum Sie in einem 8-Bit-System keine globalen Variablen verwenden möchten, sind die gleichen, die Sie auch in keinem anderen System verwenden möchten: Sie erschweren die Überlegung, wie sich das Programm verhält.
Nur schlechte Programmierer haben Probleme mit Regeln wie "Keine globalen Variablen verwenden". Gute Programmierer verstehen den Grund hinter den Regeln und behandeln sie dann eher als Richtlinien.
Ist Ihr Programm leicht zu verstehen? Ist sein Verhalten vorhersehbar? Ist es einfach, Teile davon zu modifizieren, ohne andere Teile zu beschädigen? Wenn die Antwort auf jede dieser Fragen Ja lautet , sind Sie auf dem Weg zu einem guten Programm.
quelle
Sie sollten die Verwendung globaler Variablen (kurz "Globals") nicht ganz vermeiden. Aber Sie sollten sie vernünftig verwenden. Die praktischen Probleme bei übermäßigem Gebrauch von Globalen:
Es wird empfohlen
g_
, dem Namen globaler Variablen ein Präfix hinzuzufügen . Zum Beispielg_iFlags
. Wenn Sie die Variable mit dem Präfix im Code sehen, erkennen Sie sofort, dass es sich um eine globale Variable handelt.quelle
static
Flagge für die sichtbar werdenmain()
? Bedeuten Sie, dass die gleiche Funktion, die die hat,static
siemain()
später zurückgeben kann?Der Vorteil globaler Datenstrukturen in eingebetteter Arbeit besteht darin, dass sie statisch sind. Wenn jede Variable, die Sie benötigen, global ist, wird Ihnen nie versehentlich der Speicher ausgehen, wenn Funktionen eingegeben werden und Speicherplatz für sie auf dem Stapel erstellt wird. Aber wozu dann Funktionen? Warum nicht eine große Funktion, die die gesamte Logik und Prozesse abwickelt - wie ein BASIC-Programm ohne GOSUB. Wenn Sie diese Idee weit genug bringen, haben Sie ein typisches Assembler-Programm aus den 1970er Jahren. Effizient und unmöglich zu warten und Fehler zu beheben.
Verwenden Sie also Globals mit Bedacht, wie Statusvariablen (zum Beispiel, wenn jede Funktion wissen muss, ob sich das System im Interpretations- oder Ausführungsstatus befindet) und andere Datenstrukturen, die von vielen Funktionen gesehen werden müssen und wie @PhilFrost sagt, das Verhalten von deine funktionen vorhersehbar? Gibt es eine Möglichkeit, den Stapel mit einer Eingabezeichenfolge zu füllen, die niemals endet? Dies sind Fragen für das Algorithmus-Design.
Beachten Sie, dass Statik innerhalb und außerhalb einer Funktion eine unterschiedliche Bedeutung hat. /programming/5868947/differenz zwischen-static-variable-inside-and-out-of-function
/programming/5033627/static-variable-inside-of-function-in-c
quelle
Globale Variablen sollten nur für einen wirklich globalen Zustand verwendet werden. Die Verwendung einer globalen Variablen zur Darstellung von beispielsweise dem Breitengrad der Nordgrenze der Karte funktioniert nur, wenn es immer nur eine "Nordgrenze der Karte" geben kann. Wenn der Code in Zukunft möglicherweise mit mehreren Karten mit unterschiedlichen Nordgrenzen arbeiten muss, muss der Code, der eine globale Variable für die Nordgrenze verwendet, wahrscheinlich überarbeitet werden.
In typischen Computeranwendungen gibt es oft keinen besonderen Grund anzunehmen, dass es nie mehr als eine von etwas geben wird. In eingebetteten Systemen sind solche Annahmen jedoch oft weitaus vernünftiger. Während es möglich ist, dass ein typisches Computerprogramm aufgerufen wird, um mehrere gleichzeitige Benutzer zu unterstützen, ist die Benutzeroberfläche eines typischen eingebetteten Systems für die Bedienung durch einen einzelnen Benutzer ausgelegt, der mit seinen Tasten und seinem Display interagiert. Als solches wird es zu jedem Zeitpunkt einen einzelnen Benutzeroberflächenstatus haben. Das System so zu gestalten, dass mehrere Benutzer mit mehreren Tastaturen und Anzeigen interagieren können, würde viel mehr Komplexität und Implementierungszeit erfordern als das Entwerfen für einen einzelnen Benutzer. Wenn das System nie zur Unterstützung mehrerer Benutzer aufgerufen wird, Jeder zusätzliche Aufwand, der zur Erleichterung dieser Nutzung aufgewendet wird, wird vergeudet. Sofern nicht mit einer Mehrbenutzerunterstützung zu rechnen ist, ist es wahrscheinlich sinnvoller, den für eine Einzelbenutzeroberfläche verwendeten Code zu verwerfen, wenn eine Mehrbenutzerunterstützung erforderlich ist, als zusätzliche Zeit für das Hinzufügen von Mehrbenutzerunterstützung aufzuwenden. Benutzerunterstützung, die wahrscheinlich nie benötigt wird.
Ein verwandter Faktor bei eingebetteten Systemen ist, dass in vielen Fällen (insbesondere bei Benutzeroberflächen) die Verwendung mehrerer Threads die einzig praktikable Möglichkeit ist, mehr als eine Funktion zu unterstützen. In Ermangelung eines anderen Multi-Threading-Bedarfs ist es wahrscheinlich besser, ein einfaches Single-Threading-Design zu verwenden, als die Systemkomplexität durch Multi-Threading zu erhöhen, das wahrscheinlich nie wirklich notwendig ist. Wenn das Hinzufügen von mehr als einem Element ohnehin ein umfangreiches Redesign des Systems erfordern würde, spielt es keine Rolle, ob auch die Verwendung einiger globaler Variablen überarbeitet werden muss.
quelle
Viele Leute sind über dieses Thema verwirrt. Die Definition einer globalen Variablen lautet:
Dies ist nicht dasselbe wie Dateibereichsvariablen , die durch das Schlüsselwort deklariert werden
static
. Dies sind keine globalen Variablen, sondern lokale private Variablen.Sollten Sie globale Variablen verwenden? Es gibt einige Fälle, in denen es in Ordnung ist:
In allen anderen Fällen dürfen Sie niemals globale Variablen verwenden. Es gibt nie einen Grund dafür. Verwenden Sie stattdessen Dateibereichsvariablen , was völlig in Ordnung ist.
Sie sollten sich bemühen, unabhängige, autonome Codemodule zu schreiben, die für eine bestimmte Aufgabe entwickelt wurden. Innerhalb dieser Module sollten sich interne Dateibereichsvariablen als private Datenelemente befinden. Diese Entwurfsmethode ist als Objektorientierung bekannt und allgemein als gutes Design anerkannt.
quelle
.data
Segment ist.