[STM32F217 + freeRTOS] xPortStartFirstTask runs into HardFault_Handler

Gast #2378087
Lesenswert?
• ▲
▼
Hallo an zusammen,

ich habe hier ein Board mit einem STM32F217. GPIOs, 
Serielle-Schnittstelle habe ich als erstes in Betrieb genommen und das 
funktioniert soweit. Als nächstes wollte ich freeRTOS zum laufen 
bringen.

Version: FreeRTOS.org V6.0.1
 + STM32F2xx standard peripherals library 1.0.0

Mein Problem ist, dass mein Scheduler beim Starten des ersten Threads in 
den HardFault_Handler läuft. Im Debugger konnte ich bis zum SVC_Handler 
folgen. Hat jemand eine Idee und kann mir einen Tipp geben?

Gruß,
Christian

main.c:
1
 
2
SystemInit();
3

4
/* Set the Vector Table base address at 0x08000000 */
5
NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 );
6

7
/* Configure HCLK clock as SysTick clock source. */
8
SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK );
9
NVIC_SetPriority( SysTick_IRQn, 15 );
10
NVIC_SetPriority( RTC_Alarm_IRQn, 12 );
11

12
xTaskCreate( mainTask, ( signed portCHAR * ) "Main", configMINIMAL_STACK_SIZE + 200, NULL, 1, &mainTaskHandle );
13

14
/* Start the scheduler. */
15
vTaskStartScheduler();

port.c
1
 
2
portBASE_TYPE xPortStartScheduler( void )
3
{
4
  /* Make PendSV, CallSV and SysTick the same priroity as the  
5
           kernel. */
6
  *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
7
  *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;
8

9
  /* Start the timer that generates the tick ISR.  
10
           Interrupts are disabled
11
      here already. */
12
  prvSetupTimerInterrupt();
13

14
  /* Initialise the critical nesting count ready for the first task.
15
           */
16
  uxCriticalNesting = 0;
17

18
  /* Start the first task. */
19
  vPortStartFirstTask();
20

21
  /* Should not get here! */
22
  return 0;
23
}
1
 
2
void vPortStartFirstTask( void )
3
{
4
  asm volatile(
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
          " cpsie i               \n"
9
          " msr msp, r0      \n" /* Set the msp back to the start of the stack. */
10
          " svc 0          \n" /* System call to start first task. */
11
        );
12
}
13
#endif
1
void vPortSVCHandler( void )
2
{
3
  __asm volatile (
4
          "  ldr  r3, pxCurrentTCBConst2    \n" /* Restore the context. */
5
          "  ldr r1, [r3]          \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
6
          "  ldr r0, [r1]          \n" /* The first item in pxCurrentTCB is the task top of stack. */
7
          "  ldmia r0!, {r4-r11}        \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
8
          "  msr psp, r0            \n" /* Restore the task stack pointer. */
9
          "  mov r0, #0             \n"
10
          "  msr  basepri, r0          \n"
11
          "  orr r14, #0xd          \n"
12
          "  bx r14              \n"
13
          "                  \n"
14
          "  .align 2            \n"
15
          "pxCurrentTCBConst2: .word pxCurrentTCB        \n"
16
        );
17
}
Persönliche Seite #2378114
Lesenswert?
• ▲
▼
Hallo,

ich weiß nicht, ob freeRTOS das nicht sowieso macht, aber bei meinem 
Scheduler hatte ich den Hardfault immer dann, wenn ich mit 
EXC_RETURN=0xFFFFFFFD zurückspringen wollte, der Rücksprung aber wieder 
in einen IRQ-Handler gehen sollte. Daher muss der PendSV die geringste 
Priorität haben und immer in den Threadmode springen wollen.

Das bedeutet insbesondere auch, dass der SVC höher priorisiert sein 
muss.

Gruß
Lasse

PS: Ansonsten mal wirklich single steppen und vor branches die 
Sprungadressen checken, ob der Stack da passt.
Gast #2378176
Lesenswert?
• ▲
▼
>/* Configure HCLK clock as SysTick clock source. */
>SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK );
>NVIC_SetPriority( SysTick_IRQn, 15 );

Als erstes lässt du mal die Finger vom Systick.
Der wird vom FreeRTOS belegt. Und HardFault
bedeutet dein Controller springt in den Wald.
Das liegt irgendwo in den Tiefen deines unbekannten
Programmes verborgen. Kann man also nix zu sagen.
Gast #2379315
Lesenswert?
• ▲
▼
Danke für die beiden Antworten. Das OS stürtzt inzwischen nicht mehr ab. 
Ich habe das OS jetzt als erstes in main intialisiert, noch vor der 
seriellen Schnittstelle und anderen Devices. Die anderen Sachen habe ich 
dann in die mainTask verschoben und hatte von nun an keine Probleme 
mehr.

main.c
1
SystemInit();
2

3
xTaskCreate( mainTask, ( signed portCHAR * ) "Main", configMINIMAL_STACK_SIZE + 200, NULL, 1, &mainTaskHandle );
4

5
/* Start the scheduler. */
6
vTaskStartScheduler();

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.