STM32F4 SWO Ausgabe sporadisch falsch

OP #7478720
Lesenswert?

Hallo zusammen,

zur Zeit bin ich dabei, einen Mass-Storage-Device (MSD) Bootloader auf einem STM32F427 zu debuggen. Grundlage ist dieses Github Projekt https://github.com/sfyip/STM32F103_MSD_BOOTLOADER, das ich auf den STM32F4 portiert habe. Um dort ein Problem zu debuggen, möchte ich die ITM Debug-Ausgabe auf dem SWO Pin benutzen.

Für die, die der Hintergrund interessiert, nachfolgend ein paar Details. Falls nicht, gerne direkt bei "Frage an das Forum" weiterlesen:

Eigentliches Problem, das ich debuggen möchte:

Kopiere ich (z.B. über den Windows Explorer) ein .hex file auf das erkannte MSD, so sieht es im Windows File-Dialog erstmal so aus, als würde das File vollständig übertragen. Der Bootloader überprüft anschließend, ob der geflashte Inhalt zur mit enthaltenen CRC32 passt. Hier wird aber bei mir ein Mismatch erkannt und das MSD wird erneut aktiviert.

Feststellungen:

  • Wiederhole ich den Flashvorgang mehrere Male, so wird der FLASH durchschnittlich beim 3. Mal richtig geschrieben (CRC32 Prüfung erfolgreich)
  • Beim STM32F103, also mit dem originalen, nicht portierten Projekt, ist es stabil und zuverlässig beim ersten Mal erfolgreich
  • Beim Vergleich des fehlerhaft geflashten Speichers mit dem original HEX-File fällt auf, dass ein paar einzelne Bytes (oft nur eins oder zwei) einen falschen Wert haben. Es sind jedes Mal andere Bytes
  • Das gleiche Verhalten tritt bei mehreren unterschiedlichen Boards auf

Frage an das Forum:

Zum debuggen möchte ich zunächst prüfen, ob an der HEX-File Parser Funktion noch die richtigen Daten ankommen.

Dazu habe ich die entsprechenden Funktion wie folgt mit einem ITM_SendChar() Aufruf instrumentiert (originale Funktion hier: https://github.com/sfyip/STM32F103_MSD_BOOTLOADER/blob/master/Src/ihex_parser.c):

1
bool ihex_parser(const uint8_t *steambuf, uint32_t size)
2
{
3
    uint32_t i;
4
    uint8_t c, hc;
5
    
6
    for (i = 0; i<size; i++)
7
    {
8
        c = steambuf[i];
9
        ITM_SendChar(c);

Im STM32CubeIde kann ich die empfangenen Zeichen des HEX-Files sehen. Allerdings fehlen sporadisch Zeichen. Hier ein Beispiel von meiner Ausgabe:

1
:20ED6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
2
:20ED8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
3
:20EDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
4
:20EDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
5
:20EDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
6
:20EE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
7
:20EE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
8
:20EE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
9
:20EE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
10
:20FA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
11
:20FA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
12
:20FA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
13
:20FA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
14
:20FAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
15
:20FAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
16
:20FAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26

Diese fehlenden Zeichen kommen aber in Wirklichkeit an, d.h. sie fehlen nur im Serial Viewer.

Ich habe schon folgendes probiert:

  • Verwendung eines original ST-Link v2 (statt meines China Clon)
  • Hinzufügen eines 1ms Delay nach jeder Zeile im HEX-File
  • Verwenden des Serial Viewers im ST-Link Utility anstatt CubeIDE
  • Reduzieren des SWO Taktes in den Debugger Einstellungen
  • Erstellung eines einfachen Testprogramms, das nur in einer For-Loop Zahlen von 0-65535 auf dem SWO Port ausgibt --> Auch Aussetzer
  • Test mit alter ST-Link Firmware V2.J37.S7, aktuell benutzt V2.J42.S7

Leider waren alle Maßnahmen ohne Erfolg.

Habt ihr schonmal die gleiche Erfahrung gemacht oder habt ihr einen Tipp, was ich noch probieren könnte? Mit dem jetzigen Verhalten ist die SWO Debug-Ausgabe für mich leider unbrauchbar. Für weitere Hinweise wäre ich extrem dankbar, mir gehen die Ideen nämlich aus.

Gruß, Philipp

Gast #7478772
Lesenswert?

Die SWO Ausgabe hat nur einen sehr kleinen Puffer. Prüfe, ob dein Code ggf wartet, bis wieder Platz frei ist.

Meine Funktion für diesen Zweck sieht so aus:

1
// Output a trace message
2
void ITM_SendString(char *ptr)
3
{
4
    while (*ptr)
5
    {
6
        ITM_SendChar(*ptr);
7
        ptr++;
8
    }
9
}

Ich benutze darin die von ST bereit gestellte ITM_SendChar(), welche ggf. wartet. Das gilt zumindest für STM32 L0, F1 und F3. Ist das bei deinem Code auch der Fall?

Die SWO Ausgabe findet mit 1/4 der CPU Taktfrequenz statt. Da der F4 schneller getaktet werden kann als der F1, würde ich mal darauf schauen. Vielleicht ist die Qualität des Signals auf der Leitung für die hohe Taktrate nicht gut genug. Oder der ST-Link Adapter ist dafür zu langsam.

Nachtrag: Der Quelltext von ITM_SendChar vom Cortex M4 ist:

1
__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
2
{
3
  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
4
      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
5
  {
6
    while (ITM->PORT[0U].u32 == 0UL)  <---- hier wird gewartet
7
    {
8
      __NOP();
9
    }
10
    ITM->PORT[0U].u8 = (uint8_t)ch;
11
  }
12
  return (ch);
13
}
OP #7478786
Lesenswert?

Danke für die Antwort!

Ich benutze STU32CubeMX v6.8.1 mit der STM32Cube FW_F4 v1.27.1. Die ITM_SendChar Funktion scheint identisch:

1
__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
2
{
3
  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
4
      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
5
  {
6
    while (ITM->PORT[0U].u32 == 0UL)
7
    {
8
      __NOP();
9
    }
10
    ITM->PORT[0U].u8 = (uint8_t)ch;
11
  }
12
  return (ch);
13
}

Da ich nur die reine ITM_SendChar funktion benutze und kein printf, sollte ein Puffer Problem auf Mikrocontroller Seite ausgeschlossen sein. Die Funktion wartet ja.

OP #7478809
Lesenswert?

Bin gerade bei einer Internet-Recherche auf einen entscheidenden Tipp gekommen:

Man kann auf den ST-Link V2 scheinbar auch die Segger J-Link FW flashen ;-) Das habe ich gerade an einem beim mir herumliegenden ST-Evaluation Board mit STM32F4 ausprobiert (Achtung, die Segger Lizenz erlaubt nur die Verwendung auf ST Evaluation Boards).

Vorher (ST-Link v2 Firmware): Oben beschriebenes Problem bestand wie beschrieben

Nachher (Umgeflasht auf J-Link): SWO Ausgabe sieht plausibel aus

Jetzt ist das Ergebnis der Ausgabe also reproduzierbar! Die fehlenden Zeichen kann ich erstmal nicht mehr feststellen.

Für mich sieht es eindeutig aus, als hätte hier die ST-Link Firmware einen Bug! Ich werde dann jetzt erstmal weiter die J-Link Firmware nutzen, zumal diese bei meinem Test zusammen mit CubeIDE auch noch deutlich besser funktioniert.

Dann werde ich jetzt mal versuchen, das eigentliche Problem im Bootloader zu identifizieren! Danke für eure Tipps!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren