Forum: Mikrocontroller und Digitale Elektronik NUCLEO STM32F767ZI: ich bekomme den OTG_FS_IRQHandler() nicht zum Laufen


von Frank B. (fbergemann)


Lesenswert?

Anhand von 
http://evenlund.blogspot.com/2016/10/usb-storage-with-stm32f4-discovery-and_58.html 
und https://www.youtube.com/watch?v=uIOb5sSFyUY habe ich versucht, dass 
USB OTG FS (Host) zum Laufen zu bekommen.
Aber es kommen keine Aufrufe von OTG_FS_IRQHandler(). Die scheinen mir 
aber die treibende Kraft für die USB HOST MSD State Machine zu sein(?)

Die Settings im *.ioc file sehen ok aus. Allerdings ist bei den NVIC 
settings der "USB On The GO FS global interrupts" zwar angewählt, aber 
in grau und nicht in blau angezeigt(?!)

siehe:
https://github.com/FBergemann/STM32-FreeRTOS-Framework/tree/dev-usb-host-msd.

Ich wollte am Anfang erst mal nur die State-Changes weiter propagieren 
nach 
https://github.com/FBergemann/STM32-FreeRTOS-Framework/blob/dev-usb-host-msd/User/UserSrc/Tasks/TaskUSB/TaskUSB.c 
und entsprechend auf der Console loggen. Aber das geht wg. o.g. 
fehlenden Aufruf von OTG_FS_IRQHandler() nicht.

???

von Frank B. (fbergemann)


Lesenswert?

VBUS läuft bei mir nicht.

Bei einem Referenz-Projekt funktioniert es - mit denselben Jumper 
Settings auf dem Board (daran kann es also nicht liegen). Leider 
verwendet das Referenz-Projekt kein *.ioc - so dass ich auf der Ebene 
nicht vergleichen kann.

Ist folgender code in 
https://github.com/FBergemann/STM32-FreeRTOS-Framework/blob/dev-usb-host-msd/USB_HOST/Target/usbh_conf.c 
nicht falsch?
1
 #79   GPIO_InitStruct.Pin = USB_VBUS_Pin;
2
 #80   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
3
 #81   GPIO_InitStruct.Pull = GPIO_NOPULL;
4
 #82   HAL_GPIO_Init(USB_VBUS_GPIO_Port, &GPIO_InitStruct);

Das muss doch GPIO_MODE_OUTPUT sein - oder?

Mir ist auch das Zusammenspiel (Abhängigkeiten) zwischen PA9 und PG6 & 
PG7 nicht klar. Da werde ich aus dem Datenblatt nicht schlau.

Und der im Kapitel "6.10 USB OTG FS or device" 
(https://www.st.com/resource/en/user_manual/dm00244518-stm32-nucleo144-boards-mb1137-stmicroelectronics.pdf) 
referenzierte JP4 taucht in "Figure 4. Top Layout" gar nicht auf(?)

: Bearbeitet durch User
von Frank B. (fbergemann)


Lesenswert?

Ich verstehe das nicht.

Ich habe im "Device Configuration Tool" für USB_HOST unter "Platform 
Settings" gesetzt "Drive_VBUS_FS | GIO:Ouput | PG6".

Dennoch wird der PG6 nicht in usbh_conf.c initialisiert.

Im Referenzprojekt FatFs_USBDisk gibt's dafür in usbh_conf.c
1
  /* Configure POWER_SWITCH IO pin */
2
  GPIO_InitStruct.Pin = GPIO_PIN_6;
3
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
4
  GPIO_InitStruct.Pull = GPIO_NOPULL;
5
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

Warum fehlt das im generierten Code von 
https://github.com/FBergemann/STM32-FreeRTOS-Framework/tree/dev-usb-host-msd 
?

von Frank B. (fbergemann)


Lesenswert?

Da war ein Fehler im generierten Code:
1
/**
2
  * @brief  Drive VBUS.
3
  * @param  state : VBUS state
4
  *          This parameter can be one of the these values:
5
  *           - 1 : VBUS Active
6
  *           - 0 : VBUS Inactive
7
  */
8
void MX_DriverVbusFS(uint8_t state)
9
{
10
  uint8_t data = state;
11
  /* USER CODE BEGIN PREPARE_GPIO_DATA_VBUS_FS */
12
  if(state == 0) /* invertiert - falsch! */
13
  {
14
    /* Drive high Charge pump */
15
    data = GPIO_PIN_SET;
16
  }
17
  else
18
  {
19
    /* Drive low Charge pump */
20
    data = GPIO_PIN_RESET;
21
  }
22
  /* USER CODE END PREPARE_GPIO_DATA_VBUS_FS */
23
  HAL_GPIO_WritePin(GPIOG,GPIO_PIN_6,(GPIO_PinState)data);
24
}

Das ist auch hier schon falsch:
plugins/com.st.stm32cube.common.mx_6.2.1.202103241236/db/templates/usbh_ 
platform_c.ftl

-> https://github.com/STMicroelectronics/STM32CubeF7/issues/46

: Bearbeitet durch User
von m.n. (Gast)


Lesenswert?

Und, bleibt Dir ein mulmiges Gefühl im Bauch?
Glücklicherweise ist Dir die Fehlfunktion ja aufgefallen, da die 
erwartete Reaktion vom Programm nicht stattfand.
Der Cube-Code ist wohl nie richtig getestet worden.

von Frank B. (fbergemann)


Lesenswert?

> Und, bleibt Dir ein mulmiges Gefühl im Bauch?

So ganz wohl ist mir dabei nicht, weil ich nicht weiss, was da noch 
alles für Fehler drin schlummern.

Der User USB port wird jetzt mit Spannung versorgt (ok).

Wenn ich einen USB Stick einstecke, dann lande ich auch in dem von
1
USBH_StatusTypeDef  USBH_Init(USBH_HandleTypeDef *phost,
2
                              void (*pUsrFunc)(USBH_HandleTypeDef *phost,
3
                              uint8_t id), uint8_t id)

erzeugtem thread USBH_Process_OS (ok).
1
#143  phost->thread = osThreadNew(USBH_Process_OS, phost, &USBH_Thread_Atrr);

Und zwar in USBH_Process_OS() sogar bis zu USBH_Process() hier:
1
static void USBH_Process_OS(void *argument)
2
{
3
  osStatus_t status;
4
5
  for (;;)
6
  {
7
    status = osMessageQueueGet(((USBH_HandleTypeDef *)argument)->os_event,
8
                               &((USBH_HandleTypeDef *)argument)->os_msg,
9
                               NULL, osWaitForever);
10
    if (status == osOK)
11
    {
12
      USBH_Process((USBH_HandleTypeDef *)argument);
13
    }
14
  }
15
}

D.h. auch der vorangegange osMessageQueueGet(..) funktioniert.

Aber in USBH_Process(..) steigt er hier aus
1
#479        USBH_LL_ResetPort(phost);

Bzw konkret etwas tiefer dann hier (LOC #1579):
1
HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
2
{
3
       uint32_t USBx_BASE = (uint32_t)USBx;
4
5
       __IO uint32_t hprt0 = 0U;
6
7
       hprt0 = USBx_HPRT0;
8
9
       hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
10
                  USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
11
12
       USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
13
       HAL_Delay(100U);                                 /* See Note #1 */
14
       USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
15
#1579  HAL_Delay(10U);     
16
17
       return HAL_OK;
18
}

Zu einem breakpoint NACH dem HAL_Delay(10U) komme ich nicht mehr.

Stattdessen lande ich dann als nächstes wieder in meinem breakpoint auf 
Zeile #232 hier:
1
/**
2
  * @brief This function handles USB On The Go FS global interrupt.
3
  */
4
void OTG_FS_IRQHandler(void)
5
{
6
      /* USER CODE BEGIN OTG_FS_IRQn 0 */
7
8
      /* USER CODE END OTG_FS_IRQn 0 */
9
#232  HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS);
10
      /* USER CODE BEGIN OTG_FS_IRQn 1 */
11
12
      /* USER CODE END OTG_FS_IRQn 1 */
13
}

Und der backtrace sagt:
1
Thread #1 [main] 1 [core: 0] (Suspended : Breakpoint)  
2
  OTG_FS_IRQHandler() at stm32f7xx_it.c:232 0x8000e00  
3
  <signal handler called>() at 0xfffffffd  
4
  prvPortStartFirstTask() at port.c:261 0x800dbf8  
5
  xPortStartScheduler() at port.c:367 0x800dcd0

Das liegt vermutlich am FreeRTOS scheduling wegen des 
'HAL_Delay(10U)'(?)

Wenn ich nun im Debugger auf "play" drücke lande ich bei einem 
HardFault_Handler():
1
Thread #1 [main] 1 [core: 0] (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)  
2
  HardFault_Handler() at stm32f7xx_it.c:92 0x8000d82  
3
  <signal handler called>() at 0xfffffff1  
4
  HAL_TIM_IRQHandler() at stm32f7xx_hal_tim.c:3,744 0x8005088  
5
  TIM1_UP_TIM10_IRQHandler() at stm32f7xx_it.c:190 0x8000dc6  
6
  <signal handler called>() at 0xfffffff1  
7
  memcpy() at 0x800efae  
8
  prvCopyDataToQueue() at queue.c:2,098 0x800c0fe  
9
  xQueueGenericSendFromISR() at queue.c:1,001 0x800b9a8  
10
  osMessageQueuePut() at cmsis_os2.c:1,667 0x800b008  
11
  USBH_LL_PortEnabled() at usbh_core.c:1,204 0x80099da  
12
  HAL_HCD_PortEnabled_Callback() at usbh_conf.c:181 0x800e520  
13
  HCD_Port_IRQHandler() at stm32f7xx_hal_hcd.c:1,695 0x80037c6  
14
  HAL_HCD_IRQHandler() at stm32f7xx_hal_hcd.c:554 0x8002310  
15
  OTG_FS_IRQHandler() at stm32f7xx_it.c:232 0x8000e06  
16
  <signal handler called>() at 0xfffffffd  
17
  prvPortStartFirstTask() at port.c:261 0x800dbf8  
18
  xPortStartScheduler() at port.c:367 0x800dcd0


Spass geht anders :-)

: Bearbeitet durch User
von Frank B. (fbergemann)


Lesenswert?

Könnte das ein stacksize Problem sein?
Ich habe entsprechend der Anleitung 
http://evenlund.blogspot.com/2016/10/usb-storage-with-stm32f4-discovery-and_58.html 
im "Project Manager" gesetzt:
1
Minimum Heap Size = 0x400
2
Minimum Stack Size = 0x800

Aber ich verwende FreeRTOS. Da muss ich vielleicht dafür auch noch mal 
den Stack Size hochschrauben(?)

Denn hier habe ich nur (usbh_conf.h):
1
#if (USBH_USE_OS == 1)
2
  #include "cmsis_os.h"
3
  #define USBH_PROCESS_PRIO          osPriorityNormal
4
  #define USBH_PROCESS_STACK_SIZE    ((uint16_t)128)
5
#endif /* (USBH_USE_OS == 1) */

von Frank B. (fbergemann)


Lesenswert?

> Und, bleibt Dir ein mulmiges Gefühl im Bauch?

Also dafür, dass ich gerade erst mit dem STM32 angefangen habe, komme 
ich gar nicht mal so schlecht damit zurecht - trotz der ganzen 
Widrigkeiten :-)

Es **war** der stacksize für den USB_HOST.

Das nächste issue: 
https://github.com/STMicroelectronics/STM32CubeF7/issues/47

von Frank B. (fbergemann)


Lesenswert?

Das ist echt hartes Brot :-)

Jetzt hänge ich in einer Schleife hier:
1
Thread #1 [main] 1 [core: 0] (Suspended : Step)  
2
  USBH_MSC_Read() at usbh_msc.c:780 0x8008114  
3
  USBH_read() at usbh_diskio.c:116 0x800735e  
4
  disk_read() at diskio.c:82 0x800a974  
5
  move_window() at ff.c:925 0x800b002  
6
  check_fs() at ff.c:2,971 0x800be18  
7
  find_volume() at ff.c:3,050 0x800bf8a  
8
  f_open() at ff.c:3,328 0x800c4d4  
9
  Ready() at TaskUSB.c:106 0x80117aa  
10
  TaskUSB_Run() at TaskUSB.c:69 0x8011734  
11
  pxPortInitialiseStack() at port.c:208 0x8010370

in der loop auf Zeile #25
1
USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
2
                                 uint8_t lun,
3
                                 uint32_t address,
4
                                 uint8_t *pbuf,
5
                                 uint32_t length)
6
{
7
  uint32_t timeout;
8
  MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
9
10
  if ((phost->device.is_connected == 0U) ||
11
      (phost->gState != HOST_CLASS) ||
12
      (MSC_Handle->unit[lun].state != MSC_IDLE))
13
  {
14
    return  USBH_FAIL;
15
  }
16
17
  MSC_Handle->state = MSC_READ;
18
  MSC_Handle->unit[lun].state = MSC_READ;
19
  MSC_Handle->rw_lun = lun;
20
21
  USBH_MSC_SCSI_Read(phost, lun, address, pbuf, length);
22
23
  timeout = phost->Timer;
24
25
  while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)  
26
  {
27
    if (((phost->Timer - timeout) > (10000U * length)) || (phost->device.is_connected == 0U))
28
    {
29
      MSC_Handle->state = MSC_IDLE;
30
      return USBH_FAIL;
31
    }
32
  }
33
  MSC_Handle->state = MSC_IDLE;
34
35
  return USBH_OK;
36
}

Dasselbe Problem, das jmd. anderes hier hat: 
https://community.st.com/s/question/0D50X00009Xkeg0/stm32l476-usbotg-fatfs-freertos

Ich komme nicht aus dem Zustand USBH_BUSY heraus.

OMG:
https://community.st.com/s/question/0D50X0000CErb5RSQR/usb-host-library-is-not-thread-safe
https://www.freertos.org/FreeRTOS_Support_Forum_Archive/September_2015/freertos_STM32F429Discovery_with_STM32Cube_USB_fatfs_and_FreeRTOS_14fb7b28j.html

: Bearbeitet durch User
von m.n. (Gast)


Lesenswert?

Frank B. schrieb:
> Das ist echt hartes Brot :-)
>
> Jetzt hänge ich in einer Schleife hier:

Das ist der Preis, den man für's Zusammenklicken bezahlen muß.
Aber solange Du nicht am Baum hängst ... ;-)

von Frank B. (fbergemann)


Lesenswert?

Was meinst Du mit "Zusammenklicken"?
Würde es Deiner Meinung nach funktionieren, wenn man manuell FreeRTOS, 
USB Host MSD und FatFS integriert? - auf Basis der vorhandenen 
BiBliotheken?
Oder sind die Libraries einfach (noch) nicht aufeinander abgestimmt. Und 
muss man dann alle Libraries knicken und komplett low-level alles 
selber machen?

Der link hier: 
https://community.st.com/s/question/0D50X0000CErb5RSQR/usb-host-library-is-not-thread-safe

Verweist weiter auf: 
https://community.st.com/s/question/0D50X0000C5Tns8SQC/bug-stm32-hal-driver-lock-mechanism-is-not-interrupt-safe

Und das klingt so, als ob FreeRTOS noch nicht sauber von HAL unterstützt 
wird.

Oder irre ich mich hier?

: Bearbeitet durch User
von Frank B. (fbergemann)


Lesenswert?

Äh, ... wie sind denn die Aussichten für Korrekturen und Pflege der 
Integration mit FreeRTOS in Anbetracht von: 
Beitrag "STMicroelectronics: Azure RTOS im Fokus"

von m.n. (Gast)


Lesenswert?

Frank B. schrieb:
> Was meinst Du mit "Zusammenklicken"?

Das bezog sich primär auf die Verwendung von CubeMX. Man klickt die 
Funktionen wie gewünscht an und erwartet, daß ein funktionierendes 
Programm geliefert wird: kann sein - muß aber nicht, wie man auch in 
diesem Forum an verschiedenen Stellen nachlesen kann.

Frank B. schrieb:
> Oder sind die Libraries einfach (noch) nicht aufeinander abgestimmt.

Wer soll das "Abstimmen" der LIBs denn leisten? Gut ist, wenn man 
passenden Code findet. Wenn es nicht passt, ist es Deine Aufgabe.

> Und
> muss man dann alle Libraries knicken und komplett low-level alles
> selber machen?

Bei komplexeren Funktionen wie USB kann das sehr aufwendig werden, 
entweder eigenen Code zu schreiben oder die Fehler im Fremdcode zu 
finden und beseitigen.
Persönlich brauche ich für meine Anwendungen kein USB, obwohl hier im 
Forum einige Beispiele dafür zu finden wären. Aber was ich brauche, ist 
low-level Programmierung, die die Hardware so verwendet, wie es benötigt 
wird. Daher lese ich das Datenblatt, das Reference-Manual und 
programmiere auf Registerebene. Das dauert anfangs sicherlich länger als 
CubeMX und HAL zu verwenden. Dafür weiß ich aber, wo was und warum 
passiert.

Frank B. schrieb:
> Also dafür, dass ich gerade erst mit dem STM32 angefangen habe, komme
> ich gar nicht mal so schlecht damit zurecht - trotz der ganzen
> Widrigkeiten :-)

Für ein Fazit ist es wohl noch zu früh.

von Frank B. (fbergemann)


Lesenswert?

>> Also dafür, dass ich gerade erst mit dem STM32 angefangen habe, komme ich
>> gar nicht mal so schlecht damit zurecht - trotz der ganzen Widrigkeiten :-)

> Für ein Fazit ist es wohl noch zu früh

Lass mich raten: Du bist hauptberuflich Motivationstrainer ;-)

von Johannes S. (Gast)


Lesenswert?

ich finde es auch eher erstaunlich wieviel mittlerweile auch an 
Middleware integriert ist. Und für komplexere Schnittstellen wie 
Ethernet oder USB reicht es auch nicht ein paar Seiten Datenblatt zu 
lesen, das war bisher sehr teuer oder es war ein deutlich höherer 
Eigenanteil nötig.
Wie man sieht bearbeitet STM die issues auf Github auch, aber es dauert.
Dazu kommt das der F7/H7 mit seinem Cache und verschieden angebundenen 
Speicher auch sehr komplex ist. Ein Stück Software das heute noch lief 
kann morgen schon crashen wenn durch ein gewachsenes Programm ein Buffer 
von einem Speicher in den anderen rutscht.
Auch ein RTOS mal eben optional einbauen ist gefährlich wenn nicht alle 
Libs dafür entwickelt wurden. Beim Cube generierten Code sehe ich nicht 
das da mit Tests gearbeitet wird, wie z.B. bei einem (RT)OS wie Mbed. Da 
ist es schwer neue Features rein zu bekommen weil alles aufwändig durch 
automatisierte Tests laufen muss.
Die Strategie mit MS ist schon interessant, aber einiges ist ja durch 
den CMSIS Layer für das RTOS abgefangen. Das FreeRTOS wird ja nicht 
einfach verschwinden und auch weiterhin integrierbar sein. Nur eventuell 
durch mehr eigene Handarbeit...

von m.n. (Gast)


Lesenswert?

Ich verstehe, Du möchtest meine Kontonummer ;-)

Kleine Geschichte:
Bei einem STM32H723 möchte ich RNG anwerfen, um "saubere" Zufallswerte 
zu erhalten. Beim H750 waren drei Anweisungen notwenig: RCC freigeben, 
Takt auf HSI48 stellen und Enable. Simpel.
Beim H723 versuche ich Gleiches, erhalte ein paar hundert Werte und dann 
bleibt RNG mit Taktfehler hängen.

Testweise CubeMX angeworfen und RNG per HAL starten lassen.
Nach MX_RND_Init() läuft RNG für kurze Zeit und bleibt dann stehen. In 
den Registern steht der gleiche Inhalt wie nach meiner manuellen 
Initialisierung.
Ganz schnell erledigt und wirkungslos ;-)

Auf der HAL-Ebene passiert einiges, was schlecht zu durchschauen ist. 
Dort finde ich keinen richtigen Ansatzpunkt.
Auf Registerebene habe ich zumindest herausgefunden, daß eine Senkung 
der Taktfrequenz RNG weiterlaufen läßt. Fertig bin ich noch nicht. Auf 
der Suche nach "fertigen" Lösungen stoße ich wieder auf dieses 
HAL-Gedöns.

Was ich sagen will: Im Zweifelsfall kommt man nicht umhin, sich im 
Detail mit der Hardware auseinanderzusetzen. Sich hoffnungsvoll auf 
CubeMX+HAL zu verlassen, kann schwer daneben gehen. Wenn noch andere 
Quellen dazukommen, die in einer speziellen Umgebung durchaus stabil 
laufen, kann Debugging schwer bis unmöglich werden.
Glückstreffer Stack vergrößern klappt nicht immer.

@Johannes S.
Hast Du vielleicht eine Lösung für RNG beim H723/H730?
Könnte ja sein, daß Du selbiges Problem schon mal hattest.

von Johannes S. (Gast)


Lesenswert?

m.n. schrieb:
> Könnte ja sein, daß Du selbiges Problem schon mal hattest.

nein, habe den TRNG bisher nicht (bewusst) genutzt.
Vielleicht hilft die init Sequenz aus dem Mbed weiter:
https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/trng_api.c
Auch als Beispiel wie HAL Benutzung für verschiedene Serien sehr 
unterschiedlich ist. Da sollte das funktionieren weil RNG afaik für TLS 
gebraucht wird.

von m.n. (Gast)


Lesenswert?

Vielen Dank!
Copyright ist 2006 - 2016 angegeben, wo es schon den H74x/H75x gab aber 
noch nicht die H72x/H73x Version, die deutlich differenzierter 
einstellbar ist. Aber ich werde mich weiter durchhangeln, auch in den 
Bereichen, in denen RNG benötigt wird.

von Frank B. (fbergemann)


Lesenswert?

> Sich hoffnungsvoll auf CubeMX+HAL zu verlassen, kann schwer daneben gehen.

Warum verwende ich das framework?

Weil es da ist und dafür gedacht ist, dass man Basis-Funktionalität 
einfach einbindet, verwendet, und sich auf seine eigentliche Applikation 
konzentrieren kann. Und sei es, dass man diesen Weg erst mal nur geht um 
eine sub-optimale Vorab-Lösung zu haben, die funktioniert und mit der 
man die eigentliche Funktionalität erarbeiten kann.
Konkret geht es hier um Logging. Ich will Meßwerte aufnehmen, ggf. 
"Aktoren" ansteuern" und das protokollieren. Dann kann nämlich jemand 
anderes sich diese Messwerte schon mal ansehen und damit arbeiten, 
während ich dann prüfe, ob das Logging vom framework ok ist, oder ob ich 
das noch mal überarbeiten will (tunen, verschlanken, vereinfachen).

Warum verwende ich FreeRTOS?

Weil es eine Möglichkeit ist, Funktionsblöcke gedanklich voneinander zu 
isolieren, getrennt anzugehen, ggf. sogar auf mehrere Leute verteilt 
entwickeln zu lassen. Auch hier: vielleicht nur als Prototyp, um z.B. 
erst mal Messwerte zu erhalten und auswerten zu können. Später mag man 
entscheiden, dass der overhead von FreeRTOS nicht tragbar ist und auf 
eine monolithische Lösung wechseln.

Mit dem Ansatz, FreeRTOS zu wählen kann ich nicht prinzipiell falsch 
liegen, denn sonst gäbe es dieses Produkt nicht.

Der Anspruch Meßwerte sowohl auf die Console als auch - mit höherer 
möglicher Bandbreite - in eine Log-Datei per USB aufzeichnen zu wollen, 
ist auch nicht unsinnig.

Eigentlich würde ich erwarten, dass ST da eine Referenz-Implementierung 
(Beispiele) für Logging mit und ohne FreeRTOS anbietet. Denn es ist 
essential für irgendwelche konkreten Anwendungen, die dem Nutzer da 
vorschweben.

ST verwendet ein Haufen Energie auf sein "Service Creation Tool". Warum 
wird das dann nicht mit einem wirklich bauchbarem Beispiel validiert?

: Bearbeitet durch User
von Frank B. (fbergemann)


Lesenswert?

Ich war lange weg vom Thema STM32, will jetzt aber doch noch mal einen 
Anlauf machen. Ich habe damals die STM32CubeIDE v1.6.1 verwendet. Jetzt 
habe ich mir  die aktuelle v1.16.0 installiert. Ich verwende immer noch 
das Board STM32F767ZI.
Damit bin ich jetzt den umgekehrten Weg gegangen und habe das 
funktionierende Demo "FatFs_USBDisk" genommen und die Funktionalität der 
seriellen Console aus einem anderen Projekt da hinein integriert.

Damit bekomme ich auch eine logging Zeile auf der seriellen Console 
angezeigt.
Aber die main() Routine des "FatFs_USBDisk" Demos ruft in einer 
"while(1)" Schleife USBH_Process(...) auf. Und dieser Aufruf kehrt bei 
aktiviertem logging auf der Console nicht mehr zurück.
Ich nehme an, dass da ein Konflikt bei der Verwendung der Resourcen 
vorhanden ist.

In den Sourcen des "FatFs_USBDisk" Demos finde ich in 
Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc.c:
1
#define MCO1_PIN              GPIO_PIN_8
Und das wird in derselben Datei hier verwendet
1
void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
2
{
3
  GPIO_InitTypeDef GPIO_InitStruct;
4
  /* Check the parameters */
5
  assert_param(IS_RCC_MCO(RCC_MCOx));
6
  assert_param(IS_RCC_MCODIV(RCC_MCODiv));
7
  /* RCC_MCO1 */
8
  if (RCC_MCOx == RCC_MCO1)
9
  {
10
    assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
11
12
    /* MCO1 Clock Enable */
13
    MCO1_CLK_ENABLE();
14
15
    /* Configure the MCO1 pin in alternate function mode */
16
    GPIO_InitStruct.Pin = MCO1_PIN;               /* HIER! */
17
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
18
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
19
    GPIO_InitStruct.Pull = GPIO_NOPULL;
20
    GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
21
    HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
22
23
    /* Mask MCO1 and MCO1PRE[2:0] bits then Select MCO1 clock source and prescaler */
24
    MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO1 | RCC_CFGR_MCO1PRE), (RCC_MCOSource | RCC_MCODiv));
25
  }

Der Code, den ich für die serielle Console da mit hinein integriert habe 
verwendet ebenfalls GPIO_PIN_8:
1
#define STLK_RX_Pin GPIO_PIN_8
hier:
1
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
2
{
3
  GPIO_InitTypeDef GPIO_InitStruct = {0};
4
  if(huart->Instance==USART3)
5
  {
6
  /* USER CODE BEGIN USART3_MspInit 0 */
7
8
  /* USER CODE END USART3_MspInit 0 */
9
    /* Peripheral clock enable */
10
    __HAL_RCC_USART3_CLK_ENABLE();
11
12
    __HAL_RCC_GPIOD_CLK_ENABLE();
13
    /**USART3 GPIO Configuration
14
    PD8     ------> USART3_TX
15
    PD9     ------> USART3_RX
16
    */
17
    GPIO_InitStruct.Pin = STLK_RX_Pin|STLK_TX_Pin;      /* HIER! */
18
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
19
    GPIO_InitStruct.Pull = GPIO_NOPULL;
20
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
21
    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
22
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
23
24
    /* USART3 DMA Init */
25
    /* USART3_TX Init */
26
    hdma_usart3_tx.Instance = DMA1_Stream3;
27
    hdma_usart3_tx.Init.Channel = DMA_CHANNEL_4;
28
    hdma_usart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
29
    hdma_usart3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
30
    hdma_usart3_tx.Init.MemInc = DMA_MINC_ENABLE;
31
    hdma_usart3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
32
    hdma_usart3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
33
    hdma_usart3_tx.Init.Mode = DMA_NORMAL;
34
    hdma_usart3_tx.Init.Priority = DMA_PRIORITY_LOW;
35
    hdma_usart3_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
36
    if (HAL_DMA_Init(&hdma_usart3_tx) != HAL_OK)
37
    {
38
      Error_Handler();
39
    }
40
41
    __HAL_LINKDMA(huart,hdmatx,hdma_usart3_tx);
42
43
    /* USART3 interrupt Init */
44
    HAL_NVIC_SetPriority(USART3_IRQn, 5, 0);
45
    HAL_NVIC_EnableIRQ(USART3_IRQn);
46
  /* USER CODE BEGIN USART3_MspInit 1 */
47
48
  /* USER CODE END USART3_MspInit 1 */
49
  }
50
}

Das wird vermutlich der Konflikt sein (oder EINER der Konflikte).
Kann man da für die USB Funktionalität oder für die serielle Console auf 
einen anderen PIN zurückgreifen? Oder gibt das Layout des STM32F767ZI 
das nicht her?
Kann man also nur entweder a) auf die Console loggen oder b) auf einen 
USB Stick loggen? Ich hätte gerne die Kombination von beidem.

Das Beispiel-Projekt ist hier:
https://github.com/FBergemann/STM32-USBDiskAndConsole
Bitte wundert euch nicht über die Implementierung für die serielle 
Console. Die ist aus einem anderen Projekt übernommen, das RTOS 
verwendet: https://github.com/FBergemann/STM32-FreeRTOS-Framework

von Frank B. (fbergemann)


Lesenswert?

ggf. kann man die RCC für das USB Interface wechseln.
In einer Diskussion im STM32 Forum sieht's so aus als ob es eine 
Alternative gibt: 
https://community.st.com/t5/stm32-mcus-products/setting-mco2-output-on-stm32g0/td-p/119270

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.