Hallo,
wir benutzen FreeRTOS v8.2.0 auf einem Cortex M4 (NXP LPC4078) und ich
bekomme in letzter Zeit immer öfter einen Programmabsturz in list.c, in
der Funktion vListInsert() bei der for-Schleife mit den darüber
beschriebenen 4 Fehlerursachen. Suche schon seit Tagen danach im
FreeRTOS-Forum und Google, aber habe leider noch keine Lösung. Wäre
super, wenn mir jemand einen Tipp geben könnte, was es ist.
Im konkreten Fall läuft das Programm und FreeRTOS tadellos und bei einer
bestimmten Aktion wird ein Task per xTaskCreate() erzeugt, der auch
gleich startet und per xTaskNotifyWait() auf eine Antwort wartet. Das
funktioniert an vielen anderen Stellen problemlos. In dieser Funktion
sind in der Mitte die beiden Aufrufe taskEXIT_CRITICAL(); und
taskENTER_CRITICAL(); bei denen das Programm nicht mehr weiterzugehen
scheint und danach an besagter Stelle hängt. Ist im Debugger nicht ganz
einfach nachuvollziehen, wenn man Step-over macht, kommt man nicht
weiter (auch ein späterer Breakpoint wird nicht mehr aufgerufen). Wenn
man aber mit Step-into durchläuft, klappt es meist doch. Da darf man
nicht zuviel auf den Debugger geben (LPCXpresso mit LPC-Link 2).
configASSERT() ist definiert und half mir schon ein paar mal.
Jetzt zu den 4 Möglichkeiten laut FreeRTOS:
1) Stack overflow - see
http://www.freertos.org/Stacks-and-stack-overflow-checking.html
#define configCHECK_FOR_STACK_OVERFLOW 1 ist gesetzt, aber
vApplicationStackOverflowHook wird nie aufgerufen bzw. dort hängt er
nicht. Auch die Überprüfung per vTaskList() vor dem xTaskNotifyWait() -
Aufruf der laufenden Tasks sieht ganz i.O. aus:
1
File Transfer task R 2 268 19
2
AnyBus R 0 150 3
3
IDLE R 0 93 12
4
Tmr Svc B 3 186 13
5
NFC Tag B 0 262 6
6
console B 7 264 11
7
LED Control B 2 195 1
8
Event task B 2 178 15
9
ADC Control B 2 218 7
10
ext. ADC B 2 90 5
11
Eeprom Control B 2 207 8
12
abccCmdHandler B 4 583 10
13
LSB Driver S 0 175 2
"File Transfer task" ist der aktive Task, aus dem der vListInsert() -
crash
auftritt
2) Incorrect interrupt priority assignment, especially on Cortex-M parts
where numerically high priority values denote low actual interrupt
priorities, which can seem counter intuitive. See
http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition of
configMAX_SYSCALL_INTERRUPT_PRIORITY on
http://www.freertos.org/a00110.html
Habe mir beide Webseiten angesehen, aber es ist ehrlich gesagt ziemlich
komplex. Die dort erwähnten #defines habe ich in FreeRTOSConfig.h wie
folgt gesetzt:
#define configPRIO_BITS __NVIC_PRIO_BITS // steht auf 5
Für configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY habe ich schon Werte
von 0-15 ausprobiert, macht kein Unterschied.
Da es so aussieht, dass der Crash in taskEXIT_CRITICAL() passiert würde
ich dennoch vermuten, dass es am ehesten mit den Interrupts
zusammenhängt?
3) Calling an API function from within a critical section or when the
scheduler is suspended, or calling an API function that does not end in
"FromISR" from an interrupt.
Wie erwähnt scheint es in xTaskNotifyWait() aufzutreten, in der Mitte
bei taskEXIT_CRITICAL();. Die Funktion ist original und nicht verändert.
4) Using a queue or semaphore before it has been initialised or before
the scheduler has been started (are interrupts firing before
vTaskStartScheduler() has been called?).
Da das Programm davor einwandfrei läuft, alle Tasks erstellt wurden und
auch vTaskStartScheduler() am Anfang aufgerufen wurde, sollte es damit
nicht zusammenhängen?
Da das Projekt drängt und ich nicht wirklich weiterkomme wegen dem
Hängenbleiben, würde ich mich sehr freuen, wenn mir jemand einen guten
Tipp hat. Falls noch irgendwelche Infos fehlen, liefere ich diese gerne
nach.
Danke schonmal!
Gruß,
Daniel
for(pxIterator=(ListItem_t*)&(pxList->xListEnd);pxIterator->pxNext->xItemValue<=xValueOfInsertion;pxIterator=pxIterator->pxNext)/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
26
{
27
/* There is nothing to do here, just iterating to the wanted
28
insertion position. */
29
}
30
}
Davor war er in einer Funktion und kam bis xTaskNotifyWait:
1
staticboolFile_create(uint16_t*instance)
2
{
3
charstrTaskList[500];
4
fileTask=xTaskGetCurrentTaskHandle();
5
6
*instance=0;// in case of error, return zero
7
8
LogMessage(LOG_FILE_MESSAGE,MSG_FORMATTED,"Creating file system interface object ...");
// response handler will be called from anybus task
33
uint32_tresult;
34
xTaskNotifyWait(0x00,ULONG_MAX,&result,portMAX_DELAY);/* Block indefinitely until notified. */
Dort drin läuft er dann bis taskEXIT_CRITICAL();, danach ist es für mich
unklar. (xTaskNotifyWait hat ziemlich viele Zeilen für den Beitrag hier)
Selbstverständlich kann ich vTaskList(strTaskList); mit dem 400 Byte
array wieder rausnehmen ohne Änderung des Problems.
das ist zu fast 99%iger Sicherheit ein Problem mit falsch konfigurierten
Interrupts. Sieh Dir mal im NVIC Block die Prioritäten der
Interruptsources an und im SCB die der ersten 16 Systeminterrupts.
Ist alles kein Hexenwerk und in meinem Buch recht ausführich
beschrieben. Der SysTick Interrupt muss die niedrigste Priorität haben,
und der Service Interrupt des OS auch. Kein Interrupt, der über
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY liegt, darf OS Services
aufrufen.
USBActivity_IRQn=33,/*!< USB Activity interrupt */
52
CANActivity_IRQn=34,/*!< CAN Activity interrupt */
53
UART4_IRQn=35,/*!< UART4 Interrupt */
54
SSP2_IRQn=36,/*!< SSP2 Interrupt */
55
LCD_IRQn=37,/*!< LCD Interrupt */
56
GPIO_IRQn=38,/*!< GPIO Interrupt */
57
PWM0_IRQn=39,/*!< PWM0 Interrupt */
58
EEPROM_IRQn=40,/*!< EEPROM Interrupt */
59
}LPC40XX_IRQn_Type;
Wenn ich es richtig interpretiert habe, dann steht SysTick_IRQn auf
niedrigster Priorität:
1
NVIC_SetPriority(SysTick_IRQn,(1<<__NVIC_PRIO_BITS)-1);/* set Priority for Systick Interrupt */
Für SVCall_IRQn gibt es gar keinen Aufruf, d.h. steht noch auf 0?
Was könnte nun der Fehler sein? Auch wenn es kein Hexenwerk ist,
überblicke ich das noch nicht ganz.
Bin sehr dankbar für weitere Tipps :-)
Könnte ein bug im LPC Cortex port sein, der mit der 8.2.3. gefixt wurde
(per PM mit Richard Barry). Es geht da um einen fehlerhaften Gebrauch
der __NVIC_PRIO_BITS. Mach mal einen Vergleich der beiden Codebasen.
P.S: Die 0xf8 der OS Interrupts sieht mir auf den ersten Blick nicht ok
aus, was dafür sprechen würde, dass die prio bits nicht richtig
berechnet werden. Ist aber nur ein Schuss ins Blaue (bin auf dem
Sprung).
Okay, dann könnte ich aber gleich auf FreeRTOS v10 aktualisieren?
Oder meinst Du vergleichen und herausfinden was der Bugfix war und nur
das eine übernehmen (wäre wesentlich weniger Arbeit)?
Die 0xF8 kommen halt aus der Übergabeparameter-Formel "1 um 5 nach links
shiften = 0010 0000 und 1 abziehen macht 0001 1111.
In NVIC_SetPriority() wird das dann um (8-5) nach links geschiftet, so
dass alle Bits "oben" anfangen, also 1111 1000, daher die 0xF8.
Berechnung also korrekt. Da alle Bits auf 1 stehen, müsste es doch die
niedrigste Priorität sein, oder was wäre da falsch?
ich hatte anfangs das problem das __NVIC_PRIO_BITS zwar in der cmsis
definiert wurde .. aber die IDE ( eclipse ) das an einigen stellen auch
in der FreeRTOSConfig.h ignoriert hat.
bei mir steht da:
1
#ifdef __NVIC_PRIO_BITS
2
/* __NVIC_PRIO_BITS will be specified when CMSIS is being used. */
3
#define configPRIO_BITS __NVIC_PRIO_BITS
4
#else
5
#define configPRIO_BITS 4
6
#endif
demnach nur 4 bits bei Cortex M... ist der LPC hier anders mit 5bits ?
mein M7 :
1
#define __NVIC_PRIO_BITS 4 /*!< CM7 uses 4 Bits for the Priority Levels */
Der Cortex schreibt ein Minimum von 8 Prio levels vor, d.h. 3 der 8 bits
müssen minimal signifikant sein. Was in den restlichen 5 bits passiert
ist maufacturer dependent; manche pods unterstützen bis zu 256 levels
(brauchen also alle 8 bits), manche ignorieren die ungebrauchten bits,
und manche definieren Subprioritäten o.ä. in den bits.
Wenn ich es richtig in Erinnerung habe, sind die priority levels im NVIC
und dem SCB konsistent, d.h. wenn im NVIC die Prioritäten mit x8 (~1)
und x28 (~5) codiert sind, dann wäre 0xf8 die (unzulässige) höchste
Priorität.
Was gdfgsdgsg schreibt, klingt sehr nach dem Problem, das ich mit R.
Barry mal am Wickel hatte.
@Daniel: Du kannst ja spasseshalber mal versuchen, direkt am Anfang
deiner ersten Task die Priorität von SysTick und PendSV explizit auf 0x8
festzunageln und sehen, ob das am Problem etwas ändert. Dann weisst Du
zumindestens, ob wir den richtigen Baum hoch bellen...
Re Upgrade: Grundsätzlich ist es nicht falsch, immer mit der aktuellen
Version einer Middleware zu arbeiten. Erfahrungsgemäss kann aber der
Portieraufwand ziemlich nervig werden, vor Allem wenn Dritthersteller
ihre custom ports bereit stellen, die dann mit neueren Revisionen wieder
nicht kompatibel sind. You figure.
@gdfgsdgsg: Im Handbuch (s. NVIC1.png im Anhang) lese ich, dass es 32
Interrupt Prioritäten gibt, mit 4 Bits (1111) komme ich nur auf 16
Möglichkeiten, d.h. muss dann __NVIC_PRIO_BITS auf 5 stehen?
Hab es trotzdem mal auf 4 geändert, aber hilft leider nicht.
Außerdem steht im User-Manual UM10562, dass es 5 Bits sind (s.
NVIC2/3.png)
@Rüdiger A.: Die 0x8 habe ich für beide gesetzt per
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x01
in FreeRTOSConfig.h. Im Anhang SHP_mit_0x8.png sieht man, dass es
gesetzt ist. Leider bekomme ich jetzt einen HardFault_Handler - Fehler
während einer SPI-Initialisierungs-Kommunikation. Das Programm kommt gar
nicht mehr in den Idle-Zustand (ob das jetzt "besser" oder "schlechter"
mit vListInsert geworden ist kann ich noch nicht sagen).
Erst ab 0x05 läuft der Idle Mode wieder, aber das Problem mit
vListInsert besteht trotzdem noch.
Warum soll eigentlich 0xF8 unzulässig sein? Das wäre doch Priorität
0x1F, d.h. die erlaubte Prio 31?
Gibt es noch Dinge, die ich ausprobieren könnte?
Daniel R. schrieb:> @gdfgsdgsg: Im Handbuch (s. NVIC1.png im Anhang) lese ich, dass es 32> Interrupt Prioritäten gibt, mit 4 Bits (1111) komme ich nur auf 16> Möglichkeiten, d.h. muss dann __NVIC_PRIO_BITS auf 5 stehen?> Hab es trotzdem mal auf 4 geändert, aber hilft leider nicht.> Außerdem steht im User-Manual UM10562, dass es 5 Bits sind (s.> NVIC2/3.png)>
2^5 sind 32. Der Cortex ist so gestaltet, dass die signifikanten Bits
immer in den MSB der Prioritätenbytes codiert sind. Das ist bewusst so,
damit unabhängig von der Belegung der nicht genutzten Bits höhere Werte
immer auch höhere Prioritäten sind. Deswegen codieren beim LPC die
obereren 5 bits die Priorität, und deswegen werden die Prioritäten um 5
bits nach links geshiftet. Die 4 ist eine FreeRTOS Default, die haben
beim LPC folglich nichts zu suchen.
> @Rüdiger A.: Die 0x8 habe ich für beide gesetzt per> #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x01> in FreeRTOSConfig.h. Im Anhang SHP_mit_0x8.png sieht man, dass es> gesetzt ist.
Das ist vermutlich der falsche Weg. Mach es umgekehrt so, dass Du am
Ende des kernel launches die beiden Prioritäten explizit umbiegst (Test
code). Ich habe momentan keine Kapazitäten, um die Seiteneffekte deiner
Strategie zu analyisieren, aber ich denke, dass der
configLIBRARY_LOWEST_INTERRUPT_PRIORITY etwas Anderes macht als Du
denkst (such mal danach).
> Leider bekomme ich jetzt einen HardFault_Handler - Fehler> während einer SPI-Initialisierungs-Kommunikation. Das Programm kommt gar> nicht mehr in den Idle-Zustand (ob das jetzt "besser" oder "schlechter"> mit vListInsert geworden ist kann ich noch nicht sagen).> Erst ab 0x05 läuft der Idle Mode wieder, aber das Problem mit> vListInsert besteht trotzdem noch.>> Warum soll eigentlich 0xF8 unzulässig sein? Das wäre doch Priorität> 0x1F, d.h. die erlaubte Prio 31?>
Ja, aber SysTick und PendSV müssen die niedrigste Priorität haben. Warum
steht in meinem Buch. 31 wäre die höchste.
Hier ist ansonsten auch eine hilfreiche Quelle:
https://www.freertos.org/RTOS-Cortex-M3-M4.html> Gibt es noch Dinge, die ich ausprobieren könnte?
Der sicherste Weg besteht darin, eine funktionierende Codebasis zu
nehmen und Stück für Stück zu portieren. Ist eure Hardware selbst
gestrickt oder basierend auf einem Eval Board? Bei zweiterem gibt es
bestimmt Codebeispiele für FreeRTOS im Ökosystem des Boardherstellers.
Ansonsten habe ich funktionierende Beispiele (allerdings für Andere
Cortex Derivate) hier: https://www.springer.com/de/book/9783658148492,
runterscrollen, Zusatzmaterial. Mit Chance laufen die Kapitel 3
Beispiele aus der Büchse heraus auf deinem Controller (die OS Beispiele
benutzen nur den reinen Cortex Kern, keine Board Peripherie ausser
vielleicht ein paar LEDs), dann kannst Du dir die Registerinhalte ja mal
genauer ansehen.
Im Handbuch steht doch, dass 31 die niedrigste Priorität hat
(NVIC3.png), wie kommst Du dann darauf, dass das die höchste sein soll?
Ich hab den Code durchsucht, configLIBRARY_LOWEST_INTERRUPT_PRIORITY
wird soweit ich sehen kann nur für die beiden Interrupts PendSV_IRQn und
SysTick_IRQn verwendet.
In einem der ersten Tasks mit Prio 0 habe ich die beiden Zeilen
eingebaut:
1
NVIC_SetPriority(PendSV_IRQn,1);
2
NVIC_SetPriority(SysTick_IRQn,1);
Dann passiert genau das gleiche wie mit
configLIBRARY_LOWEST_INTERRUPT_PRIORITY, es tritt ein HardFault während
der Initialisierung auf.
Was genau soll das denn bringen, weil laut FreeRTOS sollen beide doch
die niedrigste Prio haben (schreibst Du auch, aber dagegen meinst Du
anscheinend dass "0" die niedrigste ist)?
Dein STM32-Beispiel aus Kapitel 3 habe ich mir angesehen, aber unser
System ist einfach viel zu komplex um das mal schnell zu testen. Ich
möchte nicht von vorne anfangen. Die Entwicklung geht schon etwa 2
Jahre und FreeRTOS funktioniert an sich tadellos. Erst jetzt durch meine
Änderungen der letzten Wochen tritt dieser Fehler auf (ich kann nicht
sagen, was an meinen Änderungen kritisch sein sollte... und auch nicht
ab wann genau es auftrat, vielleicht gab es das früher auch schon, wenn
man einige Debug-#defines zugeschaltet hätte).
Ich habe ehrlich gesagt keine Lust mehrere 100 git-Commits durchzugehen
und zu prüfen, wo es instabiler läuft. Lieber wäre mir, dem Fehler auf
die Schliche zu kommen, zumal ja diese 4 Fehlermöglichkeiten extra
aufgelistet werden.
Ich könnte mir mit gewissem Aufwand vorstellen auf v10 zu aktualisieren,
aber das Projekt drängt. Ein gezieltes eingrenzen der Ursache fände ich
am besten. Na... gibt es noch ein paar Ideen?
Vielleicht kaufen wir auch Dein Buch. Finde es echt super hier an den
Autor rangekommen zu sein :-)
Daniel R. schrieb:> Im Handbuch steht doch, dass 31 die niedrigste Priorität hat> (NVIC3.png), wie kommst Du dann darauf, dass das die höchste sein soll?>> Ich hab den Code durchsucht, configLIBRARY_LOWEST_INTERRUPT_PRIORITY> wird soweit ich sehen kann nur für die beiden Interrupts PendSV_IRQn und> SysTick_IRQn verwendet.>
kann ich erst beantworten, wenn ich mal wieder an einem Cortex System
arbeite und mir das im echten Leben ansehen kann...
>> Dein STM32-Beispiel aus Kapitel 3 habe ich mir angesehen, aber unser> System ist einfach viel zu komplex um das mal schnell zu testen. Ich> möchte nicht von vorne anfangen. Die Entwicklung geht schon etwa 2> Jahre und FreeRTOS funktioniert an sich tadellos. Erst jetzt durch meine> Änderungen der letzten Wochen tritt dieser Fehler auf (ich kann nicht> sagen, was an meinen Änderungen kritisch sein sollte... und auch nicht> ab wann genau es auftrat, vielleicht gab es das früher auch schon, wenn> man einige Debug-#defines zugeschaltet hätte).
ok, kann es sein, dass Du in einem ISR mit höherer Priorität als
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY versuchst einen
Systemaufruf (Semaphore signalisieren o.ä.) vornimmst?
In jedem Fall wäre meine Strategie, deine Änderungen Stück für Stück
zurückzunehmen, bis das Problem nicht mehr auftritt, dann hast Du es
genau genug lokalisiert.
Und: Ein Stacküberlauf wird nicht 100% verlässlich über den
Signaturmechanismus erkannt, wie folgendes Beispiel zeigt:
void AFunctionThatOverwritesTheStack(...)
{
unsigned long a_TrashVal;
unsigned char a_SomeArray[100];
....
a_TrashVal = 0x55555555;
}
wenn bei Eintritt in diese Funktion noch 50 bytes stack übrig sind und
auf a_SomeArray nur partiell zugegriffen wird (das Array wird ja nur
reserviert, nicht notwendigerweise überschrieben), dann ist der
Schreibzugriff auf a_TrashVal weit jenseits des Stacks, aber der Context
Switcher erkennt nichts böses (weil die Stacksignatur noch intakt ist).
Es kann also trotzdem ein Stack Overflow sein.
Ich bin sämtliche Interrupts durchgegangen, alle werden mit der
Priorität configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY oder höher
initialisiert. Habe zur Sicherheit +2 angehängt, aber das ändert nichts.
Änderungen Stück für Stück zurücknehmen ist nicht so einfach, weil
zuletzt eine ganze Programmbibliothek aktualisiert und mit Änderungen
eines anderen Branches gemergt wurde. Habe mir damals aber alles Stück
für Stück mit Beyond Compare angeschaut. Es geht ja auch alles, bis dass
er halt irgendwann (es muss nicht unbedingt bei erwähntem xTaskNotify()
auftreten) wieder bei vListInsert steht. Habe schon versucht die
Parameter der for-Schleife auszuwerten, aber ist sehr kompliziert. Auch
im Debugger aus vListInsert rauspsringen brachte mir keine Erkenntnisse
(...).
Hab nun nochmal mit dem Heap und den Task-Stack-Größen rumgespielt. Wenn
der Heap zu klein und in einem Task zuviel Stack angefordert wird, dann
kommt es bei einem xTaskCreate bei prvAllocateTCBAndStack zu einem
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY.
Angenommen es tritt ein Stack-Overflow auf und
vApplicationStackOverflowHook zeigt es mir warum auch immer nicht an,
dann sollte das Problem doch mit einer größeren configTOTAL_HEAP_SIZE
beseitigt werden, solange es ausreichend vergrößert wird?
Auch wenn ich configTOTAL_HEAP_SIZE maximal vergrößere auf 44kb, wodurch
der 64kb RAM komplett voll ist, bleibt das Problem 1:1 bestehen.
Mal sehen, ob ich morgen noch Ideen habe, was neue Erkenntnisse bringt,
ansonsten bin ich dankbar für jeden Tipp :-)
Daniel R. schrieb:> Ich bin sämtliche Interrupts durchgegangen, alle werden mit der> Priorität configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY oder höher> initialisiert. Habe zur Sicherheit +2 angehängt, aber das ändert nichts.>
Hallo Daniel,
also da die Info, dass das FreeRTOS seit 2 Jahren stabil lief, erst
später kam, würde ich Alles was Interrupts, Prioritäten etc. angeht
erstmal genau so lassen wie es war.
>> Hab nun nochmal mit dem Heap und den Task-Stack-Größen rumgespielt. Wenn> der Heap zu klein und in einem Task zuviel Stack angefordert wird, dann> kommt es bei einem xTaskCreate bei prvAllocateTCBAndStack zu einem> errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY.
Ja, genau so denkt man es sich ja auch... ;-)
> Angenommen es tritt ein Stack-Overflow auf und> vApplicationStackOverflowHook zeigt es mir warum auch immer nicht an,> dann sollte das Problem doch mit einer größeren configTOTAL_HEAP_SIZE> beseitigt werden, solange es ausreichend vergrößert wird?
Äh, nein, Du musst ja explizit bei jedem xTaskCreate() die Stackgrösse
angeben, also solange Du einer Task nicht explizit mehr Stack gönnst,
bringt ja allein das vergrössern des Heaps nicht, oder sehe ich da etwas
falsch?...
> Auch wenn ich configTOTAL_HEAP_SIZE maximal vergrößere auf 44kb, wodurch> der 64kb RAM komplett voll ist, bleibt das Problem 1:1 bestehen.>
Welchen Memory Allocator benutzt Du? Bist Du vielleicht in die fehlende
thread safety Falle getappt
(https://www.freertos.org/a00111.html#heap_3)?
> Mal sehen, ob ich morgen noch Ideen habe, was neue Erkenntnisse bringt,> ansonsten bin ich dankbar für jeden Tipp :-)
Okay, kann sein dass bei xTaskCreate() die usStackDepth absolut und
nicht minimal angegeben wird. Habe diese schon für sämtliche Tasks
vergrößert und mit vTaskList() kontrolliert, normalerweise sollte es
groß genug sein.
Beim Speichermanagment nutzen wir heap_4.c. Die anderen heap-c-Dateien
werden im Build-Prozess exkludiert.
Ist das dann auch Thread-Safe?
Ich bin alle Interrupts durchgegangen und habe tatsächlich 2 aktive
gefunden, die mit Prio 0 liefen, also höhere Prio als
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY. Leider wurde es mit "5"
nicht besser, vermutlich auch weil beide Interrupts (I2C und GPIO) keine
FreeRTOS-Api-Funktionen aufrufen.
Desweiteren hab ich nochmal bei sämtlichen xTaskCreate-Aufrufen
usStackDepth vergrößert, bringt aber auch nichts (configTOTAL_HEAP_SIZE
steht wie schonmal erwähnt auf 40kb). Sollten die folgenden
HighWatermarks aus vTaskList nicht groß genug sein, d.h. weit genug von
0 weg?
Hallo Daniel,
das lezte, was ich ohne genauer in den Code zu sehen als mögliche
Fehlerquelle noch ins Feld werfen würde wäre eine Mutexvariable, die
eigentlich rekursiv sein müsste aber es nicht ist. Das ist ein typischer
Fehler in heap3.c, wo malloc_lock() und malloc_unlock() mit einer nicht
rekursiven mutex implementiert werden (in low Memory conditions rufen
die C Runtime libs malloc_lock() rekursiv auf). In heap4.c sollte das
erstmal kein Thema sein, aber vielleicht hast Du eine andere Stelle, wo
ein Mutex nicht rekursiv definiert ist aber sein müsste. Da Du den hang
immer an derselbesn Stelle hast, sieht das wie ein mögliches
Fehlerszenario aus.
Wenn Ihr gar nicht weiter kommt, kannst Du mir eine PM schreiben.
So, wir haben das Problem gelöst!
Es lag daran, dass ein anderer Stack in unserer Bibliothek an vielen
Stellen global alle Interrupts aus- und wieder eingeschaltet hat, da
dort "kritische" - Bereich definiert wurden, die in der Abarbeitung
nicht durch Interrupts unterbrochen werden dürfen.
In solch einer critical section wurde ein xQueueSend für den UART-Task
verwendet, der unter Umständen voll war und es dann gewartet wurde.
Leider lief aber in dem Moment das ganze FreeRTOS mit dem UART-Task, der
mit xQueueReceive die Queue wieder geleert hätte, nicht mehr weiter,
weil der SysTick-Interrupt durch das globale Ausschalten der Interrupts
nicht mehr lief. Das war dann somit die Endlosschleife, wo es nicht mehr
weiterging, eine Deadlock sozusagen.
Die Lösung könnte nun sein, mit xSemaphoreTake und Give zu arbeiten um
kritische Bereiche nicht zu unterbrechen und gleichzeitg das Sperren
aller Interrupts zu umgehen, damit der UART-Task die Queue weiterhin
abarbeitet.
Danke für die ganzen Tipps!