Warum unterscheidet sich diese Hex-Datei von dem auf dem Gerät programmierten Code?

Ich habe ein Design mit einem STM32F105 . Meine Anwendung in C geschrieben; mit Eclipse und gcc. Ich habe Eclipse (mit OpenOCD und einem ST-LINK/V2- Programmierer) verwendet, um die Firmware auf die Geräte zu schreiben. Jetzt muss ich viele Geräte programmieren und suche nach einer schnelleren Methode.

Die ST-LINK Utility- Software scheint eine gute Wahl zu sein. Sie können es auf eine .hex-Datei verweisen und es in den "automatischen Modus" versetzen. Es erkennt dann, wenn ein Gerät mit dem Programmiergerät verbunden ist, und schreibt darauf. Dann schließen Sie ein anderes Gerät an, das automatisch geschrieben wird. Sehr weich.

Hier ist also das Problem: Es scheint, dass die von Eclipse auf das Gerät geschriebene Firmware tatsächlich anders ist als die von Eclipse generierte Hex-Datei .

Das ist, was ich sehe:

  1. Ich programmiere Device#1 über Eclipse. Ich entferne den Programmierer, setze das Gerät zurück und es funktioniert gut.
  2. Ich finde die von Eclipse generierte .hex-Datei (.../Debug/application.hex).
  3. Ich programmiere Gerät Nr. 2 mit dem ST_LINK-Dienstprogramm und dieser Datei. Ich entferne den Programmierer. Der Code wird auch nach einem Geräte-Reset nicht ausgeführt .
  4. Ich verwende das ST-LINK-Dienstprogramm, um den (funktionierenden) Code direkt von Gerät Nr. 1 zu lesen.
  5. Ich verwende das ST-LINK-Dienstprogramm, um diesen Code auf Gerät Nr. 2 zu programmieren. Jetzt funktioniert Gerät Nr. 2 ordnungsgemäß .

OK, also muss die generierte .hex-Datei falsch sein. Ich kann das ST-LINK-Dienstprogramm verwenden, um die beiden Hex-Dateien (aus den Schritten 2 und 4) zu vergleichen. Es zeigt, dass die Dateien bis zum Ende identisch sind:

(Klicken, um zu zoomen, wenn Sie müssen)

Hexkomp


Abschließend meine Fragen:

Warum ist die generierte .hex-Datei falsch? Vielleicht verwendet Eclipse gcc, um das Hex zu erstellen, und ändert es dann auf dem Weg zum Gerät? Wie kann ich Eclipse dazu bringen, eine Hex-Datei auszugeben, die mit dem Code übereinstimmt, den es auf einem tatsächlichen Gerät programmiert?


Beachten Sie, dass ich die „Debug“-Konfiguration erstelle. Wenn Eclipse eine Verbindung zum Zielgerät herstellt, programmiert es den Code und ermöglicht mir das Debuggen. Wenn ich die Debugger-Hardware entferne, funktioniert das Gerät immer noch. Das heißt, der Code funktioniert gut ohne den angefügten Debugger.

Es sieht so aus, als hätten Sie ein Kommunikationsproblem mit gelöschten/eingefügten Bits/Bytes. Es sieht aus wie ein klassisches Pufferungs-/Flusssteuerungsproblem, bei dem der Eingangspuffer überläuft, nachdem 48 Bytes übertragen wurden. Können Sie den Programmierer mit einer langsameren Geschwindigkeit ausführen? Stellen Sie außerdem sicher, dass Sie überall eine gemeinsame Basis haben.
"Beachten Sie, dass ich die "Debug"-Konfiguration erstelle." - Was passiert, wenn Sie mit der 'Release'-Konfiguration bauen?
@Mick Danke dafür. Ich sehe die verschobenen Werte, von denen Sie sprechen. Die Datei, die funktioniert, ist jedoch diejenige, die ich von einem Gerät gelesen und auf ein anderes geschrieben habe. Die nicht funktionierende Datei stammt direkt aus der IDE und wurde nie übertragen ...
@BruceAbbott: Ich hatte keine 'Release'-Konfiguration konfiguriert, also hat es eine Weile gedauert, bis ich das ausprobiert habe. Erraten Sie, was; es funktionierte! Wenn Sie Ihren Kommentar in eine Antwort umwandeln möchten, würde ich ihn gerne akzeptieren. Anscheinend programmiert Eclipse den 'Debug'-Code (unter Verwendung der .elf-Datei) so, dass er ohne angeschlossenen Debugger ausgeführt werden kann, obwohl die 'Debug'-Hex-Datei nicht alleine ausgeführt werden kann.

Antworten (1)

Vielleicht verwendet Eclipse gcc, um das Hex zu erstellen, und ändert es dann auf dem Weg zum Gerät?

Nein, es ist umgekehrt. Wenn Sie ein Projekt in Eclipse kompilieren,

  1. .oeinzelne Dateien werden zu Objektdateien kompiliert
  2. Objektdateien und Bibliotheken werden zu einer .elfDatei verknüpft
  3. objcopyerzeugt eine .hexDatei aus.elf
  4. und schließlich wird die Größe von gedruckt size, aber dieser letzte Schritt ist rein informativ.

Der Debugger arbeitet aber mit dem .elfaus Schritt 2, weil er Symbole und andere Debugging-Hilfsmittel enthält, die beim Konvertieren in verloren gehen .hex. Daher würde ich mir Schritt 3 und vielleicht auch die Datei sehr genau ansehen .elf.

So sollte Schritt 3 im Fenster der Eclipse-Build-Konsole aussehen

Finished building target: app.elf

Invoking: Cross ARM GNU Create Flash Image
arm-none-eabi-objcopy -O ihex "app.elf"  "app.hex"
Finished building: app.hex

Invoking: Cross ARM GNU Print Size

Überprüfen Sie zunächst, ob Warnungen oder andere verdächtige Anzeichen vorhanden sind. Wird es neu generiert, wenn Sie es entfernen und das Projekt erstellen? Und wenn du das entfernst .elf? Sind die Dateizeitstempel korrekt? Versuchen Sie, es von der Befehlszeile aus zu wiederholen. Damit das funktioniert, müssen Sie den vollständigen Pfad zu arm-none-eabi-objcopyin Ihrer Toolchain angeben oder in Ihre PATH. Stellen Sie sicher, dass der Toolchain-Pfad in Eclipse richtig eingestellt ist und keine anderen Versionen von objcopyherumliegen, insbesondere in Ihrer PATH.

Sie können die .elfmit untersuchen arm-none-eabi-objdump. Listen Sie das "Verzeichnis" mit auf -h, es sieht so aus

app.elf:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .isr_vector   0000013c  08008000  08008000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .text         0000b4cc  08008140  08008140  00008140  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .rodata       0000b1c0  08013610  08013610  00013610  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .ARM          00000008  0801e7d0  0801e7d0  0001e7d0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .init_array   00000008  0801e7d8  0801e7d8  0001e7d8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  5 .fini_array   00000004  0801e7e0  0801e7e0  0001e7e0  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  6 .data         00000a60  20000000  0801e7e4  00020000  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  7 .noinit       00000004  20000a60  0801f244  00020a60  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  8 .bss          0000cbf8  20000a68  0801f248  00020a68  2**3
                  ALLOC

Überprüfen Sie die Felder LMAund Sizefür jeden Abschnitt. Gibt es eine Überschneidung? Dump den Inhalt mit -sund untersuche ihn um die Problemadresse zu finden.