Forum: Mikrocontroller und Digitale Elektronik STM32 läuft mit Debugger schneller als er soll


von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Die LED an PC13 blitzt wie erwartet im Sekundentakt.

Aber wenn ich das Programm mit dem Debugger ausführe, blitzt sie 
schneller (0,75 Sekunden). Woran kann das liegen?

Das Programm wurde mit der Option -O0 compiliert.

Hardware:
Dieses minimale STM32F303CCT6 Board
https://robotdyn.com/stm32f303cct6-256-kb-flash-stm32-arm-cortexr-m4-mini-system-dev-board-3326a9dd-3c19-11e9-910a-901b0ebb3621.html
Als Debugger nutze ich die SW4STM32 in Kombination mit einem originalen 
ST-Link v2.1

von Dr. Sommer (Gast)


Lesenswert?

Ist das ITM_Print schneller wenn der Debugger dran ist? Nimm das mal 
raus.

von Stefan F. (Gast)


Lesenswert?

> Ist das ITM_Print schneller wenn der Debugger dran ist?
> Nimm das mal raus.

Habe ich probiert, das macht keinen Unterschied.

Wenn ich als Taktquelle HSI 8 MHz oder HSE 8Mhz anstelle der PLL nutze, 
tritt der Effekt nicht auf.

Ich habe inzwischen diverse PLL Multiplier durchprobiert. Der einzige, 
bei dem der Effekt nicht auftritt ist 9x (=72 MHz).

von Stefan F. (Gast)


Lesenswert?

Der Effekt tritt in einem von CubeMX generiertem Projekt (bei 48Mhz) 
nicht auf. Irgendwas muss in meinen wenigen in SystemInit() falsch sein. 
Kann mir jemand helfen, diese Funktion zu überprüfen?

von Rätsel Rater (Gast)


Lesenswert?

Stefanus F. schrieb:
> Irgendwas muss in meinen wenigen in SystemInit() falsch sein.

Muss doch nicht.

Vielleicht fummelt dein Debugger (also der Teil der im PC
läuft) in den Controller-Registern rum und keiner weiss es?

von Stefan F. (Gast)


Lesenswert?

Rätsel Rater schrieb:
> Vielleicht fummelt dein Debugger (also der Teil der im PC
> läuft) in den Controller-Registern rum und keiner weiss es?

Aber müsste der Fehler dann nicht ebenso in dem Cube-HAL Projekt 
auftreten?

Ich habe gerade mal den HSI Oszillator anstelle von HSE mit PLL x6 
verwendet. Das tritt das Problem auch auf. Ein Problem mit dem Quart 
kann ich damit wohl auch ausschließen.

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Weil ich den China-Produkten nicht traue, habe ich das Ganze jetzt mit 
einem anderen Board (Nucleo64 STM32F303RET6) wiederholt.

Das Problem tritt auch dort auf. Die LED blinkt wieder alle 0,75 
Sekunden anstatt jede Sekunde, wenn ich den Debugger benutze.

Es ist also definitiv kein Hardwarefehler.

Ich habe den Vollständigkeit halber den Quelltext für den STM32F303RE 
angehängt. Ist im Prinzip identisch, nur die Trace Meldungen habe ich 
dieses mal weg gelassen.

von Dr. Sommer (Gast)


Lesenswert?

Stefanus F. schrieb:
> Irgendwas muss in meinen wenigen in SystemInit() falsch sein

Fehlt da nicht am Ende das Warten auf das Umschalten des Takts auf die 
PLL? Vielleicht ein paar DSB einstreuen?

von Stefan F. (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Fehlt da nicht am Ende das Warten auf das Umschalten des Takts auf die
> PLL? Vielleicht ein paar DSB einstreuen?

Meinst du das?:
> // Wait until PLL is ready
> while(!READ_BIT(RCC->CR, RCC_CR_PLLRDY)) {}

von Dr. Sommer (Gast)


Lesenswert?

Stefanus F. schrieb:
> Meinst du das?:

Nein, das Umschalten danach braucht IIRC auch noch eine Warteschleife.

Hier ein funktionierender Code für F103:
https://github.com/Erlkoenig90/f1usb/blob/master/sys/clockconf.c

von Stefan F. (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Hier ein funktionierender Code für F103

Vielen Dank, das habe ich direkt ausprobiert. Leider bleibt mein Problem 
bestehen. Um es noch weiter einzugrenzen, habe die Verwendung des 
Systemtimers raus geschmissen und stattdessen Warteschleifen 
programmiert.

Die funktionieren auch wie gewünscht ohne Debugger, aber mit Debugger 
läuft er wieder deutlich zu schnell.


Mein Quelltext sieht inzwischen so aus:
1
#include <stdint.h>
2
#include "stm32f3xx.h"
3
4
// delay loop without using a timer
5
// for 48MHz, Latency 1, gcc optimizer enabled
6
void delay_ms(uint32_t msec)
7
{
8
    for (uint32_t j=0; j<6000UL*msec; j++)
9
    {
10
        __NOP();
11
    }
12
}
13
14
// Change system clock to 48 MHz using 8 MHz crystal
15
// Called by Assembler startup code
16
void SystemInit(void)
17
{
18
    // Flash latency 1 wait state
19
    MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_0);
20
21
    // Enable HSE oscillator
22
    SET_BIT(RCC->CR, RCC_CR_HSEON);
23
24
    // Wait until HSE oscillator is ready
25
    while(!READ_BIT(RCC->CR, RCC_CR_HSERDY)) {}
26
27
    // 48 MHz using the 8 MHz HSE oscillator with 6x PLL, lowspeed I/O runs at 24 MHz
28
    WRITE_REG(RCC->CFGR, RCC_CFGR_SWS_HSE + RCC_CFGR_PLLSRC_HSE_PREDIV + RCC_CFGR_PLLMUL6 + RCC_CFGR_PPRE1_DIV2);
29
30
    // Enable PLL
31
    SET_BIT(RCC->CR, RCC_CR_PLLON);
32
33
    // Wait until PLL is ready
34
    while(!READ_BIT(RCC->CR, RCC_CR_PLLRDY)) {}
35
36
    // Select PLL as clock source
37
    MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
38
39
    // Wait until PLL is active
40
    while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_1) __NOP ();
41
}
42
43
44
int main(void)
45
{
46
    // Enable Port A
47
    SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN);
48
49
    // PA5 = Output
50
    MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER5, GPIO_MODER_MODER5_0);
51
52
    while (1)
53
    {
54
        // LED On (High)
55
        WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BS_5);
56
        delay_ms(100);
57
58
        // LED Off (Low)
59
        WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BR_5);
60
        delay_ms(900);
61
    }
62
}

Ich habe inzwischen den gcc Optimizer eingeschaltet. Das beeinflusst 
natürlich die Geschwindigkeit der Warteschleife, aber ändert nichts an 
meinem Problem.

von Dennis R. (dennis_r93)


Lesenswert?

Zeig mal dein Debug initialisierungsscript.

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Dennis R. schrieb:
> Zeig mal dein Debug initialisierungsscript.

Gerne, siehe Anhang. Ich habe gleich noch ein paar andere Dateien 
angehängt, die vielleicht nützlich sein könnten.

Das ist für mich ein richtig schräges Rätsel. Mein Code stimmt ziemlich 
mit dem Beispiel auf 
https://github.com/cjheath/stm32f3-discovery-basic-template/blob/master/src/system_stm32f30x.c 
überein. Ich habe nur ein paar oder-Verknüpfungen mit Konstanten 
weggelassen, die den Wert 0 haben (RCC_CFGR_HPRE_DIV1 und 
RCC_CFGR_PPRE2_DIV1).

von Stefan F. (Gast)


Lesenswert?

Es gibt Sachen, die gibt's gar nicht. Aber Dennis R. hat mich in die 
richtige Richtung geführt.

Und zwar habe ich jetzt die STM32 Cube IDE heruntergeladen und siehe da: 
Das Problem ist weg!

Zurück in die System Workbench: Problem ist wieder da.

von (Gast)


Lesenswert?

du verwendest openocd?

schau mal in die targets/stm32f3x.cfg:
1
proc stm32f3x_default_reset_init {} {
2
        # Configure PLL to boost clock to HSI x 8 (64 MHz)
3
        mww 0x40021004 0x00380400   ;# RCC_CFGR = PLLMUL[3:1] | PPRE1[2]
4
        mmw 0x40021000 0x01000000 0 ;# RCC_CR |= PLLON
5
        mww 0x40022000 0x00000012   ;# FLASH_ACR = PRFTBE | LATENCY[1]
6
        sleep 10                    ;# Wait for PLL to lock
7
        mmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1]
8
9
        # Boost JTAG frequency
10
        adapter_khz 8000
11
}

vielleicht tut das was ungutes.

von (Gast)


Lesenswert?

Die RCC-Register kann man sich ja ansehen, steht da das drin was 
drinstehen soll? Gibts Unterschiede zwischen dem 1s und 0.75s Blinker?

von Dennis R. (dennis_r93)


Lesenswert?

Hallo Stefanus,

Das ist sehr komisch. Mir selber ist so ein Verhalten noch nie 
vorgekommen.

Dein Script sieht unauffällig aus, aber ich kenne die Inlcudes nicht.
Ich selber kenne nur die Keil Scripte.

Ich gehe davon aus, dass der Inhalt vom Flash beides mal der gleiche 
ist.
Ist das Blinken nur dann schneller wenn der Debugger Aktiviert ist oder 
reicht es schon den Debugger einfach nur mit dem Board zu verbinden?

Hast du ein Osziloskop zur Hand? Dann könntest du mit an einem Pin den 
Systemtakt ausgeben und mit dem Osziloskop erkennen was los ist.

Der ITM hat i.d.r. einen Puffer. D.h. wenn du ein mal Pro sekunde
4 Buchstaben schreibst dann sollte das keine 
Geschwindigkeitsauswirkungen haben.

Kannst du den ITM Port Lesen ohne den Kern zu debuggen?
Dafür müsstest du die ITM Ausgabe in deinem Init Script aktivieren.

Edit:

Ok, ihr scheint das Problem gefunden zu haben :-)

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Dennis R. schrieb:
> Ist das Blinken nur dann schneller wenn der Debugger Aktiviert ist
Ja

> Dann könntest du mit an einem Pin den Systemtakt ausgeben
> und mit dem Osziloskop erkennen was los ist.

Nicht nötig, denn ich habe ja schon anhand der delay() Schleife bemerkt, 
dass der Systemtakt genau um Faktor 1,5 zu schnell ist.

> Kannst du den ITM Port Lesen ohne den Kern zu debuggen?

Ich weiß nicht, wie man das macht.

rµ schrieb:
> schau mal in die targets/stm32f3x.cfg:
> # Configure PLL to boost clock to HSI x 8 (64 MHz)
> vielleicht tut das was ungutes.

Das passt exakt zur falschen Blink-Frequenz, die ich sehe.

> Die RCC-Register kann man sich ja ansehen

Nicht in der System Workbench, wo der Fehler auftritt. Aber du hast mich 
auf eine Idee gebracht. Da gibt es ein paar Bits in den RCC Registern, 
die man nur umstellen darf, wenn die PLL deaktiviert ist. Wenn jetzt der 
Debugger die PLL auf 64 MHz einstellt, ist mein Programm vielleicht 
genau deswegen nicht imstande, sie auf 48 Mhz umzustellen.

Die ST Cube IDE benutzt was anderes als openocd, das könnte erklären, 
warum das Problem mit der Cube IDE richtig läuft.

Ihr seid echt super, jetzt habe ich einen Ansatzpunkt, mit dem ich 
arbeiten kann. Vielen Dank!

von Stefan F. (Gast)


Lesenswert?

Ich hab's ausprobiert. Das war es wirklich. Ich musste zwei Zeilen 
einfügen, um zunächst die PLL zu deaktivieren, bevor ich sie 
umkonfigurieren. Da wäre ich ohne eure Hilfe never ever drauf gekommen.
1
// Change system clock to 48Mhz using 8Mhz crystal
2
// Called by Assembler startup code
3
void SystemInit(void)
4
{
5
    // First disable PLL just in case it was enabled by the debugger
6
    MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSI);
7
    while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_HSI) {}
8
    CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
9
10
    // Flash latency 1 wait state
11
    MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_0);
12
13
    // Enable HSE oscillator
14
    SET_BIT(RCC->CR, RCC_CR_HSEON);
15
16
    // Wait until HSE oscillator is ready
17
    while(!READ_BIT(RCC->CR, RCC_CR_HSERDY)) {}
18
19
    // 48Mhz using the 8Mhz HSE oscillator with 6x PLL, lowspeed I/O runs at 24Mhz
20
    WRITE_REG(RCC->CFGR, RCC_CFGR_SWS_HSI + RCC_CFGR_PLLSRC_HSE_PREDIV + RCC_CFGR_PLLMUL6 + RCC_CFGR_PPRE1_DIV2);
21
22
    // Enable PLL
23
    SET_BIT(RCC->CR, RCC_CR_PLLON);
24
25
    // Wait until PLL is ready
26
    while(!READ_BIT(RCC->CR, RCC_CR_PLLRDY)) {}
27
28
    // Select PLL as clock source
29
    MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
30
31
    // Set USB prescaler to 1, skip in case of 72 MHz
32
    MODIFY_REG(RCC->CFGR, RCC_CFGR_USBPRE, RCC_CFGR_USBPRE);
33
34
    // Update variable
35
    SystemCoreClock=48000000;
36
}

von (Gast)


Lesenswert?

Nur so als Anmerkung zum Abschluss (das Problem ist ja gelöst)

Stefanus F. schrieb:
>> Die RCC-Register kann man sich ja ansehen
>
> Nicht in der System Workbench, wo der Fehler auftritt.

Ich meinte damit, dass sich das Register auslesen lässt, sogar gefahrlos 
und ohne Nebeneffekt. Das muss ja nicht der Debugger machen, das 
Programm kann selber nachschaun was da drin steht.

OpenOCD kann man auch per telnet kontaktieren und mit den 
Memory-Befehlen kann man auch Register auslesen (mrw oder so).

von Stefan F. (Gast)


Lesenswert?

Ein interessanter Nachtrag:
Beim STM32F103 tritt das Problem nicht auf. Ich füge die Zeile jetzt 
aber trotzdem in meine Mustervorlage ein. Ist sicherer.

von Bauform B. (bauformb)


Lesenswert?

rµ schrieb:
> du verwendest openocd?
>
1
 proc stm32f3x_default_reset_init {} {
2
>         # Configure PLL to boost clock to HSI x 8 (64 MHz)
3
> }

Wie krank ist das denn? Sag' bitte, dass das optional ist. Wer denkt 
sich sowas aus? Ist der Herr Poettering jetzt auch im embedded Bereich 
unterwegs?
Mit irgendeinem zufälligen, unbekannten Takt funktioniert doch kaum ein 
Programm. Außer, man treibt einigen zusätzlichen Aufwand, z.B.

Stefanus F. schrieb:
> Ich hab's ausprobiert. Das war es wirklich. Ich musste zwei Zeilen
> einfügen, um zunächst die PLL zu deaktivieren, bevor ich sie
> umkonfigurieren.

> Ich füge die Zeile jetzt aber trotzdem in meine Mustervorlage ein.
> Ist sicherer.

Das ist natürlich richtig, zum *um*-konfigurieren braucht man das, aber 
doch nicht nach einem Reset. Konsequenterweise müsste man bei jedem init 
davon ausgehen, dass alle Register zufällige Werte enthalten. Es gibt 
aber einzelne Bits die man nur einmal schreiben kann...

von (Gast)


Lesenswert?

Bauform B. schrieb:
> rµ schrieb:
>> du verwendest openocd?
>> proc stm32f3x_default_reset_init {} {
>>         # Configure PLL to boost clock to HSI x 8 (64 MHz)
>> }
> Wie krank ist das denn? Sag' bitte, dass das optional ist. Wer denkt
> sich sowas aus? Ist der Herr Poettering jetzt auch im embedded Bereich
> unterwegs?
> Mit irgendeinem zufälligen, unbekannten Takt funktioniert doch kaum ein
> Programm. Außer, man treibt einigen zusätzlichen Aufwand, z.B.

Ich habs nicht ausprobiert oder genauer untersucht ob das immer 
zuschlägt oder nur manchmal. Dass so Debugger in den Registern 
herumfuhrwerken und alles mögliche konfigurieren, damit muss man rechnen 
IMHO. Kommt ja eh komplett mit Quellen.

Zufällig ist der Takt sicher nicht, der interne Oszillator der F3 ist 
immer 8MHz, mal 8 ergibt immmer 64MHz, und das vertragen die MCUs der F3 
Baureihe auch.

von (Gast)


Lesenswert?

Stefanus F. schrieb:
> Ein interessanter Nachtrag:
> Beim STM32F103 tritt das Problem nicht auf. Ich füge die Zeile jetzt
> aber trotzdem in meine Mustervorlage ein. Ist sicherer.

Naja, openocd verwendet beim F103 ja auch ein anderes 
Initialisierungsskript.

von Bauform B. (bauformb)


Lesenswert?

rµ schrieb:
> Zufällig ist der Takt sicher nicht, der interne Oszillator der F3 ist
> immer 8MHz, mal 8 ergibt immmer 64MHz

Für mein Programm ist der Takt zufällig. Vielleicht wird der Faktor 
morgen, oder für einen STM32F105, von 8 auf 4 geändert. Und was ist, 
wenn mein Programm mit dem HSI-Takt zufrieden ist und die PLL nicht 
braucht? Erwarten die wirklich, dass meine UART-Initialisierung die 
PLL-Konfiguration dekodiert und die Baudrate danach einstellt?

Und wie viele ähnliche Überraschungen sind da noch versteckt? Pfuscht 
der vielleicht nicht nur nach einem Reset dazwischen?

Gibt es irgendeine Erklärung, warum man sowas macht? ARM hat die 
SWD-Mimik ziemlich transparent gemacht, der Debugger könnte viel machen 
ohne das Programm zu beeinflussen. Und dann sowas?

von (Gast)


Lesenswert?

Bauform B. schrieb:
> rµ schrieb:
>> Zufällig ist der Takt sicher nicht, der interne Oszillator der F3 ist
>> immer 8MHz, mal 8 ergibt immmer 64MHz
>
> Für mein Programm ist der Takt zufällig. Vielleicht wird der Faktor
> morgen, oder für einen STM32F105, von 8 auf 4 geändert. Und was ist,
> wenn mein Programm mit dem HSI-Takt zufrieden ist und die PLL nicht
> braucht?

Dein Programm muss so oder so neu übersetzt werden wenns von F3 auf F1 
geht. Das openocd-script ist für die F3 gedacht und wird nur für diese 
verwendet.

> Erwarten die wirklich, dass meine UART-Initialisierung die
> PLL-Konfiguration dekodiert und die Baudrate danach einstellt?

Ja. Jeder vernünftige Baudraten-Kalkulator macht das auch so. Abgesehen 
davon gilt es nicht nur den CPU-Takt zu berücksichtigen, sondern 
vielmehr den Takt des jeweiligen Bus' an dem fraglicher UART hängt, das 
kann man bei dem STMs ja teilweise recht flexibel konfigurieren. Wer 
würde schon so eine engstirnige UART-Initialisierung schreiben, die nur 
mit genau einem Fall umgehen kann, und vielleicht den zweiten UART gar 
nicht bedienen kann, weil der am anderen nur halb so schnellen Bus 
hängt?

> Und wie viele ähnliche Überraschungen sind da noch versteckt? Pfuscht
> der vielleicht nicht nur nach einem Reset dazwischen?

Was im OpenOCD sonst noch versteckt ist weiss ich nicht, aber ich hab in 
meine Scripts schon Sachen eingebaut die z.B. die DBGMCU Register so 
ändern, dass die Timer während einem Break stehenbleiben (oder auch 
nicht, je nach dem).

> Gibt es irgendeine Erklärung, warum man sowas macht? ARM hat die
> SWD-Mimik ziemlich transparent gemacht, der Debugger könnte viel machen
> ohne das Programm zu beeinflussen. Und dann sowas?

Offenbar war es irgendwem mit 1MHz zu langsam, und laut Kommentar soll 
der JTAG-Takt maximal 1/6 des CPU-Takts sein.

von S. R. (svenska)


Lesenswert?

Bauform B. schrieb:
> Wer denkt sich sowas aus?

Einer, der die Chips mit OpenOCD flashen will.
Das dauert bei 1 MHz sehr lange, debuggen ebenfalls.

von Bauform B. (bauformb)


Lesenswert?

rµ schrieb:
>> Erwarten die wirklich, dass meine UART-Initialisierung die
>> PLL-Konfiguration dekodiert und die Baudrate danach einstellt?
>
> Ja. Jeder vernünftige Baudraten-Kalkulator macht das auch so. Abgesehen
> davon gilt es nicht nur den CPU-Takt zu berücksichtigen, sondern
> vielmehr den Takt des jeweiligen Bus' an dem fraglicher UART hängt, das
> kann man bei dem STMs ja teilweise recht flexibel konfigurieren. Wer
> würde schon so eine engstirnige UART-Initialisierung schreiben, die nur
> mit genau einem Fall umgehen kann, und vielleicht den zweiten UART gar
> nicht bedienen kann, weil der am anderen nur halb so schnellen Bus
> hängt?

na gut, die UARTs auf dem aktuellen Chip wird man wohl alle 
berücksichtigen. Eine Taktumschaltung zwecks Strom sparen natürlich 
auch. Aber schon dabei gibt's viele Möglichkeiten und ein Programm wird 
nur sehr wenige davon benutzen. Eine wirklich flexible 
UART-Initialisierung würde also viel nie benutzten Code enthalten. Wie 
weit treibt man das im wirklichen Leben? Jedenfalls möchte ich dabei 
nicht noch auf Debugger oder IDE aufpassen müssen.

Immerhin geht's mir dank deiner Geduld schon wieder viel besser ;)

von Stefan F. (Gast)


Lesenswert?

Was ich immer wieder auffällig finde: Wenn man von AVR oder MC51 in die 
Welt der STM32 Controller vordringt, stößt man immer wieder auf 
unerwartete Effekte. Die langen Errata bin ich auch nicht gewohnt.

Ist das bei anderen ARM Controllern auch so, oder ist "lass dich 
überraschen" nur bei ST an der Tagesordnung?

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Bauform B. schrieb:
> Eine wirklich flexible
> UART-Initialisierung würde also viel nie benutzten Code enthalten. Wie
> weit treibt man das im wirklichen Leben?

Der STM32HAL macht sonen schmarrn.
Wenn du da die Baudrate einstellst ließt der erstmal sämtliche RCC 
Register im CLK Pfad zum UART und rechnet den APB Takt aus.

Dabei gibts dann noch ein Bug im CubeMX Autocode für den L431.
Da wird ein PLL Init struct member nicht gefüllt, dann steht zwar 
korrekterweise 1 im Register, aber der Gammel HAL verrehcnet sich um den 
Faktor 2.
-> HAL+Autocode nicht nutzen, nur Bugs, Bugs, Bugs!
1
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
2
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
3
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
4
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
5
//RCC_OscInitStruct.PLL.PLLM = 1;                    << wird von CubeMX nicht inited und steht daher auf 0 (bss) -> HAL nimmt defaultwert von 2, aber die PLL bekommt 1 im Reg
6
RCC_OscInitStruct.PLL.PLLN = 10;
7
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
8
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
9
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;

Dadurch passiert folgendes im UARt Init Code des Gammel HALs:
1
uint32_t clk = HAL_RCC_GetPCLK2Freq(); // CLK = 31750000 statt 80000000
2
usartdiv = (uint16_t)(UART_DIV_SAMPLING16(clk, huart->Init.BaudRate));

von (Gast)


Lesenswert?

Stefanus F. schrieb:
> Was ich immer wieder auffällig finde: Wenn man von AVR oder MC51 in die
> Welt der STM32 Controller vordringt, stößt man immer wieder auf
> unerwartete Effekte. Die langen Errata bin ich auch nicht gewohnt.
>
> Ist das bei anderen ARM Controllern auch so, oder ist "lass dich
> überraschen" nur bei ST an der Tagesordnung?

Also ich bin am Anfang bei den AVRs auch auf genug unerwartete Effekte 
gestossen, vor allem in Verbindung mit den Fuses, dem EEPROM und ein 
paar anderen Kleinigkeiten die ich nach Jahren erfolgreich aus dem 
Gedächtnis verdrängt habe.

Von der Komplexität her ist so ein ARM ja nicht vergleichbar mit den 
AVRs, "mehr" (eingebaute Peripherie) erzeugt halt "mehr" (potentiell 
unerwartetes Verhalten).

von (Gast)


Lesenswert?

Mw E. schrieb:
> Bauform B. schrieb:
>> Eine wirklich flexible
>> UART-Initialisierung würde also viel nie benutzten Code enthalten. Wie
>> weit treibt man das im wirklichen Leben?
>
> Der STM32HAL macht sonen schmarrn.
> Wenn du da die Baudrate einstellst ließt der erstmal sämtliche RCC
> Register im CLK Pfad zum UART und rechnet den APB Takt aus.

Mit der STM HAL handelt man sich so oder so viel Code ein der großteils 
unbenutzt ist. Von der Code-Ästhetik (die grenzwertig grausam ist) ganz 
abgesehen, aber #define DAS_IST_SOWIESO_EIN_CMSIS_PROBLEM. Die 
Bug-Dichte finde ich auch bedenklich, aber so als Inspirationsquelle wie 
gewisse Abläufe prinzipiell denkbar wären ist es ganz brauchbar.

Bei mir bleibt auch der Eindruck zurück, dass man Flash verbrauchen 
will. Bei den großen Controllern isses ja wurscht ob man 15kB 
generierten Code nur zur Initialisierung der Pins mitlinkt, hat man nur 
32kB isses aber nicht mehr so egal...

In dem Fall der Baudraten-Berechnung kann die lib aber nicht wirklich 
anders, irgendwoher muss die ja wissen, wie schnell der UART getaktet 
ist, und soo kompliziert ist das ClockTree-auslesen ja auch wieder 
nicht.

Ansonsten, wenn man alles zur Compile-Zeit wüsste und sich nichts zur 
Laufzeit ändert könnte man das ja auch direkt als Konstante im Code 
ablegen.

von Stefan F. (Gast)


Lesenswert?

Mit eurer Hilfe konnte ich letztendlich die USB-Serial Implementierung 
von W.S. auf den Nachfolger des Blue-Pill Boardes (mit STM32F303CC) 
portieren.

Board: http://stefanfrings.de/stm32/stm32f3.html#stm32f3mini
USB Code: http://stefanfrings.de/stm32/stm32f3.html#vcpnohal

Besten Dank nochmal.

von Stefan F. (Gast)


Lesenswert?

Ich habe Antwort von AC6 bekommen. Sie können das Problem reproduzieren, 
sind allerdings unsicher, ob das ein Bug oder eine Notwendigkeit ist.

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.