STM32, Systick, Arduino, GetCurrentMicro; Verständnisproblem

Gast #5647359
Lesenswert?

Hallo

Ich portiere momentan ein Arduino-Projekt auf nativen Code für STM32. 
Dabei muss ich ein paar Funktionen selbst implementieren, die bisher das 
Ardiuno-Framework bereitstellt. Eine davon ist die Funktion micros(), 
mit der die Systemzeit in Mikrosekunden abgefragt werden kann.

Im Quellcode des Arduino-Frameworks für STM32 ist das folgendermaßen 
umgesetzt:
1
/**
2
  * @brief  Function called to read the current micro second
3
  * @param  None
4
  * @retval None
5
  */
6
uint32_t GetCurrentMicro(void)
7
{
8
  /* Ensure COUNTFLAG is reset by reading SysTick control and status register */
9
  LL_SYSTICK_IsActiveCounterFlag();
10
  uint32_t m = HAL_GetTick();
11
  uint32_t u = SysTick->LOAD - SysTick->VAL;
12
  if(LL_SYSTICK_IsActiveCounterFlag()) {
13
    m = HAL_GetTick();
14
    u = SysTick->LOAD - SysTick->VAL;
15
  }
16
  return ( m * 1000 + (u * 1000) / SysTick->LOAD);
17
}
18

19
/**
20
  * @brief  Function called wto read the current millisecond
21
  * @param  None
22
  * @retval None
23
  */
24
uint32_t GetCurrentMilli(void)
25
{
26
  return HAL_GetTick();
27
}
28

29
/**
30
  * @brief  This function checks if the Systick counter flag is active or not.
31
  * @note   It can be used in timeout function on application side.
32
  * @rmtoll STK_CTRL     COUNTFLAG     LL_SYSTICK_IsActiveCounterFlag
33
  * @retval State of bit (1 or 0).
34
  */
35
__STATIC_INLINE uint32_t LL_SYSTICK_IsActiveCounterFlag(void)
36
{
37
  return ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == (SysTick_CTRL_COUNTFLAG_Msk));
38
}
39

40
/**
41
  * @brief  Povides a tick value in millisecond.
42
  * @note   The function is declared as __Weak  to be overwritten  in case of other 
43
  *         implementations  in user file.
44
  * @retval tick value
45
  */
46
__weak uint32_t HAL_GetTick(void)
47
{
48
  return uwTick;  
49
}

Ich habe Verständnisprobleme bei der Funktion GetCurrentMicro.

Warum gerden die Werte von HAL_GetTick und Systick->LOAD zweimal den 
Variablen m und u zugewiesen?

Ich verstehe, dass die Funktion LL_SYSTICK_IsActiveCounterFlag zweimal 
aufgerufen wird, weil erst beim zweiten Aufruf sicher erkennbar ist, ob 
der Timer wirklich zählt. Aber wozu die zweimalige Zuweisung der Werte 
für m und u?

Genau genommen ergibt der ganze If-Block keinen Sinn, weil in m und u in 
beiden Fällen die gleichen Werte stehen, ganz egal, ob der Block 
durchlaufen wird oder nicht.

Übersehe ich etwas?
 

Gruß
Michael
#5647393
Lesenswert?

Zuerst wird das Flag gelöscht mit dem angezeigt wird, dass gerade 
hochgezählt wurde (COUNTFLAG).
Dann werden die Werte ausgelesen und geschaut ob zwischenzeitlich 
gezählt wurde.
Wenn ja, hast du keinen konsistenten Stand deiner Variablen, weil 
möglicherweise m vor den IRQ gelesen wurde, u aber erst danach.
Also werden die Werte einfach beide nochmal gelesen (im "if"-Block).
Da der SysTick üblicherweise nur jede ms kommt weisst du jetzt sicher, 
dass beim zweiten auslesen kein SysTick-IRQ dazwischen kam und hast 
somit einen konsistenten Stand beider Variablen.
Gast #5647486
Lesenswert?

Hermann K. schrieb:
> Wenn ja, hast du keinen konsistenten Stand deiner Variablen, weil
> möglicherweise m vor den IRQ gelesen wurde, u aber erst danach.
> Also werden die Werte einfach beide nochmal gelesen (im "if"-Block).

Das muss der Grund sein. Das klingt schlüssig. Danke für die Erklärung! 
:-)

Die anderen beiden Links gucke ich mir gleich an. Danke auch dafür.


Gruß
Michael

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren