Hi! Ich versuche seit einiger Zeit, das STM32F4 Discovery board unter Linux zum Laufen zu bekommen. Zum Glück gibt es dazu das Tutorial hier: http://www.mikrocontroller.net/articles/STM32F4-Discovery Prinzipiell hat (mit kleineren Schwierigkeiten) alles soweit geklappt. Ich hab inzwischen auch st-link und den compiler erfolgreich kompiliert und kann sie per Konsole aufrufen. Jetzt habe ich das blink-Programm aus dem Tutorial kopiert und wollte es kompilieren, aber dann kommt immer so ein dummer Fehler: undefined reference to `assert_param' und das, obwohl ich oben im header der main.c noch die config-File einbinde #include "stm32f4xx_conf.h", in der assert_param wie im Tutorial beschrieben eingebunden wird. was mache ich denn noch falsch?! Viele Grüße, Michael
Bist Du sicher das kein #ifdef oder eine andere Bedingung das Einbinden verhindert? Alternativ kannst Du im Makefile dem Compiler auch den Parameter übergeben: -D"assert_param(expr)=((void)0)"
naja, eigentlich sollte das alles passen. ich zeig dir mal meine main.c:
1 | #include "stm32f4xx.h" |
2 | #include "stm32f4xx_conf.h" |
3 | GPIO_InitTypeDef GPIO_InitStructure; |
4 | |
5 | void Delay(__IO uint32_t nCount) { |
6 | while(nCount--) { |
7 | }
|
8 | }
|
9 | |
10 | int main(void) { |
11 | /* GPIOD Periph clock enable */
|
12 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); |
13 | |
14 | /* Configure PD12, 13, 14 and PD15 in output pushpull mode */
|
15 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; |
16 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; |
17 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; |
18 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; |
19 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; |
20 | GPIO_Init(GPIOD, &GPIO_InitStructure); |
21 | |
22 | while (1) { |
23 | /* Set PD12 Green */
|
24 | GPIOD->BSRRL = GPIO_Pin_12; |
25 | /* Reset PD13 Orange, PD14 Red, PD15 Blue */
|
26 | GPIOD->BSRRH = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; |
27 | Delay(10000000L); |
28 | |
29 | /* Set PD13 Orange */
|
30 | GPIOD->BSRRL = GPIO_Pin_13; |
31 | /* Reset PD12 Green, PD14 Red, PD15 Blue */
|
32 | GPIOD->BSRRH = GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15; |
33 | Delay(10000000L); |
34 | |
35 | /* Set PD14 Red */
|
36 | GPIOD->BSRRL = GPIO_Pin_14; |
37 | /* Reset PD12 Green, PD13 Orange, PD15 Blue */
|
38 | GPIOD->BSRRH = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15; |
39 | Delay(10000000L); |
40 | |
41 | /* Set PD15 Blue */
|
42 | GPIOD->BSRRL = GPIO_Pin_15; |
43 | /* Reset PD12 Green, PD13 Orange, PD14 Red */
|
44 | GPIOD->BSRRH = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14; |
45 | Delay(10000000L); |
46 | }
|
47 | }
|
und die stm32f4xx_conf.h (eigentlich alles nur aus dem tut kopiert)
1 | #ifndef __STM32F4xx_CONF_H
|
2 | #define __STM32F4xx_CONF_H
|
3 | |
4 | /* Includes ------------------------------------------------------------------*/
|
5 | /* Uncomment the line below to enable peripheral header file inclusion */
|
6 | // #include "stm32f4xx_adc.h"
|
7 | // #include "stm32f4xx_can.h"
|
8 | // #include "stm32f4xx_crc.h"
|
9 | // #include "stm32f4xx_cryp.h"
|
10 | // #include "stm32f4xx_dac.h"
|
11 | // #include "stm32f4xx_dbgmcu.h"
|
12 | // #include "stm32f4xx_dcmi.h"
|
13 | // #include "stm32f4xx_dma.h"
|
14 | // #include "stm32f4xx_exti.h"
|
15 | // #include "stm32f4xx_flash.h"
|
16 | // #include "stm32f4xx_fsmc.h"
|
17 | // #include "stm32f4xx_hash.h"
|
18 | #include "stm32f4xx_gpio.h" |
19 | // #include "stm32f4xx_i2c.h"
|
20 | // #include "stm32f4xx_iwdg.h"
|
21 | // #include "stm32f4xx_pwr.h"
|
22 | #include "stm32f4xx_rcc.h" |
23 | // #include "stm32f4xx_rng.h"
|
24 | // #include "stm32f4xx_rtc.h"
|
25 | // #include "stm32f4xx_sdio.h"
|
26 | // #include "stm32f4xx_spi.h"
|
27 | // #include "stm32f4xx_syscfg.h"
|
28 | // #include "stm32f4xx_tim.h"
|
29 | // #include "stm32f4xx_usart.h"
|
30 | // #include "stm32f4xx_wwdg.h"
|
31 | // #include "misc.h"
|
32 | |
33 | #ifdef USE_FULL_ASSERT
|
34 | #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
|
35 | void assert_failed(uint8_t* file, uint32_t line); |
36 | #else
|
37 | #define assert_param(expr) ((void)0)
|
38 | #endif
|
39 | |
40 | #endif
|
Bedenke auch das die Dateien: stm32f4xx_gpio.c stm32f4xx_rcc.c ebenfalls assert_param benutzen. Da reicht es nicht wenn nur die main.c die Funktion kennt.
das heißt? soll ich in diese dateien auch die stm32f4xx_conf.h einbinden?! das sind doch vorgegebene header dateien, da pfuscht man doch nix drin rum?
Mach es doch so wie ich oben geschreiben habe. Im Makefile dem Compiler -D"assert_param(expr)=((void)0)" übergeben.
aber das kann doch nicht die allgemeine Lösung sein?! der erstellt die makefile ja bei jedem build neu, das heißt dass ich jedesmal manuell die makefile ändern soll und dann manuell builden soll?! abgesehen davon funktioniert das grade auch nicht, vielleicht bin ich einfach zu dumm das an die richtige stelle in der make zu packen. was hat es eigentlich mit dieser stm32f4xx_conf.h auf sich, braucht man die stm32f4xx.h UND die stm32f4xx_conf.h in der main.c? Laut dem tutorial includet der ja nur die stm32f4xx.h sry, ich checks nicht ;)
Hi Michael. Kannst du bitte mal die komplette Fehlerausgabe aus Eclipse einstellen und hier veröffentlichen? Meine Vermutung ist das dein Eclipse nicht alle Include-Verzeichneisse kennt. Sind dei PATH-Variablen richtig gesetzt? Einmal auf einer neuen Konsole "echo $PATH" ausführen und hier veröffentlichen. Welches Linux verwendest du?
Übergib mal folgende Compilerflags, das tun die Examplecodes auch: -DUSE_STM32F4_DISCOVERY -DSTM32F4XX -DUSE_STDPERIPH_DRIVER
Hmm, Reihenfolgenproblem? Wenn das Makro nach der verwendenden Stelle in irgendeinem Header (inline Funktionen) benutzt wird, dann wird es nicht mehr ersetzt und bleibt als echter Funktionsaufruf im Code. Zieh das Makro testweise mal vor alle Includes
1 | #ifdef USE_FULL_ASSERT
|
2 | #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
|
3 | void assert_failed(uint8_t* file, uint32_t line); |
4 | #else
|
5 | #define assert_param(expr) ((void)0)
|
6 | #endif
|
7 | |
8 | |
9 | #include "stm32f4xx.h" |
10 | #include "stm32f4xx_conf.h" |
11 | ...
|
Auch kommt mir die Reihenfolge der Header hier etwas seltsam vor.
Wenn ich mich recht entsinne steckt in der stm32f4xx.h ein #include "stm32f4xx_conf.h" ist allerdings schon wider viel zulange her das ich mich mit dem STM32F4 weiter beschäftigen konnte.
Ich hatte das Problem auch, allerdings beim STM32F2 was aber keinen Unterschied machen sollte. Ich habe mir dann damit beholfen, die "stm32f2xx_conf.h" bzw. "stm32f4xx_conf.h" in den einzelnen Library Files noch mit zu includen. Du benutzt ja z.B. die GPIO&RCC Lib...demzufolge müsste es reichen, in der "stm32f4xx_gpio.c" und in der "stm32f4xx_rcc.c" die "stm32f4xx_conf.h" zu includen, da in dieser die assert Makros definiert sind. Es müssten Dir ansonnsten auch Meldungen ausgespuckt werden, in welchem File es zu den Fehlern kommt. Wie das aber korrekt gemacht wird weiss ich auch nicht...mir hat es damals so gereicht. Aber so ganz im Sinne des Erfinders kann das ja nicht sein, da es sich um die fertige ST Lib handelt. Das man da manuell noch *.h Files includen muss wird sicherlich auch eleganter zu lösen sein, aber so hats bei mir funktioniert
Hi, ich habe die Firmware für das Evalboard für Linux angepasst und alle unnötigen Dateien (diejenigen für IDEs) entfernt. Kompiliert wird mit "make", entwicklet mit dem emcacs ;-) Grüße Arthur Dent
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.