Frage

Wir sind derzeit eine Anwendung für einen MSP430 MCU zu entwickeln und in einige seltsamen Probleme ausgeführt werden. Wir entdeckten, dass erklärt Arrays einen Bereich nach Erklärung der „normalen“ Variablen withing, manchmal verursacht, was nicht definiertes Verhalten zu sein scheint. Wie folgt aus:

foo(int a, int *b);

int main(void)
{
    int x = 2;
    int arr[5];

    foo(x, arr);

    return 0;
}

foo wird ein Zeiger als zweite Variable übergeben, dass manchmal Punkt nicht dem arr array. Wir prüfen dies durch Einzelschritt durch das Programm, und sehen, dass der Wert des ARR Array-as-a-Zeigervariable in dem Hauptbereich ist nicht die gleiche wie der Wert der Zeigervariable b in dem foo Umfang. Und nein, das ist nicht wirklich reproduzierbar ist, haben wir nur dieses Verhalten beobachten hin und wieder.

Diese beobachtbar ist, noch bevor eine einzige Zeile der foo Funktion ausgeführt wird, wird der übergebene Zeiger-Parameter (b) einfach nicht auf die Adresse zeigt, dass arr ist.

Ändern Sie das Beispiel scheint das Problem zu lösen, wie folgt aus:

foo(int a, int *b);

int main(void)
{
    int arr[5];
    int x = 2;

    foo(x, arr);

    return 0;
}

hat jemand eine Eingabe oder Hinweise, warum wir dieses Verhalten erleben? Oder ähnliche Erfahrungen gemacht? Die MSP430 Programmieranleitung gibt an, dass Code an die ANSI C89-Spezifikation entsprechen sollte. und so habe ich mich gefragt, ob es sagt, dass Arrays hat vor nicht-Array-Variablen deklariert werden?

Jede Eingabe auf diese würde geschätzt.


Aktualisieren

@ Adam Shiemke und tomlogic:

Ich frage mich, was C89 gibt an über verschiedene Arten von Werten innerhalb Erklärungen zu initialisieren. Dürfen Sie so etwas wie schreiben:

int bar(void)
{
    int x = 2;
    int y;

    foo(x);
}

Und wenn ja, was ist:

int bar(int z)
{
    int x = z;
    int y;

    foo(x);
}

Ist das erlaubt? Ich nehme an, das folgende zu illegal C89 sein:

int bar(void)
{
    int x = baz();
    int y;

    foo(x);
}

Vielen Dank im Voraus.


Update 2 Problem gelöst. Grundsätzlich wir, wo das Deaktivieren von Interrupts, bevor die Funktion (foo) und nach Erklärungen von Variablen aufrufen. Wir wo in der Lage, das Problem in einem einfachen Beispiel zu reproduzieren, und die Lösung scheinen eine _Nop () Anweisung nach der Deaktivierung Interrupt-Aufruf zu sein hinzuzufügen.

Wenn jemand interessiert Ich kann das komplette Beispiel reproduzieren das Problem veröffentlichen, und das Update?

Vielen Dank für die Eingabe zu diesem Thema.

War es hilfreich?

Lösung

Es soll möglich sein, um zu bestimmen, ob es ein Compiler Fehler ist auf dem Assembler-Code basierte, das produziert wird. Ist die Anordnung anders, wenn Sie die Reihenfolge der Variablendeklarationen ändern? Wenn Ihr Debugger Sie können, versuchen Sie Einzelschritt durch die Versammlung.

Wenn Sie einen Compiler Fehler zu tun finden, auch, überprüfen Sie die Optimierung. Ich habe Fehler wie diese durch den Optimierer eingeführt gesehen.

Andere Tipps

Das sieht aus wie ein Compiler-Fehler.

Wenn Sie Ihr erstes Beispiel (die problematische) verwenden und Ihren Funktionsaufruf als foo(x, &arr[0]); schreiben, haben Sie die gleichen Ergebnisse sehen? Was ist, wenn Sie das Array wie int arr[5] = {0}; initialisieren? Keines von beiden sollte etwas ändern, aber wenn sie es tun würde es bei einem Compiler Fehler hinweisen.

In Ihrer aktualisierten Frage:

  

Im Grunde wir, wo Interrupts vor dem Aufruf der Funktion (foo) und nach Erklärungen von Variablen zu deaktivieren. Wir wo in der Lage, das Problem in einem einfachen Beispiel zu reproduzieren, und die Lösung zu sein scheinen eine _NOP() Anweisung nach dem Deaktivieren der Interrupt-Aufruf hinzuzufügen.

Es klingt, als ob die Interrupt-Eigen / Funktion / Makro zu deaktivieren (oder aber Unterbrechungen gesperrt sind) könnte eine Anweisung verursachen sein ‚übersprungen‘ oder so etwas. Ich würde untersuchen, ob es codiert / ordnungsgemäß funktioniert.

aussehen Beide Beispiele konformen C89 mir zu sein. Es sollte kein beobachtbaren Unterschied im Verhalten sein, dass foo Annahme Zugriff nicht über die Grenzen des Arrays.

Für C89, müssen die Variablen in einer Liste am Anfang des Bereichs vor jeder Zuordnung deklariert werden. C99 können Sie Zuordnung eine Erklärung mischen. Also:

{ 
    int x; 
    int arr[5];

    x=5;
...

ist legal c89 Stil. Ich bin überrascht, Ihr Compiler nicht irgendeine Art von Fehlern auf, dass werfen hat, wenn es nicht c99 nicht unterstützt.

, um den echten Code Unter der Annahme, ist viel komplexer, heres ein paar Dinge, die ich würde überprüfen, bedenken sie Vermutungen sind:

Könnten Sie den Stapel gelegentlich werden überfüllt? Wenn dies der Fall könnte dies einige Artefakt „Stack Verteidigung“ sein durch den Compiler / uC? Ist der falsche Wert von foo fallen innerhalb einer vorhersagbaren Speicherbereich? wenn so hat dieser Bereich eine Bedeutung (innerhalb des Stapels, usw.)?

Ist die mcu430 unterschiedliche Bereiche für RAM- und ROM-Adressierung? Das heißt, ist der Adressraum für ram 16bit während des Programmadressraumes 24bit? PIC haben eine solche Architektur zum Beispiel. Wenn dies der Fall wäre es möglich, dass arr als rom (24bit) zugeordnet bekommen und die Funktion erwartet einen Zeiger auf RAM (16 Bit) würde der Code arbeiten, wenn die arr in den ersten 16-Bit des Adressraum zugewiesen wurde, aber Ziegel, wenn sein über diesem Bereich .

Vielleicht haben Sie an irgendeiner Stelle in Ihrem Programm in illegalen Speicherschreib, die Ihren Stack korrumpiert.

Haben Sie einen Blick auf die Demontage?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top