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
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?
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 | }
|
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.