Forum: Mikrocontroller und Digitale Elektronik FreeRTOS auf stm32F103 spring falsch bei NVIC lesen


von Philipp (Gast)


Lesenswert?

Hallo,
ich habe auf einem STM32F103RB nun FreeRTOS aufgesetzt und alles 
angepasst und es kommt beim start zu folgender stelle ...
1
portBASE_TYPE xPortStartScheduler( void )
2
{
3
  /* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
4
  *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
5
  *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;
6
7
  /* Start the timer that generates the tick ISR.  Interrupts are disabled
8
  here already. */
9
  prvSetupTimerInterrupt();
10
11
  /* Initialise the critical nesting count ready for the first task. */
12
  uxCriticalNesting = 0;
13
14
  /* Start the first task. */
15
  vPortStartFirstTask();
16
17
  /* Should not get here! */
18
  return 0;
19
}

Bei vPortStartFirstTask liest er von der Adress 0xE000ED08 und spring 
jedoch wieder zu der zuvor bereits aufgerufenen Funktion 
prvSetupTimerInterrupt.
1
void vPortStartFirstTask( void )
2
{
3
    __asm volatile(
4
    
5
    " ldr r0, =0xE000ED08   \n" /* Use the NVIC offset register to locate the stack. */
6
    " ldr r0, [r0]       \n"
7
    " ldr r0, [r0]       \n"
8
    " msr msp, r0      \n" /* Set the msp back to the start of the stack. */
9
    " svc 0          \n" /* System call to start first task. */
10
    );
11
}
12
13
void prvSetupTimerInterrupt( void )
14
{
15
  /* Configure SysTick to interrupt at the requested rate. */
16
  *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
17
  *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
18
}

Diese Schleife läuft dann ewig. Wo liegt der Fehler bzw. was habe ich 
vergessen zu konfigurieren? Irgendwie kommt der Stack durcheinander oder 
...

Philipp

von Philipp (Gast)


Lesenswert?

Ich habe nun den Stack angesehen und er springt dann zu 
DEFAULT_ISR_HANDLER SVCHandler. Im Callstack ist zu sehen, daß er ca. 
15x zur main zurückkehrt und alles nochmals ausführt.

von (prx) A. K. (prx)


Lesenswert?

Letzthin hatten wir hier mal den Fall, da passten die Namen der Handler 
im Startup-Code nicht zu den entsprechenden Namen im Code.

Jedenfalls sollte der SVCHandler vom FreeRTOS zum tragen kommen, sonst 
wird das garantiert nix.

von (prx) A. K. (prx)


Lesenswert?

Die aktuelle Version des ARM CMSIS Standards für Cortex-M3 definiert 
sämtliche Vektoren im Startupcode. Ein Handler muss folglich exakt den 
Namen verwenden, der dafür vorgesehen ist, sonst wird er ignoriert. 
FreeRTOS tut das nicht, folglich wird dessen SVC Handler in Verbindung 
mit einem CMSIS-konformen Startupcode ingnoriert.

ST verwendete in der Lib V2 eine davon abweichende inkompatible Technik. 
Dort werden die Vektoren als C-Tabelle im File stm32f10x_vector.c 
definiert. FreeRTOS bezieht sich darauf und verwendet eine modifizierte 
Version dieser Tabelle, die direkt auf den vPortSVCHandler verweist.

Welche Entwicklungsumgebung verwendest du?

von Philipp (Gast)


Lesenswert?

Also der ASM Code löst ja eigentlich den Call aus mit "svc 0" oder? Was 
ich nicht ganz verstehe ist, was soll dann eigenlich in der SVC 
Interrupt Routine passieren. Es soll doch der erste Task gestartet 
werden.

von (prx) A. K. (prx)


Lesenswert?

Philipp schrieb:

> Also der ASM Code löst ja eigentlich den Call aus mit "svc 0" oder? Was
> ich nicht ganz verstehe ist, was soll dann eigenlich in der SVC
> Interrupt Routine passieren. Es soll doch der erste Task gestartet
> werden.

Yep, aber nur wenn du auch im richtigen SVC Handler landest. Ich gehe 
davon aus, dass du aufgrund des eben beschriebenen Problems statt dessen 
in einem Dummy-Handler landest.

von Philipp (Gast)


Lesenswert?

Ich habe Rowley mal in Verwendung. Ich versuche noch herauszufinden, was 
optimal ist. Bin zwar seit vielen Jahren Keil Fan, aber da der Assistent 
nicht mal ein lauffähiges Demo erzeugen konnte, versuche ich gerade die 
Rowley.

von Philipp (Gast)


Lesenswert?

Also im Startup ist er definiert mit " .word SVCHandler" und in der 
stm32f10x_it.c steht "void SVCHandler(void)", also müßte es doch 
funktionieren.

von (prx) A. K. (prx)


Lesenswert?

Ich verwende ebenfalls Rowley (V2), aber kein FreeRTOS. Von Haus aus 
kriegst du bei Rowley einen eigenen CMSIS-konformen Startup-Code. 
Folglich muss der SVC Handler so heissen wie dort vorgesehen, also 
SVCHandler.

Probier mal, den Handler vom FreeRTOS entsprechend unzubenennen. Müsste 
mit -DvPortSVCHandler=SVCHandler möglich sein (rebuild all).

Für andere Interrupts, beispielsweise vUart... gilt das analog.

Alternativ kannst du dem Rowley beibringen, auf seinen Startup-Code zu 
verzichten und den im FreeRTOS verwenden. Aber frag micht jetzt nicht 
wie das geht, hab's noch nicht probiert. Ich halte mich lieber ans 
CMSIS.

von (prx) A. K. (prx)


Lesenswert?

Na super, hab's grad nochmal kontrolliert. Das Chaos setzt sich fort, 
denn in Rowley heisst das Symbol SVCHandler, im CMSIS statt dessen 
SVC_Handler.

Wobei Rowley immerhin konsequent ist. CMSIS verteilt die Unterstriche 
ziemlich frei von Logik.

von Philipp (Gast)


Lesenswert?

Also das FreeRTOS hat keine Definition für einen SVCHandler oder 
ähnliches - oder ich finde es nicht.

Da mir das nach mehreren Tagen nun auch schon zu blöd wird eine Frage. 
Was verwendest du denn als OS bzw. ist das von Rowley gut?

Philipp

von (prx) A. K. (prx)


Lesenswert?

Philipp schrieb:

> Also das FreeRTOS hat keine Definition für einen SVCHandler oder
> ähnliches - oder ich finde es nicht.

Wirf mal einen Blick in ./Source/portable/GCC/ARM_CM3/port.c und suche 
die "Exception handlers". Das sind diejenigen, die aufgerufen werden 
sollten.

Wenn du dort vorneweg für diese Handler sowas wie
 #define falscherName richtigerName
schreibst, dann sollten auch mit Rowley-Startupcode die richtigen 
Handler aufgerufen werden. Die richtigen Namen findest du in 
Project/System Files/STM32F10x_Startup.s.

Wenn du den Code aus den Demos vom FreeRTOS verwendest, einschliesslich 
dessen Startup(!), denn passt es ohne Modifikation vom port.c, denn dort 
ist ggf. crt0_STM32x.c dafür zuständig. Aber dann musst du 
sicherstellen, dass der Rowley-Startupcode nicht greift.

von Philipp (Gast)


Lesenswert?

Vielen Dank, super für deine Hilfe. Es geht (Hurra). Man braucht oft nur 
jemanden, der einem die Tomaten von den Augen nimmt :-)

Na dann kanns ja los gehn ...


Philipp

von (prx) A. K. (prx)


Lesenswert?

Update: Es gibt bei Rowley mittlerweile zwei alternative CPU Support 
Packages für STM32.

STMicroelectronics STM32F10x CPU Support Package (1.11):
Das ist die oben skizzierte Version, möglicherweise Rowleys Eigenbau, 
jedenfalls die mit den nicht ganz zu CMSIS passenden Vektoren.

STMicroelectronics STM32 CPU Support Package (2.0):
Zu CMSIS passende Version.

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.