Forum: Mikrocontroller und Digitale Elektronik STM32F4 SWO Ausgabe sporadisch falsch


von Philipp S. (philipp_s918)


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

von Monk (roehrmond)


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
}

: Bearbeitet durch User
von Philipp S. (philipp_s918)


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.

: Bearbeitet durch User
von Philipp S. (philipp_s918)


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!

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.