Forum: Mikrocontroller und Digitale Elektronik STM32, Systick, Arduino, GetCurrentMicro; Verständnisproblem


von Michael (Gast)


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

von Hermann K. (r2d2)


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.

von Hint Hint (Gast)


Lesenswert?

Michael schrieb:
> Übersehe ich etwas?

Ja, es gibt andere Möglichkeiten:

https://www.mikrocontroller.net/articles/STM32_f%C3%BCr_Einsteiger

siehe unter: Taktzeitberechnung und Überwachung

von Hint Hint (Gast)


Lesenswert?

Hier gibt's auch noch reichlich zum schöpfen:

Beitrag "stm32f103 1 us Systick-timer delay"

von Michael (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.