Forum: Mikrocontroller und Digitale Elektronik STM32F103: DWT Timer stört Debugger?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Chris J. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

habe ich da etwas überlesen? Ich benutze diese Routinen um 
Ausführunsgzeiten zu messen und eine MikroSec Timer zu verwenden aber 
seitdem spielt mein Debuger (swd) etwas verrückt, macht komische Sachen. 
Friert ab und zu ein usw. Hat der damit was zu tun?
1
#pragma GCC push_options
2
#pragma GCC optimize ("O3")
3
void delayUS_DWT(uint32_t us)
4
{
5
  volatile uint32_t cycles = (SystemCoreClock/1000000L)*us;
6
  __disable_irq();
7
  volatile uint32_t start = DWT->CYCCNT;
8
  do  {
9
  } while(DWT->CYCCNT - start < cycles);
10
  __enable_irq();
11
}
12
#pragma GCC pop_options
13
14
#pragma GCC push_options
15
#pragma GCC optimize ("O0")
16
uint32_t DWT_Delay_Init(void) {
17
  /* Disable TRC */
18
  CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; // ~0x01000000;
19
  /* Enable TRC */
20
  CoreDebug->DEMCR |=  CoreDebug_DEMCR_TRCENA_Msk; // 0x01000000;
21
22
  /* Disable clock cycle counter */
23
  DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; //~0x00000001;
24
  /* Enable  clock cycle counter */
25
  DWT->CTRL |=  DWT_CTRL_CYCCNTENA_Msk; //0x00000001;
26
27
  /* Reset the clock cycle counter value */
28
  DWT->CYCCNT = 0;
29
30
     /* 3 NO OPERATION instructions */
31
     __ASM volatile ("NOP");
32
     __ASM volatile ("NOP");
33
     __ASM volatile ("NOP");
34
35
  /* Check if clock cycle counter has started */
36
     if(DWT->CYCCNT)
37
     {
38
       return 0; /*clock cycle counter started*/
39
     }
40
     else
41
  {
42
    return 1; /*clock cycle counter not started*/
43
  }
44
}
45
#pragma GCC pop_options

von lange weiler (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Chris J. schrieb:
> mein Debuger (swd)

Der ist vermutlich geheim weil du dazu keine Angaben machst.

von Chris J. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
lange weiler schrieb:
> Chris J. schrieb:
>> mein Debuger (swd)
>
> Der ist vermutlich geheim weil du dazu keine Angaben machst.

St-Link V2 und alternativ ein Segger JLINK.

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Chris J. schrieb:

> habe ich da etwas überlesen? Ich benutze diese Routinen um
> Ausführunsgzeiten zu messen und eine MikroSec Timer zu verwenden

Das geht auch super, nur heißt DWT doch schon "Data Watchpoint Trigger", 
und der befindet sich im Reference Manual nicht ohne Grund im Kapitel 
"Core Debug". Mit anderen Worten, natürlich kann das in Konflikt mit dem 
Debugger geraten.

von Chris J. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Nop schrieb:
> Chris J. schrieb:
>
>> habe ich da etwas überlesen? Ich benutze diese Routinen um
>> Ausführunsgzeiten zu messen und eine MikroSec Timer zu verwenden
>
> Das geht auch super, nur heißt DWT doch schon "Data Watchpoint Trigger",
> und der befindet sich im Reference Manual nicht ohne Grund im Kapitel
> "Core Debug". Mit anderen Worten, natürlich kann das in Konflikt mit dem
> Debugger geraten.

Das war mir schon fast klar. Wäre es denn auch ein Problem, wenn ich den 
nur lesend verwende? Ihn also nicht zurücksetze. Dann habe ich zwar ein 
Übelaufproblem (evtl.) aber auch nicht wirklich oft. Den Systick 
verwende ich nicht, wäre aber ggf. auch ne Möglichkeit.

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Noch ein Tip, dese Zeile hier:
volatile uint32_t cycles = (SystemCoreClock/1000000L)*us;

Da hast Du eine Division drin. Die würde ich aus dieser Routine 
rauslagern. Bau Dir eine Variable SystemCoreClock_Div_1e6 oder so, die 
Du immer dann updatest, wenn Du die Taktfrequenz des Systems verstellst.

Abgesehen davon ist es relativ sinnfrei, funktions-lokale Variablen als 
volatile zu deklarieren.

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Chris J. schrieb:

> Das war mir schon fast klar. Wäre es denn auch ein Problem, wenn ich den
> nur lesend verwende?

Falls der Debugger den nicht auch noch schreibend verwendet. Sonst gehst 
Du in Dein Delay rein in gutem Glauben, der Debugger spielt damit 
schreibend herum, und heraus kommt irgendein Delay.

> Den Systick verwende ich nicht, wäre aber ggf. auch ne Möglichkeit.

Nicht im Mikrosekunden-Bereich, dann ist die CPU nur noch mit Systick 
beschäftigt. Den kannst Du für Delays im Bereich von Millisekunden 
nehmen, also per Softwaretimer.

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ach ja, und in der Delay-Routine sollte das Allererste sein, das 
Cyclecount-Register auf 0 zu setzen. Alles andere erst danach, weil dann 
der Overhead bereits sauber im Delay beinhaltet wird.

von Chris J. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Nop schrieb:
> Ach ja, und in der Delay-Routine sollte das Allererste sein, das
> Cyclecount-Register auf 0 zu setzen.

Genau das erzeugt ja die Probleme ;-) Daher lasse ich das sein. Den Rest 
arbeite ich mal ein, vor allem die Division raus, einfach nur 2 Zeilen 
höher setzen und fertig, da die Taktfrequenz nie verändert wird. Ich 
benutze sleep zum Heia machen, damit er sich nicht "überhitzt" ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.