Hallo,
ich arbeite mit einem STM32 und FreeRTOS.
Ich habe die Tasks mit der PRIO configKERNEL_INTERRUPT_PRIORITY und die
Interruptroutine mit PRIO configMAX_SYSCALL_INTERRUPT_PRIORITY laufen
(ruft eine API Funktion).
Nach unbestimter Zeit (2 Sekunden - 3 Minuten) hängt das System - die
Tasks werden nicht mehr ausgeführt, die Interrupt Routine schon.
Hat jemand Ahnung, wie die PRIOs eingestellt gehören? Ich habe alles
durchgelesen und nach den Vorgaben eingestellt, aber ohne Erfolg.
Hier die Interrupt-Routine :
Oh, ich glaube Du verwechselst da was. Die Interrupt-Prioritäten haben
nichts mit den Task-Prioritäten zu tun.
Interrupt-Prioritäten (FreeRTOS auf Cortex-M3):
Du willst:
Eigentlich immer:
#define configKERNEL_INTERRUPT_PRIORITY 255
Setzt die Task-Wechsel-Routine auf niedrigste Priorität. Nur daran
rumspielen, wenn Du genau weißt, wie der Taskwechsel von FreeRTOS auf
dem CM3 funktioniert.
Bei dem hier hast Du Spielraum:
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (8<<4) //only 4 bits
implem. in STM32
Wenn Du jetzt eine Interruptroutine hast, die FreeRTOS-Syscalls macht
(wie Deine Empfangsroutine) dann muss sie eine niedrigere oder gleiche
Priorität als configMAX_SYSCALL_INTERRUPT_PRIORITY haben (Cortex-M3:
niegerigere Priorität -> größerer Wert).
Und zwar im NVIC. Also z.b. so:
NVIC_SetPriority(USART1_IRQn, 9);
Dabei ist zu beachten: Im STM32 sind nur 4 Bits an Prioritäten
implementiert. Mit NVIC_SetPriority() setzt Du nur die wichtigen oberen
4 Bits. configMAX_SYSCALL_INTERRUPT_PRIORITY bezieht sich aber auf das
ganze Byte. Darum wie in obigem Beispiel das shift-left um 4.
FreeRTOS 5.3.0 hatte noch ein bisschen Schluckauf mit der
ST-Firmware-Lib 3.0 bei den high-density devices. Da gabs großes
Stack-Durcheinander. Ob das mittlerweile besser/korrigiert ist, weiß ich
nicht: http://sourceforge.net/forum/message.php?msg_id=7447039
Task-Prioritäten (z.b. bei xTaskCreate()):
Hier gehts nur drum welcher Task wann Prozessorzeit bekommt. Das ist
immer ein Wert zwischen 0 (idle Task) und configMAX_PRIORITIES-1.
Gruß
Clemens
Wie komme ich drauf, was schuld ist. Ich habe schon alles ausprobiert.
Was ich nicht verstehe ist, wenn der Kenel die niedrigste Priorität hat
und die Tasks die gesamte Zeit brauchen, wie soll der Kernel dann alles
managen? Sollte er nicht die höhste haben?
Philipp
Für mich sieht das erstmal gut aus.
Zum Thema Prioritäten:
Deine Task-Prioritäten haben NIX mit den Interrupt-Prioritäten zu tun.
Deine Tasks sind keine Interrupts! Die haben Ihre eigene Hierarchie.
Die Task-Wechsel-Routine vom FreeRTOS muss die kleinste
INTERRUPT-Priorität haben, da es sonst Stackgewurschtel gibt. Dadurch
werden die Tasks erst
umgeschalten wenn kein Interrupt mehr bearbeitet wird.
Ich würde mal vor allem das hier aus Deiner ISR rausnehmen:
taskDISABLE_INTERRUPTS();
taskENABLE_INTERRUPTS();
Ich weiß nicht ob das was macht, aber brauchen tust Du's nicht.
Sonst würde ich mal testen ob eine einfach blinkende LED läuft. oder ob
tatsächlich die IRQ-routine schuld ist.
Tut das, dann die UART ISR mal einfach die Empfangsdaten aus dem
Empfangsregister auslesen lassen und keine FreeRTOS-Syscalls machen
lassen.
...und halt langsam an den Fehler rantasten.
Hallo,
nur mal so ein Gedanke:
In der IRQ Routine wird zwar TXE abgefragt aber nichts weiter gemacht.
Muß das interrupt Enable nicht abgeschaltet werden für TXE ?
Ich habe auch den STM32 mit FreeRTOS am laufen. Jedoch spreche ich die
Serielle Schnittstelle direkt an und nicht über die Library.
Bei mir sieht es wie folgt aus:
Hallo,
ich habe deine IRQ Routine mal ausprobiert und es bleibt leider. Nach
einigen Sekunden steht das System. Kannst du mir mal deine Prioritäten
mitteilen. Der Stack - so wie es aussieht - kanns nicht sein.
Moin moin,
ich habe mal mein kleines Projekt angehängt. Es handelt sich um zwei
Eclipse Projekte. Das eine enthält freeRTOS, als Ergebnis wird eine
Library erzeugt. Die Library wird vom zweiten Projekt verwendet und
enthält neben Serieller Schnittstelle mit eigenem Task noch einen Task
zum Blinken einer LED. Ausserdem wird noch die RTC initialisiert und ein
Timer initialisiert, jedoch nicht wirklich benutzt.
Bei mir läuft das unter Windoof XP mit Eclipse (Ganymed), neuestem
Yagarto und "GNU ARM Eclipse Plugin".
Ich hoffe das hilft dir weiter.
Gruß
Garag
Hallo,
so ich glaube, das Problem ist gelöst. Ich ergänze diesen Thread, falls
jemand anderer auch das Problem hat.
Die Prioritäten für die Interrupt-Routinen (USART, ...) werden wie folgt
definiert :
1
// Configure the NVIC Preemption Priority Bits
2
// wichtig!, sonst stimmt nichts überein mit den neuen ST Libs (ab Version 3.1.0)
3
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
4
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
5
6
// entspricht 11-15, 11 ist das höchst mögliche, sonst gibt es Probleme mit dem OS