Forum: Mikrocontroller und Digitale Elektronik USB CDC mit CubeMX2 und HAL 2.0 auf STM32C5


von Nemopuk (nemopuk)


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
von Wastl (hartundweichware)


Lesenswert?

Auf deiner Webseite ist zu lesen
1
CDC_Transmit_FS( (uint8_t*) msg, strlen(msg));  <--- compiliert nicht, kann das jemand korrigieren?

Sagt dir der Compiler "ich kompiliere nicht", oder kommt doch etwas
sinnhaftigeres heraus?
von Nemopuk (nemopuk)


Lesenswert?

CDC_Transmit_FS gibt es offenbar nicht mehr in der HAL 2.0
: Bearbeitet durch User
von Zino (zinn)


Lesenswert?

Für STM32C071 habe ich CDC ACM mit USBX ohne RTOS zum Laufen gebracht. 
Keine Ahnung, welche HAL-Version das ist, CDC_Transmit_FS gibt es da 
auch nicht. Würde der Code helfen?
von Nemopuk (nemopuk)


Lesenswert?

Zino schrieb:
> Würde der Code helfen?

Ich glaube schon, würde ich mir gerne anschauen.
von Wastl (hartundweichware)


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 nicht
eine Fehlermeldung per Copy&Paste hier zu liefern?
von Wastl (hartundweichware)


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:
von Zino (zinn)


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.
von Zino (zinn)


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.
von Dergute W. (derguteweka)


Lesenswert?

Moin,

Sieht so aus, als wuerde tinyusb auch auf einem stm32c542nucleo Board 
laufen. Da wuerde ich mit meinem derzeitigen Erfahrungsstand sofort 
alles von ST, Microsoft oder schlimmer stehen und liegen lassen und zu 
tinyusb wechseln.

Gruss
WK
von Zino (zinn)


Lesenswert?

Zweite Hürde: ich gehe davon aus, daß du das ohne ThreadX machen 
möchtest. Dann sollte die while-Schleife in main() so aussehen:
1
while(1) {
2
  /* ... */
3
  ux_device_stack_tasks_run();
4
  ux_system_tasks_run();
5
}
von Zino (zinn)


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.
von Zino (zinn)


Lesenswert?

Ja, jetzt kann man diese Lösung per Internet-Suche oder KI finden, aber 
auch nur deshalb, weil ich (unter anderem Namen) sie hier beschrieb:

https://community.st.com/stm32-mcus-embedded-software-32/usbx-cdc-acm-write-problem-137428
von Zino (zinn)


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
}
von Zino (zinn)


Lesenswert?

So, das müßte jetzt alles sein. Vielleicht noch ein besserer Name für 
sendCDC().
von Zino (zinn)


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
}
von Zino (zinn)


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?
von Wastl (hartundweichware)


Lesenswert?

Zino schrieb:
> So, das müßte jetzt alles sein.

Ich fasse zusammen: endlich ein neuer, einfacher, User-freundlicher
Code für den Neueinsteiger/Anfänger.
von Zino (zinn)


Lesenswert?

Wastl schrieb:
> Ich fasse zusammen: endlich ein neuer, einfacher, User-freundlicher
> Code für den Neueinsteiger/Anfänger.

Genau. So geht's, wenn man bei Microsoft einkauft.
von Nemopuk (nemopuk)


Angehängte Dateien:

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.
: Bearbeitet durch User
von Nemopuk (nemopuk)


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
von Nemopuk (nemopuk)


Angehängte Dateien:

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.
: Bearbeitet durch User
von Nemopuk (nemopuk)


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
von Zino (zinn)


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.
von Nemopuk (nemopuk)


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?
von Nemopuk (nemopuk)


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
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.