STM32F103: DWT Timer stört Debugger?

Gast #5237944
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
Gast #5237990
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.
Gast #5237995
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.
Gast #5237998
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.
Gast #5238001
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.
Gast #5238250
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

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