USB CDC mit CubeMX2 und HAL 2.0 auf STM32C5

OP #8067105
Lesenswert?

Hat das schon mal jemand benutzt? Ich hätte Interesse an einem minimalen Code-Beispiel, das wiederholt "Hallo!" sendet.

Ziel ist, das Beispiel auf dieser Webseite zu korrigieren: https://stefanfrings.de/stm32/stm32c5.html#vcphal

: Bearbeitet durch User
#8067248
Lesenswert?

Nemopuk schrieb:

CDC_Transmit_FS gibt es offenbar nicht mehr in der HAL 2.0

Also schaffst es du als langjährig geübter Programmierer auch nicht, in der HAL-Beschreibung nachzulesen welche Funktions- aufrufe alternativ möglich sind?

Ich interpretiere dein Verhalten so dass du die Aufmerksamkeit unerfahrender Leser auf deine eigenen Ergüsse auf deiner Homepage lenken willst.

Denn so dumm wie du hier tust wirst du dich in Wirklichkeit nicht anstellen können. Siehe:

Nemopuk schrieb:

Ziel ist, das Beispiel auf dieser Webseite zu korrigieren:

#8067268
Lesenswert?

Wastl schrieb:

Nemopuk schrieb:

CDC_Transmit_FS gibt es offenbar nicht mehr in der HAL 2.0

Also schaffst es du als langjährig geübter Programmierer auch nicht, in der HAL-Beschreibung nachzulesen welche Funktions- aufrufe alternativ möglich sind?

So einfach ist die Sache nicht. In der HAL-Doku steht nichts zu USBX (das ist der neue von Microsoft eingekaufte USB-Stack). Oder stand nichts, als ich das damals brauchte, aber ich denke nicht, daß sich die Lage verbessert hat. Es gibt eine Doku zu USBX (https://wiki.st.com/stm32mcu/wiki/Introduction_to_USBX), aber das Problem ist dieses Zitat von dort:

1
USBX is the Azure® RTOS USB Host and USB Device embedded stack. It is tightly coupled with ThreadX.

Man kann USBX standalone konfigurieren, also für die Verwendung ohne FreeRTOS, aber man steht dann völlig ohne Dokumentation da. Die interne Doku des Codes ist unter aller Sau. Oder war es, als ich das damals anschaute.

#8067273
Lesenswert?

Ich gehe davon aus, daß die Konfiguration der USBX-Middleware in STM32CubeMX2 oder STM32CubeIDE erfolgreich durchgeführt wurde. Ist nicht so einfach wie bei früheren USB-Stacks. Aber es gibt verschiedene Anleitungen im Netz. Wichtig ist, daß irgendwo "standalone" ausgewählt wird. Wo genau, kann ich nicht sagen, da ich heute ohne STM32CubeMX/STM32CubeIDE bin.

Erste Hürde: Es mag bei STM32CubeMX2 nun anders als bei STM32CubeMX sein, jedenfalls mußte ich dies in main() nach dem MX_USBX_Device_Init()-Aufruf einfügen:

1
HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS, 0x00, PCD_SNG_BUF, 0x0040); /* EP 0 OUT */
2
HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS, 0x80, PCD_SNG_BUF, 0x0080); /* EP 0 IN */
3
HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS, 0x81, PCD_SNG_BUF, 0x00c0); /* EP 1 IN interrupt */
4
HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS, 0x03, PCD_SNG_BUF, 0x0100); /* EP 3 OUT */
5
HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS, 0x82, PCD_SNG_BUF, 0x0140); /* EP 2 IN bulk */
6
ux_dcd_stm32_initialize((ULONG)USB_DRD_FS, (ULONG)&hpcd_USB_DRD_FS);
7
HAL_PCD_Start(&hpcd_USB_DRD_FS);

Verschiedene Varianten davon sind im Netz zu finden, diese hier wurde von mir selbst ermittelt und funktioniert für den STM32C071.

#8067279
Lesenswert?

Dritte Hürde: Die ursprüngliche Frage dieses Threads. Statt CDC_Transmit_FS() ist ux_device_class_cdc_acm_write_run() zu verwenden. Das ist aber auch nicht einfach. Bei mir sieht es ungefähr so aus:

1
static void sendCDC(const void *ptr, size_t size)
2
{
3
  UCHAR *p = (UCHAR *)ptr;
4
  while (size != 0) {
5
      ULONG n = 0;
6
      unsigned r = ux_device_class_cdc_acm_write_run(cdc_acm, p, size, &n);
7
      if (r == UX_STATE_NEXT) {
8
        p += n;
9
        size -= n;
10
        continue;
11
      } else if (r != UX_STATE_WAIT) {
12
        break;
13
      }
14
      ux_system_tasks_run();
15
    }
16
}

Da sollte natürlich noch ein Timeout und Fehlerbehandlung rein.

#8067288
Lesenswert?

Noch eine Hürde: die von sendCDC() verwendete Variable cdc_acm muß auch noch gesetzt werden. In main.c:

1
extern UX_SLAVE_CLASS_CDC_ACM  *cdc_acm;

In USBX/App/ux_device_cdc_acm.c muß USBD_CDC_ACM_Activate() ergänzt werden:

1
/* USER CODE BEGIN PV */
2
UX_SLAVE_CLASS_CDC_ACM *cdc_acm;
3
/* USER CODE END PV */
4

5
...
6

7
VOID USBD_CDC_ACM_Activate(VOID *cdc_acm_instance)
8
{
9
  /* USER CODE BEGIN USBD_CDC_ACM_Activate */
10
  UX_PARAMETER_NOT_USED(cdc_acm_instance);
11
  cdc_acm = (UX_SLAVE_CLASS_CDC_ACM*)cdc_acm_instance;
12
  /* USER CODE END USBD_CDC_ACM_Activate */
13

14
  return;
15
}
#8067292
Lesenswert?

Doch noch eine Ergänzung für USBX/App/ux_device_cdc_acm.c, damit cdc_acm nicht in den Wald zeigt:

1
VOID USBD_CDC_ACM_Deactivate(VOID *cdc_acm_instance)
2
{
3
  /* USER CODE BEGIN USBD_CDC_ACM_Deactivate */
4
  UX_PARAMETER_NOT_USED(cdc_acm_instance);
5
  cdc_acm = NULL;
6
  /* USER CODE END USBD_CDC_ACM_Deactivate */
7

8
  return;
9
}
#8067295
Lesenswert?

Der Vollständigkeit halber noch das Lesen von Daten. Bei mir in main.c zwischen ux_device_stack_tasks_run() und ux_system_tasks_run():

1
if (cdc_acm != NULL) {
2
  ULONG n = 0;
3
  unsigned r = ux_device_class_cdc_acm_read_run(cdc_acm, buf, sizeof(buf), &n);
4
  if (r == UX_STATE_NEXT) {
5
    doSomethingWithInput(buf, n);
6
  }
7
}

Natürlich mit geeigneter Variable buf ungefähr so:

1
static UCHAR buf[64];

Noch Fragen?

OP #8067336
Lesenswert?

Zino, du hast meine Frage direkt verstanden und ich bin für deine Antwort auch sehr dankbar.

Allerdings habe ich die Datei USBX/App/ux_device_cdc_acm.c nicht gefunden und stecke an dieser Stelle fest. Ich habe daher das ganze Projekt gepackt und angehängt. Es wäre sehr nett von dir, wenn du es vervollständigen würdest. Mit einem Diff werde ich dann deine Änderungen identifizieren.

Das Thema übersteigt meinen Horizont doch erheblich. Trotzdem würde dieses Kapitel auf meiner Homepage gerne in Ordnung bringen, der Vollständigkeit halber. Ich vermute, dass viele Leute das dann später nutzen können - war bisher immer so.

Darf ich auf meiner Homepage eine Danksagung hinterlassen? Wie soll ich dich dort nennen? Eventuell auch einen Link zu deiner Homepage oder so, wenn du magst.

Angehängte Dateien:
: Bearbeitet durch User
OP #8067342
Lesenswert?

Wastl schrieb:

Also schaffst es du als langjährig geübter Programmierer nicht eine Fehlermeldung per Copy&Paste hier zu liefern?

Ich aus gutem Grund Leute angesprochen, die sich mit dem Thema auskennen. So wie Zino.

Wastl schrieb:

Also schaffst es du als langjährig geübter Programmierer auch nicht, in der HAL-Beschreibung nachzulesen welche Funktions- aufrufe alternativ möglich sind?

So dumm wie du hier tust wirst du dich in Wirklichkeit nicht anstellen können.

Du überschätzt mich wohl. Ich bin eher knapp über dem Arduino Niveau unterwegs. Blöderweise unterstützt der Arduino Core den STM32C5 aber nicht. Ich schreibe meine Erkenntnisse öffentlich einsehbar auf, damit auch andere daraus Nutzen ziehen können. Bin sicher nicht der Einzige, der sich für den Chip interessiert.

Wastl, vielleicht magst du uns zeigen, wie man das richtig macht und wo es dokumentiert ist.

: Bearbeitet durch User
OP #8067415
Lesenswert?

Ich bin einen Schritt weiter. Ich nutze nun Tasks in der Hauptschleife und ich habe die richtigen Stellen gefunden, wo ich die Variable cdc_acm einfügen muss. Es compiliert. Zino, denkst du das könnte so klappen?

Den Punkt aus Beitrag "Re: USB CDC mit CubeMX2 und HAL 2.0 auf STM32C5" habe ich noch nicht umgesetzt. Jetzt warte ich auf die Hardware, damit ich testen kann.

Angehängte Dateien:
: Bearbeitet durch User
OP #8067556
Lesenswert?

Dergute W. schrieb:

Da wuerde ich mit meinem derzeitigen Erfahrungsstand sofort alles von ST, Microsoft oder schlimmer stehen und liegen lassen und zu tinyusb wechseln.

TinyUSB hat eine überzeugende Doku und viel verständlichere Beispiele. Gefällt mir! Der Tipp kommt direkt auf meine Homepage.

Ich möchte das Beispiel mit Cube HAL dennoch lauffähig machen.

: Bearbeitet durch User
#8067609
Lesenswert?

Nemopuk schrieb:

Ich bin einen Schritt weiter. Ich nutze nun Tasks in der Hauptschleife und ich habe die richtigen Stellen gefunden, wo ich die Variable cdc_acm einfügen muss. Es compiliert. Zino, denkst du das könnte so klappen?

Ja, aber die Änderungen werden wahrscheinlich bei der nächsten Code-Generierung überschrieben, weil die Kommentare entfernt wurden (von ST oder Microsoft), die das verhindern. Es scheint keine bessere Lösung zu geben, habe aber nur ein paar Sekunden reingeschaut.

OP #8068000
Lesenswert?

Zino schrieb:

Ja, aber die Änderungen werden wahrscheinlich bei der nächsten Code-Generierung überschrieben, weil die Kommentare entfernt wurden (von ST oder Microsoft), die das verhindern.

Nein, da wurden keine Kommentare entfernt. Mich hat das auch irritiert. Offenbar funktioniert das bei Cube MX2 nun anders.

Es scheint keine bessere Lösung zu geben, habe aber nur ein paar Sekunden reingeschaut.

Das nacht nichts. Es gut darum, ein bisschen Starthilfe zu haben. Doku von ST ist diesbezüglich ja quasi nicht vorhanden. Stattdessen verweisen sie auf "examples" die ebenfalls unvollständig sind. Was zum Teufel nützt mir ein uC, der als CDC Device erkannt wird, aber weder sendet noch empfängt?

OP #8072028
Lesenswert?

Am "Hello World" mit USBX bin ich gescheitert, sowohl mit als auch ohne FreeRTOS. Ich blicke schon durch das neue HAL MX2 Framework nicht durch. Wenn da dann noch USBX und FreeRTOS oben drauf kommen, klinkt sich mein Hirn ganz aus. Das ist zu viel auf einmal, und mir für ein paar kleine Hobbyprojekte ehrlich gesagt auch zu kompliziert. Ich habe aus gutem Grund nicht studiert und das soll auch so bleiben.

Mit tinyUSB bin ich hingegen ganz ohne weitere Hilfe auf Anhieb zurecht gekommen. Deswegen bleibe ich jetzt dabei.

Dennoch möchte ich nochmal für eure Hilfe danken.

: Bearbeitet durch User

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