STM32 - FMC: NAND Write blockiert Interrupts

Gast #6100227
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
        return HAL_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:
1
uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
2
{
3
  uint32_t data = 0U;
4
  uint32_t deviceaddress = 0U;
5
  
6
  /* Identify the device address */
7
  if(hnand->Init.NandBank == FMC_NAND_BANK2)
8
  {
9
    deviceaddress = NAND_DEVICE1;
10
  }
11
  else
12
  {
13
    deviceaddress = NAND_DEVICE2;
14
  } 
15

16
  /* Send Read status operation command */
17
  *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
18
  
19
  /* Read status register data */
20
  data = *(__IO uint8_t *)deviceaddress;
21

22
  /* Return the status */
23
  if((data & NAND_ERROR) == NAND_ERROR)
24
  {
25
    return NAND_ERROR;
26
  } 
27
  else if((data & NAND_READY) == NAND_READY)
28
  {
29
    return NAND_READY;
30
  }
31

32
  return NAND_BUSY; 
33
}

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
Gast #6100236
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.
#6100261
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...
Gast #6100267
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?
Gast #6100268
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 = *(__IO uint8_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...
Gast #6100403
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_t xTaskGetTickCount( void )
2
{
3
TickType_t xTicks;
4

5
  /* Critical section required if running on a 16 bit processor. */
6
  taskENTER_CRITICAL();   <==== !!!!!!
7
  {
8
    xTicks = xTickCount;
9
  }
10
  taskEXIT_CRITICAL();    <==== !!!!!!
11

12
  return xTicks;
13
}
Gast #6100404
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.
Gast #6100407
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.