Hallo, Als Controller nutzt ich einen STM32L4 Nun versuche ich nach langer Zeit FreeRTOS zum laufen zu bekommen. Wenn ich den xPortSysTickHandler nicht zum SysTick definiere funktioniert der Task und macht, was er soll. Nach dem SystemInit (Clocks, Systick etc) wird direkt der xPortSysTickHandler aufgerufen, welcher danach xTaskIncrementTick aufruft und xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) ); verursacht dann den Hardfault. pxDelayedTaskList ist noch "0x00000000", da zu dem Zeitpunkt kein Task definiert ist. Was mache ich falsch?
Nachtrag: wenn ich nach dem System Init die IRQs ausschalte und direkt vor dem Scheduler wieder aktiviere funktioniert es. Ganz nachvollziehen kann ich es leider nicht.
Benutzt du den stm-Port von freertos? Für den f4 darf man da den systick nicht selber aktivieren. Das macht der Port selber.
Bzw. Schau mal in die Demos rein wie cmsis das handhabt.
Ich nutzte den aus der Demo. "Implementation of functions defined in portable.h for the ARM CM4F port." Habe gerade gesehen, dass in der CMSIS angefragt wird, ob der Scheduler schön läuft
1 | #if (INCLUDE_xTaskGetSchedulerState == 1 )
|
2 | if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) |
3 | {
|
4 | #endif /* INCLUDE_xTaskGetSchedulerState */ |
5 | xPortSysTickHandler(); |
6 | #if (INCLUDE_xTaskGetSchedulerState == 1 )
|
7 | }
|
8 | #endif /* INCLUDE_xTaskGetSchedulerState */ |
Da scheint ein Problem zu sein. Das mit dem Systick schaue ich mir auch noch an, ob er in meinem "Port" definiert ist. Danke
Also ich hab das so gelöst:
int main()
{
stm32_core_init();
periphery_init();
rtos_timer_create(timer_led, "LEDTimer", true, 500, 0);
rtos_ip_init(ip, netmask, gateway, dnsserver, mac);
rtos_create_task(udp_comm_task, "ERB UDP Comm Task", 512, NULL, 7);
rtos_init();
while (true);
return 0;
}
#ifdef USE_FREERTOS
#include "FREERTOS/FreeRTOSConfig.h"
#include "FREERTOS/FreeRTOS.h"
extern void xPortSysTickHandler(void);
#endif
#ifdef USE_FREERTOS
#define USE_SYSTICK
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#endif
void stm32_core_init()
{
...
/* SysTick initialization */
#ifdef USE_SYSTICK
#if ((SYSTICK_HZ - 1) > SysTick_LOAD_RELOAD_Msk)
#error SYSTICK_HZ not possible.
#else
SysTick->LOAD = (uint32_t)((frequency.system_clock / SYSTICK_HZ) -
1UL); /* set reload register */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value
*/
#ifndef USE_FREERTOS
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk
| SysTick_CTRL_ENABLE_Msk;
stm32_irq_priority prio;
prio.preempt_priority = SYSTICK_INT_PREEMPT_PRIO;
prio.sub_priority = SYSTICK_INT_SUB_PRIO;
stm32_irq_enable(SysTick_IRQn, &prio);
#endif
#endif
#endif
...
}
#ifdef USE_SYSTICK
volatile uint32_t tick = 0;
void SysTick_Handler()
{
tick++;
#ifdef USE_FREERTOS
#if (INCLUDE_xTaskGetSchedulerState == 1 )
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
#endif
xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
}
#endif
#endif
}
Das mag vllt nicht so ideal sein, da meine Delayfunktion erst losläuft,
sobald freertos losgelaufen ist. Das sollte man hier noch ändern oder
eben beachten. Normalerweise braucht man die ja eher weniger, wenn man
das OS am laufen hat :>
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.