Hallo,
ich habe ein NAND Flash am FMC eines STM32F446 am laufen. Bei einem Page
Write durch die HAL Funktion 'HAL_NAND_Write_Page_8b' wird nach dem
Schreiben der Status gepollt bis das NAND Flash die Daten verarbeitet
hat, das passiert mit folgendem Code:
1
while(HAL_NAND_Read_Status(hnand)!=NAND_READY)
2
{
3
4
if((HAL_GetTick()-tickstart)>NAND_WRITE_TIMEOUT)
5
{
6
returnHAL_TIMEOUT;
7
}
8
}
Die Schleife dauert bei mir ca. 276us. In dieser Zeit kommen bei mir
keine anderen Interrupts durch. Da ich zyklisch einen ADC abfrage ist
mir dies aufgefallen.
Die Funktion HAL_NAND_Read_Status sieht so aus:
Weiss jemand an was das liegt und wie man das beheben kann? Ich habe
schon sämtliche Datenblätter von ST durch aber nichts zu dem Thema
gefunden.
Viele Gruesse
cc
Hast du mal versucht, den ISR-Vektor und den ISR-Code selbst in den RAM
zu verlegen? Vielleicht wird der Zugriff auf den internen Flash
irgendwie blockiert/verzögert.
Programmierer schrieb:> Hast du mal versucht, den ISR-Vektor und den ISR-Code selbst in den RAM> zu verlegen? Vielleicht wird der Zugriff auf den internen Flash> irgendwie blockiert/verzögert.
Es geht hier um externes NAND Flash am FMC.
Mit dem internen NOR Flash des Controllers, in dem defaultmäßig auch die
Vektortabelle steht, hat das gar nichts zu tun...
Das Problem hier dürfte an der Verwendung blockierender HAL Routinen
liegen. Hab mich mit dem FMC bislang nicht beschäftigt, aber bei anderer
Peripherie gibt's statt der blockierenden Varianten auch immer welche,
die nichtblockierend über Callback-Interrupts arbeiten...
Thorsten S. schrieb:> Es geht hier um externes NAND Flash am FMC.
Ich weiß.
Thorsten S. schrieb:> .> Mit dem internen NOR Flash des Controllers, in dem defaultmäßig auch die> Vektortabelle steht, hat das gar nichts zu tun...
Würde man denken. Aber wer weiß, wie sich das beeinflusst und was da
durch die selbe Logik geht.
Thorsten S. schrieb:> Das Problem hier dürfte an der Verwendung blockierender HAL Routinen> liegen.
In denen ist aber nichts von deaktivierten Interrupts zu sehen. Oder
vielleicht in der nicht gezeigten HAL_NAND_Write_Page_8b Funktion?
Programmierer schrieb:> Hast du mal versucht, den ISR-Vektor und den ISR-Code selbst in> den RAM> zu verlegen? Vielleicht wird der Zugriff auf den internen Flash> irgendwie blockiert/verzögert.
Nein, der interne Flash sollte ja genau so wenig/viel beeinflusst sein
wie der RAM. Zudem ist der RAM schon knapp ;)
pegel schrieb:> Könnte das mit:>> #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)>> bzw. der Interrupt Prioritäten zu tun haben?Thorsten S. schrieb:> Das Problem hier dürfte an der Verwendung blockierender HAL Routinen> liegen. Hab mich mit dem FMC bislang nicht beschäftigt, aber bei anderer> Peripherie gibt's statt der blockierenden Varianten auch immer welche,> die nichtblockierend über Callback-Interrupts arbeiten...
Ich habe ein FreeRTOS am laufen und der Aufruf erfolgt in einem Task.
Die Interrupt-Priorität der anderen Interrupts sind auf 0, d.h. diese
würden auf jeden Fall durchkommen. Vor dem Polling des Status kommen
diese ja auch durch.
Die Zeile
1
data=*(__IOuint8_t*)deviceaddress;
benötigt übrigens 20 Cycles habe ich gerade gesehen. Sonst wäre mir
nichts aufgefallen was die Interrupts beeinflussen könnte. Bin weiter
ratlos...
cc schrieb:> Ich habe ein FreeRTOS am laufen und der Aufruf erfolgt in einem Task.
Funktioniert denn der Taskwechsel mittels (SysTick?) Timer Interrupt?
Hier übrigens die ganze Funktion - wer diese nicht selber suchen möchte.
Die ITM_EVENTs habe ich eingefügt, um zu sehen welcher Teil wie lange
benötigt und wo Interrupts blockiert werden. Von Abschalten der
Interrupts ist leider nichts zu sehen...
cc schrieb:> Weiss jemand an was das liegt und wie man das beheben kann?
Irgendeine der HAL-Funktionen wird eine höhere Priorität haben, als der
ADC-Interrupt und ihn daher ständig unterbrechen.
Ich hätte da HAL_GetTick() in Verdacht.
Hallo,
such doch bitte mal raus, wie bei Dir die HAL_GetTick() implementiert
ist. Das ist eine weak, die in der Defaultimplementation ohne
Manipulation der Interruptmaske einen Zähler abfragt, der mit dem HAL
1ms Timer ISR inkrementiert wird (das ist eines der Dinge, die ich an
der ST HAL nicht mag). Es kann aber auch sein, dass die auf
xTaskGetTickCount() gemappt wird, und da hast Du genau das Problem, das
Peter in die Diskussion gebracht hat:
1
TickType_txTaskGetTickCount(void)
2
{
3
TickType_txTicks;
4
5
/* Critical section required if running on a 16 bit processor. */
Peter D. schrieb:> Irgendeine der HAL-Funktionen wird eine höhere Priorität haben, als der> ADC-Interrupt und ihn daher ständig unterbrechen.> Ich hätte da HAL_GetTick() in Verdacht.
Nein, das ist lediglich eine Getter Funktion die eine Variable
zurückgibt. Die ganzen Libraries sind ja an sich nur C code welche keine
Priorität im Sinn eines Interrupts besitzen können.
Das Auslesen des NAND-Status, welches beim schrittweise Debuggen 20
Taktzyklen braucht benötigt - wenn ich vorher und nachher den
Cyclecounter des Kerns auslese doch wesentlich länger, eher so im
Bereich 300us. Das könnte das Problem sein.
RAc schrieb:> such doch bitte mal raus, wie bei Dir die HAL_GetTick() implementiert> ist. Das ist eine weak, die in der Defaultimplementation ohne> Manipulation der Interruptmaske einen Zähler abfragt, der mit dem HAL> 1ms Timer ISR inkrementiert wird (das ist eines der Dinge, die ich an> der ST HAL nicht mag). Es kann aber auch sein, dass die auf> xTaskGetTickCount() gemappt wird, und da hast Du genau das Problem, das> Peter in die Diskussion gebracht hat:
Nein, wird nicht überschrieben. Die Funktion wird hier auch gar nie
aufgerufen, die Funktion HAL_NAND_Read_Status liefert beim ersten Aufruf
das OK.