Forum: Compiler & IDEs stm32nucleo F401RE (Eclipse + GNU-ARM-Plugin + gcc)


von Bernd K. (prof7bit)


Lesenswert?

Hallo,

ich hab hier ein stm32nucleo F401RE herumliegen und habe mir folgendes 
in den Kopf gesetzt:

* Entwicklung unter Linux
* Eclipse CDT mit GNU-ARM-Plugin
* OpenOCD
* Die grüne LED soll blinken

Eigentlich sollte das doch möglich sein, zumindest wenn man dem glauben 
darf was ich bisher aus zahlreichen zusammengetragenen 
Informationsfetzen herausinterpretiert habe.

Mein Hauptproblem liegt momentan an der Erstellung eines minimalen 
Hello-World-Projektes (LED-blinken) mit Eclipse und dem erfolgreichen 
Kompilieren desselben (vom Flashen auf den Controller wage ich zu diesem 
Zeitpunkt noch gar nicht zu träumen).

Hat das einer der Anwesenden hier schonmal erfolgreich praktiziert und 
wäre bereit mich schrittweise an der Hand zu führen bis die LED blinkt?

Bereits installiert und funktionsfähig (aber eventuell noch nicht 
richtig konfiguriuert) sind:

* Eclipse Luna mit CDT
* arm-none-eabi-gcc 4.9.3 20141119 (release)
* GNU-ARM-Plugins für Eclipse, aktuelle Versionen
* OpenOCD v0.8.0

Wenn ich ein neues leeres Projekt erstelle (oder auch das 
"Blinky"-Template) mit Gnu-Arm-Plugin und als Zielhardware "STM32F4xx" 
und "STM32F401xE" wähle dann erhalte ich ein Projekt welches sich nicht 
kompilieren lässt:
1
Building file: ../system/src/cmsis/vectors_stm32f4xx.c
2
Invoking: Cross ARM C Compiler
3
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=soft -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -Wall -Wextra  -g3 -DDEBUG -DUSE_FULL_ASSERT -DSTM32F401xE -DUSE_HAL_DRIVER -DHSE_VALUE=8000000 -I"../include" -I"../system/include" -I"../system/include/cmsis" -I"../system/include/stm32f4-hal" -std=gnu11 -MMD -MP -MF"system/src/cmsis/vectors_stm32f4xx.d" -MT"system/src/cmsis/vectors_stm32f4xx.o" -c -o "system/src/cmsis/vectors_stm32f4xx.o" "../system/src/cmsis/vectors_stm32f4xx.c"
4
../system/src/cmsis/vectors_stm32f4xx.c:358:7: error: 'SPI4_IRQHandler' undeclared here (not in a function)
5
       SPI4_IRQHandler        // SPI4
6
       ^
7
make: *** [system/src/cmsis/vectors_stm32f4xx.o] Fehler 1

Daraus schließe ich daß der Support für STM32F4xx im GNU-ARM-Plugin 
überhaupt noch nicht implementiert oder komplett ungetestet ist.

Ist nun an dieser Stelle schon Ende der Fahnenstange oder kann ich das 
Plugin (oder zumindest Eclipse) dennoch irgendwie verwenden? Wenn ja: 
Wie?

Bernd

von hp-freund (Gast)


Lesenswert?

Bernd K. schrieb:
> Daraus schließe ich daß der Support für STM32F4xx im GNU-ARM-Plugin
> überhaupt noch nicht implementiert oder komplett ungetestet ist.

Na so hart würde ich es nicht formulieren.

Es scheint Probleme bei den Controller bedingten Einstellungen zu geben.

Die haben wohl einfach übersehen das der F401 auch ein SPI4 hat.

Geh in die:
system/src/cmsis/vectors_stm32f4xx.c

ca. Zeile 200 steht als letztes:
1
FPU_IRQHandler(void);

Wenn Du danach:
1
#if defined(STM32F401xE)
2
void __attribute__ ((weak, alias ("Default_Handler")))
3
SPI4_IRQHandler(void);
4
#endif
einfügst, comiliert es mit Warnungen an anderen Stellen.

Der SPI4_IRQHandler ist wie Du siehst im folgenden bedingten Block und 
damit inaktiv.
Ich hoffe nur das sich der Rest dadurch nicht verschiebt.

von Bernd K. (prof7bit)


Lesenswert?

hp-freund schrieb:
> Bernd K. schrieb:
>> Daraus schließe ich daß der Support für STM32F4xx im GNU-ARM-Plugin
>> überhaupt noch nicht implementiert oder komplett ungetestet ist.

> Wenn Du danach:
>
1
> #if defined(STM32F401xE)
2
> void __attribute__ ((weak, alias ("Default_Handler")))
3
> SPI4_IRQHandler(void);
4
> #endif
5
>
> einfügst, comiliert es mit Warnungen an anderen Stellen.

Das hab ich ausprobiert und es kompiliert in der Tat.

Das nächste Problem war dann die Takt-Konfiguration, die passte 
überhaupt nicht und nach langem Herumstochern hab ich jetzt tief 
vergraben in der STM32Cube_FW_F4_V1.3.0 was passendes gefunden das sieht 
nun nachdem ichs umbenannt und für das gnuarmplugin-Template passend 
gemacht habe folgendermaßen aus (in der vom plugin erzeugten 
_initialize_hardware.c die configure_system_clock() durch dieses 
ersetzt):
1
/**
2
  * @brief  System Clock Configuration
3
  *         The system Clock is configured as follow :
4
  *            System Clock source            = PLL (HSI)
5
  *            SYSCLK(Hz)                     = 84000000
6
  *            HCLK(Hz)                       = 84000000
7
  *            AHB Prescaler                  = 1
8
  *            APB1 Prescaler                 = 2
9
  *            APB2 Prescaler                 = 1
10
  *            HSI Frequency(Hz)              = 16000000
11
  *            PLL_M                          = 16
12
  *            PLL_N                          = 336
13
  *            PLL_P                          = 4
14
  *            PLL_Q                          = 7
15
  *            VDD(V)                         = 3.3
16
  *            Main regulator output voltage  = Scale2 mode
17
  *            Flash Latency(WS)              = 2
18
  * @param  None
19
  * @retval None
20
  */
21
void configure_system_clock()
22
{
23
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
24
  RCC_OscInitTypeDef RCC_OscInitStruct;
25
26
  /* Enable Power Control clock */
27
  __PWR_CLK_ENABLE();
28
29
  /* The voltage scaling allows optimizing the power consumption when the device is
30
     clocked below the maximum system frequency, to update the voltage scaling value
31
     regarding system frequency refer to product datasheet.  */
32
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
33
34
  /* Enable HSI Oscillator and activate PLL with HSI as source */
35
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
36
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
37
  RCC_OscInitStruct.HSICalibrationValue = 0x10;
38
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
39
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
40
  RCC_OscInitStruct.PLL.PLLM = 16;
41
  RCC_OscInitStruct.PLL.PLLN = 336;
42
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
43
  RCC_OscInitStruct.PLL.PLLQ = 7;
44
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
45
46
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
47
     clocks dividers */
48
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
49
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
50
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
51
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
52
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
53
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
54
}

Des Weiteren in der ebenfalls vom Plugin erzeugten BlinkLed.h die wohl 
ursprünglich auf eines der Discovery boards zugeschnitten war die 
korrekten Port und Pinnummern für die grüne LED geändert:
1
#define BLINK_PORT_NUMBER               (0)
2
#define BLINK_PIN_NUMBER                (5)

Und jetzt blinkt es und lässt sich auch debuggen.

Das war ja eine schwere Geburt, da soll noch mal einer sagen ARM wäre 
einfach, und bis jetzt hab ich kaum an der Oberfläche gekratzt. Es hat 
ganz offensichtlich schon seinen Grund warum man gerne simplere und 
leichter zu nutzende Architekturen einsetzt wenn die zu lösende Aufgabe 
kein schwereres Kaliber zwingend erfordert.

von (prx) A. K. (prx)


Lesenswert?

> leichter zu nutzende Architekturen einsetzt wenn die zu lösende Aufgabe
> kein schwereres Kaliber zwingend erfordert.

AVR ist eindeutig einfacher. Aber auch da neigen Anfänger dazu, die 
falsche Taktquelle einzustellen. Um dann vor der verschlossenen Tür zu 
stehen, mit Schlüssel auf der falschen Seite der Tür.

von Bernd K. (prof7bit)


Lesenswert?

A. K. schrieb:
> AVR ist eindeutig einfacher.

Also ich versuch mal zusammenzufassen was mich am meisten verwirrt hat, 
jezt wo der Eindruck noch frisch ist:

* die Libraries, HAL, etc. sollen in den Projektordner kopiert werden, 
einzelne Tutorials erweckten gar den Eindruck man müsse einzelne Dateien 
wo anders hin kopieren, modifizieren, empfand ich als irritierend.

* Der Ablauf nach dem Start bis zur main(), ich bin mir immer noch nicht 
sicher ob ich begriffen habe was der empfohlene Weg ist ein neues 
Projekt anzulegen oder später auf nen anderen Prozessor umzusteigen, was 
die Philosophie hinter diesem Aufbau ist. Bei avr-gcc passiert das 
automatisch, was vor der main() geschieht muss mich nicht kümmern, es 
sei denn ich mach ein nacktes asm-Projekt, warum geht das hier nicht 
ebenso?

* Das gnuarm-Plugin erzeugt Code für ein leeres Projekt, da geht wohl 
einiger Hokuspokus hinter den Kulissen ab, ich habe gemischte Gefühle 
dabei. Ich bin mir noch nicht sicher wie ich das vereinbaren kann mit 
der Struktur der Dateien in der STM32Cube zip-datei, die 
Beispielprojekte sind dort ähnlich aber doch anders organisiert, leider 
ist es schwer den includes der Beispielprojekte aus dem STM32Cube zu 
folgen wenn man mangels der dazugehörigen IDE die includepfade und 
defines nicht kennt. Nicht besonders einfach nachzuvollziehen wenn man 
damit zum ersten Mal konfrontiert wird.

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.