Forum: Mikrocontroller und Digitale Elektronik UART Clock Initialisierungsproblem auf STM32F407G-DISC1 (Discovery)


von Christoph K. (chriskuku)


Lesenswert?

Ich hatte ja an anderer Stelle erwähnt, daß ich mecrisp-stellaris-forth 
auf ein nucleo-Board erfolgreich geflasht und zum Laufen gebracht habe.

Jetzt habe ich hier noch ein zweites Board, STM32F407G-DISC1, auf dem 
ich ein anderes Programm testen wollte. Dieses Programm benutzt UART3 
(PB11/PB10) auf dem Discoveryboard. Also habe ich den USART umgeschaltet 
auf USART3 in der Source des mecrisp-forth (weil ich die Drähtchen an 
den SMD-Chip nicht wieder umverdrahten wollte). Ich wollte erst mal das 
mecrisp-forth auf dem discovery verifizieren.

Aber komischerweise loopt das mecrisp-forth in der Initialisierungsphase 
in einer Code-Passage (terminal.s im Verzeichnis stm32F407), die so 
aussieht:
1
 -----------------------------------------------------------------------------
2
Setup_Clocks:
3
@ -----------------------------------------------------------------------------
4
        @ Initialize STM32 Clocks
5
6
        @ Ideally, we would just take the defaults to begin with and
7
        @ do nothing.  Because it is possible that HSI is not
8
        @ accurate enough for the serial communication (USART2), we
9
        @ will switch from the internal 8 MHz clock (HSI) to the
10
        @ external 8 MHz clock (HSE).
11
12
        ldr r1, = RCC_CR
13
        mov r0, HSEON
14
        str r0, [r1]            @ turn on the external clock
15
16
awaitHSE:
17
        ldr r0, [r1]
18
        ands r0, #HSERDY
19
        beq.n awaitHSE            @ hang here until external clock is stable

Und zwar kommt es aus der awaitHSE-Loop nicht heraus.

Ich weiß nicht, ob das mit der Clockauswahl wirklich so nötig ist, aber 
der Autor wird sich was dabei gedacht haben und ich will den Code 
eigentlich nicht verändern ohne ihn verstanden zu haben.



Grüße
Christoph

: Bearbeitet durch User
von Christoph K. (chriskuku)


Lesenswert?

Habe festgestellt, daß diese Codepassage nur in der terminal.s für die 
Boards stm32f407 und stm32f429 vorkommt.

Stoppt der gdb eigentlich nach dem Start auf der Reset-Adresse?

$ cat .gdbinit
file firmware.elf
target remote localhost:4242
load firmware.elf


GDB:

#!/bin/sh
/Users/kuku/opt/gcc-arm-none-eabi-8-2018-q4-major/bin/arm-none-eabi-gdb

1
$ ./GDB
2
GNU gdb (GNU Tools for Arm Embedded Processors 8-2018-q4-major) 8.2.50.20181213-git
3
Copyright (C) 2018 Free Software Foundation, Inc.
4
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
5
This is free software: you are free to change and redistribute it.
6
There is NO WARRANTY, to the extent permitted by law.
7
Type "show copying" and "show warranty" for details.
8
This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".
9
Type "show configuration" for configuration details.
10
For bug reporting instructions, please see:
11
<http://www.gnu.org/software/gdb/bugs/>.
12
Find the GDB manual and other documentation resources online at:
13
    <http://www.gnu.org/software/gdb/documentation/>.
14
15
For help, type "help".
16
Type "apropos word" to search for commands related to "word".
17
0x00001582 in serial_qemit ()
18
Loading section .text, size 0x3bc8 lma 0x0
19
Start address 0x0, load size 15304
20
Transfer rate: 122432 bits in <1 sec, 15304 bytes/write.
21
(gdb) 
22
(gdb)

EDIT: irgendwie merkt sich gdb, wo er das letzte Mal gestoppt wurde 
(^C).
Wenn ich ihn dann erneut starte, steht dann da z.B. die Adresse wie oben 
zu sehen:
0x00001582 in serial_qemit ()

: Bearbeitet durch User
von Philip S. (phs)


Angehängte Dateien:

Lesenswert?

Christoph K. schrieb:
> Ich hatte ja an anderer Stelle erwähnt, daß ich mecrisp-stellaris-forth
> auf ein nucleo-Board erfolgreich geflasht und zum Laufen gebracht habe.
>

Abgefahren. Forth ist schon irgendwie Geek-Level 1000 ;-)

> Jetzt habe ich hier noch ein zweites Board, STM32F407G-DISC1, auf dem
> ich ein anderes Programm testen wollte. Dieses Programm benutzt UART3
> (PB11/PB10) auf dem Discoveryboard. Also habe ich den USART umgeschaltet
> auf USART3 in der Source des mecrisp-forth (weil ich die Drähtchen an
> den SMD-Chip nicht wieder umverdrahten wollte). Ich wollte erst mal das
> mecrisp-forth auf dem discovery verifizieren.
>

Wahrscheinlich nur ein Nebenaspekt, aber ich verstehe nicht ganz was Du 
mit "Drähtchen (...) umverdrahten" meinst. Auf dem Discovery Board sind 
doch fast alle unbenutzten I/O Pins nach außen auf die Stiftleiste 
geführt?

Wenn Du das zugehörige STM32F4DIS-BB Extension Board m. RS-232 
Transceiver und 9-pol Buchse verwendest, dann sollte es U(S)ART6 sein.

> Aber komischerweise loopt das mecrisp-forth in der Initialisierungsphase
> in einer Code-Passage (terminal.s im Verzeichnis stm32F407), die so
> aussieht:
>
>
1
>  -----------------------------------------------------------------------------
2
> Setup_Clocks:
3
> @ 
4
> -----------------------------------------------------------------------------
5
>         @ Initialize STM32 Clocks
6
> 
7
>         @ Ideally, we would just take the defaults to begin with and
8
>         @ do nothing.  Because it is possible that HSI is not
9
>         @ accurate enough for the serial communication (USART2), we
10
>         @ will switch from the internal 8 MHz clock (HSI) to the
11
>         @ external 8 MHz clock (HSE).
12
> 
13
>         ldr r1, = RCC_CR
14
>         mov r0, HSEON
15
>         str r0, [r1]            @ turn on the external clock
16
> 
17
> awaitHSE:
18
>         ldr r0, [r1]
19
>         ands r0, #HSERDY
20
>         beq.n awaitHSE            @ hang here until external clock is 
21
> stable
22
> 
23
>
>
> Und zwar kommt es aus der awaitHSE-Loop nicht heraus.
>

Ist das Programm für den STM32F407 geschrieben / kompiliert worden oder 
hast Du eine Version für einen anderen µC der STM32F4 Familie verwendet?

Auf was löst denn das Macro "RCC_CR" auf? Sprich: Welche Adresse steht 
denn schlussendlich in R1? Lt. F407 Datenblatt sollte der RCC im Bereich 
0x4002 3800 - 0x4002 3BFF liegen; das kann aber bei anderen Controllern 
auch unterschiedlich sein.

Das gleiche für die Bits HSEON und HSERDY: Welche Masken stehen da 
tatsächlich? Auch hier kann's mal Unterschiede zw. CPUs der selben 
Familie geben.

Vielleicht kannst Du mit dem Debugger mal die Adresse 0x4002 3800 
auslesen, schauen wie die Bits im Register stehen und das mit dem "CPU 
Reference Manual" des STM32F407 vergleichen.

> Ich weiß nicht, ob das mit der Clockauswahl wirklich so nötig ist, aber
> der Autor wird sich was dabei gedacht haben und ich will den Code
> eigentlich nicht verändern ohne ihn verstanden zu haben.
>

Naja, der Kommentar im Code sagt's ja eigentlich: Anstatt des internen 
soll der externe Oszillator verwendet, da man sich dadurch eine 
präzisere Taktung verspricht. Der UART hängt ja CPU intern auf einem Bus 
(APB1 oder APB2) und muss die APB Bus Clock so unterteilen, dass das 
UART Timing eingehalten wird.

Wahrscheinlich gibt's "in der Nähe" des Snippets auch noch mehr Code, 
der die PLL aufsetzt. Die Zusammenhänge im Clock Setup lassen sich ganz 
gut in STM32CubeMX erfassen; im Anhang mal ein Screenshot der Default 
Konfiguration für das Discovery Board.

Hoffe das hilft Dir weiter.

von Christoph K. (chriskuku)


Angehängte Dateien:

Lesenswert?

Philip S. schrieb:
> Christoph K. schrieb:
>> Ich hatte ja an anderer Stelle erwähnt, daß ich mecrisp-stellaris-forth
>> auf ein nucleo-Board erfolgreich geflasht und zum Laufen gebracht habe.
> ....
> Wahrscheinlich nur ein Nebenaspekt, aber ich verstehe nicht ganz was Du
> mit "Drähtchen (...) umverdrahten" meinst. Auf dem Discovery Board sind
> doch fast alle unbenutzten I/O Pins nach außen auf die Stiftleiste
> geführt?
>

Drähtchen, siehe Anhang (Istzustand bei mir) bzw. Bild im STM32F407 
UM1472 Usermanual.

> Wenn Du das zugehörige STM32F4DIS-BB Extension Board m. RS-232
> Transceiver und 9-pol Buchse verwendest, dann sollte es U(S)ART6 sein.
>

Braucht man sowas, wenn es die USB und virtual COM gibt?


>> Aber komischerweise loopt das mecrisp-forth in der Initialisierungsphase
>> in einer Code-Passage (terminal.s im Verzeichnis stm32F407), die so
>> aussieht:
>>
>>
1
>>  -----------------------------------------------------------------------------
2
>> Setup_Clocks:
3
>> @
4
>> -----------------------------------------------------------------------------
5
>>         @ Initialize STM32 Clocks
6
>>
7
>>         @ Ideally, we would just take the defaults to begin with and
8
>>         @ do nothing.  Because it is possible that HSI is not
9
>>         @ accurate enough for the serial communication (USART2), we
10
>>         @ will switch from the internal 8 MHz clock (HSI) to the
11
>>         @ external 8 MHz clock (HSE).
12
>>
13
>>         ldr r1, = RCC_CR
14
>>         mov r0, HSEON
15
>>         str r0, [r1]            @ turn on the external clock
16
>>
17
>> awaitHSE:
18
>>         ldr r0, [r1]
19
>>         ands r0, #HSERDY
20
>>         beq.n awaitHSE            @ hang here until external clock is
21
>> stable
22
>>
23
>>
>>
>> Und zwar kommt es aus der awaitHSE-Loop nicht heraus.
>>
>
> Ist das Programm für den STM32F407 geschrieben / kompiliert worden oder
> hast Du eine Version für einen anderen µC der STM32F4 Familie verwendet?
>

Ja. Der Autor hat das mecrisp-Forth grob gesagt, auf folgende 
STM32-Plattformen portiert/angepaßt:

stm32f030f4
stm32f030k6
stm32f030r8
stm32f042f6
stm32f051
stm32f072rb
stm32f100
stm32f103
stm32f103rb
stm32f207zg
stm32f303
stm32f303k8
stm32f401
stm32f407
stm32f411
stm32f429
stm32l031k6
stm32l053c8
stm32l073rz
stm32l152
stm32l152rb
stm32l476
stm32wb55

> Auf was löst denn das Macro "RCC_CR" auf? Sprich: Welche Adresse steht

Kein Macro, sondern ein  .EQU:

stm32F407/terminal.s:  .equ RCC_BASE        ,   0x40023800
stm32F407/terminal.s:  .equ RCC_CR          ,   RCC_BASE + 0x00


> denn schlussendlich in R1? Lt. F407 Datenblatt sollte der RCC im Bereich
> 0x4002 3800 - 0x4002 3BFF liegen; das kann aber bei anderen Controllern
> auch unterschiedlich sein.
>
> Das gleiche für die Bits HSEON und HSERDY: Welche Masken stehen da
> tatsächlich? Auch hier kann's mal Unterschiede zw. CPUs der selben
> Familie geben.
>
stm32F407/terminal.s:    .equ HSERDY        ,   BIT17
stm32F407/terminal.s:    .equ HSEON         ,   BIT16
stm32F407/terminal.s:        mov r0, HSEON
stm32F407/terminal.s:        ands r0, #HSERDY

> Vielleicht kannst Du mit dem Debugger mal die Adresse 0x4002 3800
> auslesen, schauen wie die Bits im Register stehen und das mit dem "CPU
> Reference Manual" des STM32F407 vergleichen.
>
>> Ich weiß nicht, ob das mit der Clockauswahl wirklich so nötig ist, aber
>> der Autor wird sich was dabei gedacht haben und ich will den Code
>> eigentlich nicht verändern ohne ihn verstanden zu haben.
>>
>
> Naja, der Kommentar im Code sagt's ja eigentlich: Anstatt des internen
> soll der externe Oszillator verwendet, da man sich dadurch eine
> präzisere Taktung verspricht. Der UART hängt ja CPU intern auf einem Bus
> (APB1 oder APB2) und muss die APB Bus Clock so unterteilen, dass das
> UART Timing eingehalten wird.
>
> Wahrscheinlich gibt's "in der Nähe" des Snippets auch noch mehr Code,
> der die PLL aufsetzt. Die Zusammenhänge im Clock Setup lassen sich ganz
> gut in STM32CubeMX erfassen; im Anhang mal ein Screenshot der Default
> Konfiguration für das Discovery Board.
>
> Hoffe das hilft Dir weiter.

Danke. Ja das Bildchen des Clock-Setups im STM32CubeMX hatte ich schon 
mal gesehen. Danke für die Erinnerung.

: Bearbeitet durch User
von Philip S. (phs)


Lesenswert?

Christoph K. schrieb:
> Drähtchen, siehe Anhang (Istzustand bei mir) bzw. Bild im STM32F407
> UM1472 Usermanual.
>

Danke, wieder was gelernt.

War mir nicht bewusst, dass der ST-Link auf dem Discovery Board 
mittlerweile auch als VCP verwendet werden kann.

>> Wenn Du das zugehörige STM32F4DIS-BB Extension Board m. RS-232
>> Transceiver und 9-pol Buchse verwendest, dann sollte es U(S)ART6 sein.
>>
>
> Braucht man sowas, wenn es die USB und virtual COM gibt?
>

Nein.

>
>>> Aber komischerweise loopt das mecrisp-forth in der Initialisierungsphase
>>> in einer Code-Passage (terminal.s im Verzeichnis stm32F407), die so
>>> aussieht:
>>>
>>>
1
>>>  -----------------------------------------------------------------------------
2
>>> Setup_Clocks:
3
>>> @
4
>>> -----------------------------------------------------------------------------
5
>>>         @ Initialize STM32 Clocks
6
>>>
7
>>>         @ Ideally, we would just take the defaults to begin with and
8
>>>         @ do nothing.  Because it is possible that HSI is not
9
>>>         @ accurate enough for the serial communication (USART2), we
10
>>>         @ will switch from the internal 8 MHz clock (HSI) to the
11
>>>         @ external 8 MHz clock (HSE).
12
>>>
13
>>>         ldr r1, = RCC_CR
14
>>>         mov r0, HSEON
15
>>>         str r0, [r1]            @ turn on the external clock
16
>>>
17
>>> awaitHSE:
18
>>>         ldr r0, [r1]
19
>>>         ands r0, #HSERDY
20
>>>         beq.n awaitHSE            @ hang here until external clock is
21
>>> stable
22
>>>
23
>>>
>>>
>>> Und zwar kommt es aus der awaitHSE-Loop nicht heraus.
>>>

Ich hab' mal spasseshalber den Code bei mir direkt am Reset Handler 
eingefügt; sollten also die ersten Instruktionen sein, die ausgeführt 
werden. Einfach um auszuschließen, dass vorher irgendwas in S/W 
passieren muss, bevor das HSERDY Bit an geht.

Resultat: Bei mir läuft der Code sofort durch.

Ich sehe daher zwei Möglichkeiten: Entweder der ext. Quartz schwingt 
nicht wie er soll oder das Programm macht an anderer Stelle irgendwas, 
was den RCC "verwirrt".

Ich würde mir als nächstes tatsächlich mal den Inhalt des RCC CR 
anschauen, d.h. R0 nachdem "ldr r0, [r1]" ausgeführt wurde.

Tut mir leid, dass ich Dir keinen besseren Tipp geben kann.

Zur Referenz hier was ich bei mir sehe:
1
85    ldr r1, = RCC_CR
2
(gdb) info reg pc
3
pc             0x80052f4           0x80052f4 <Reset_Handler>
4
(gdb) stepi
5
86    mov r0, HSEON
6
(gdb) 
7
87    str r0, [r1]            @ turn on the external clock
8
(gdb) info reg r0 r1
9
r0             0x10000             65536
10
r1             0x40023800          1073887232
11
(gdb) stepi
12
90    ldr r0, [r1]
13
(gdb) 
14
91    ands r0, #HSERDY
15
(gdb) info reg r0 r1
16
r0             0x37503             226563
17
r1             0x40023800          1073887232
18
(gdb)

von Johannes S. (Gast)


Lesenswert?

über (Löt)Jumper kann man ja verschiedene Taktoptionen wählen, wurde da 
evtl. etwas verstellt? Per default sollte ja der 8 MHz Quarz benutzt 
werden, bei den neueren Nucleos hat ST den weggelassen und den 
Hauptprozessor aus dem STLink extern mitgetaktet.
Und Power für den Clock muss auch eingeschaltet sein, habe jetzt nicht 
nachgesehen was da default 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.