Forum: Compiler & IDEs STM32 USB CDC Objetkt in Kompilat mehrmals vorhanden


von Benny (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe mir per CubeMX ein Projekt zusammengeklickt und habe mich 
aufgrund der geringen Ressourcen des STM32F042K6 mal ein wenig mit der 
Analyse des Maps-Files gechäftigt. Dabei ist mir aufgefallen, dass der 
Compiler (GCC 5.3) ein Objekt im .data-Setment mehrmals anlegt. Ich habe 
die entsprechende Stelle vom Programm AMAP angehängt. Auch mein Projekt 
ist anbei. Falls jemand noch irgendwelche Kompilate benötigt, kann ich 
sie gern hochladen.

Von der Größe her handelt es sich anscheinend um das Objekt hpcd_USB_FS 
in der Datei src/gen/src/usbd_conf.c. Dieses wird in 
src\gen\src\usbd_conf.c definiert/genutzt und in 
rc\gen\src\stm32f0xx_it.c noch einmal genutzt. Warum wird es zweimal 
angelegt? Hat jemand eine Idee?

VG Benny

von Der Andere (Gast)


Lesenswert?

Benny schrieb:
> Dieses wird in
> src\gen\src\usbd_conf.c definiert/genutzt und in
> rc\gen\src\stm32f0xx_it.c noch einmal genutzt

Wie ist es in den beiden C Dateien definiert?

von Benny (Gast)


Lesenswert?

Denkbar einfach, oder? In der stm32f0xx_it.c:

1
extern PCD_HandleTypeDef hpcd_USB_FS;
2
3
void USB_IRQHandler(void)
4
{
5
  /* USER CODE BEGIN USB_IRQn 0 */
6
7
  /* USER CODE END USB_IRQn 0 */
8
  HAL_PCD_IRQHandler(&hpcd_USB_FS);
9
  /* USER CODE BEGIN USB_IRQn 1 */
10
11
  /* USER CODE END USB_IRQn 1 */
12
}

In der usbd_conf.c:

1
PCD_HandleTypeDef hpcd_USB_FS;
2
3
USBD_StatusTypeDef  USBD_LL_Init (USBD_HandleTypeDef *pdev)
4
{ 
5
  /* Init USB_IP */
6
  /* Link The driver to the stack */
7
  hpcd_USB_FS.pData = pdev;
8
  pdev->pData = &hpcd_USB_FS;
9
10
  hpcd_USB_FS.Instance = USB;
11
  hpcd_USB_FS.Init.dev_endpoints = 8;
12
  hpcd_USB_FS.Init.speed = PCD_SPEED_FULL;
13
  hpcd_USB_FS.Init.ep0_mps = DEP0CTL_MPS_64;
14
  hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
15
  hpcd_USB_FS.Init.low_power_enable = DISABLE;
16
  hpcd_USB_FS.Init.lpm_enable = DISABLE;
17
  hpcd_USB_FS.Init.battery_charging_enable = DISABLE;
18
  if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK)
19
  {
20
    Error_Handler();
21
  }
22
23
  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18);
24
  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);
25
  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0xC0);  
26
  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0x110);
27
  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x82 , PCD_SNG_BUF, 0x100);  
28
  return USBD_OK;
29
}

von Benny (Gast)


Lesenswert?

Ich habe den "Fehler" gefunden!

Mir ist aufgefallen, dass das gesuchte Objekt im Map-File keinen Namen, 
sondern eine Nummer besitzt. Ich konnte mich daran erinnern, dass dies 
vor allem bei lokalen statischen Variablen vorgenommen. Also habe ich 
mich in der Datei noch einmal umgesehen. Uns siehe da:
1
/**
2
  * @brief  static single allocation.
3
  * @param  size: size of allocated memory
4
  * @retval None
5
  */
6
void *USBD_static_malloc(uint32_t size)
7
{
8
  static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
9
  return mem;
10
}

Diese Funktion wird aufgerufen um Speicher für den USB-CDC-IF Stack zu 
alloziieren.
1
...
2
  pdev->pClassData = USBD_malloc(sizeof (USBD_CDC_HandleTypeDef));
3
  
4
  if(pdev->pClassData == NULL)
5
...

So und jetzt Hosen runter, wer würde so etwas programmieren? Ich finde 
das mehr als umständlich. Klar kann man so eine Integration in eine 
Speicherverwaltung hinbekommen, aber für einen Mikrocontroller ist das 
ja mehr als überflüssig. Es würde doch ausreichen (wie überall) einfach 
diese Variable zu instanziieren und in die Init zu geben.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Benny schrieb:
> So und jetzt Hosen runter, wer würde so etwas programmieren?

Vermutlich jemand, der dem USB-Stack von einem System, auf dem malloc 
verwendet werden kann, auf eines portiert hat, auf dem er es vermeiden 
möchte, malloc zu verwenden.

Ziemlich übler Hack, und eine interessante Quelle für die lustigsten 
Fehler (man muss nur die Funktion mehrfach aufrufen und annehmen, jeder 
Aufruf gäbe einen unterschiedlichen Pointer zurück ...)

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.