Im Moment bin ich unangenehm vom STM32F103 überrascht.
Für bestimmte Projekte (bspw. das Anbinden von parallelen Displays
dessen Anschluesse quer Beet über 3 Ports verteilt sind - nein, das kann
ich nicht ändern, weil das Board vorgegeben ist) möchte ich das
Bitwackeln so schnell als möglich erledigen.
Leider kann ich nicht alle Pins mittels DMA (bspw. über einen SPI)
ansprechen, deshalb: Bitwackeln.
Mein Problem (oder besser mein Ärgernis) ist folgendes:
Coretakt: 72MHz
Library: libopencm3
Während das Setzen und wieder Löschen eines GPIO's bei 160 ns liegt,
benötigt das Löschen und wieder Setzen "satte" 430 ns (was mehr als das
Doppelte ist).
Weshalb ist das so?
Mein Testprogramm ist im Anhang, Systemtimertakt ist ausgeschaltet.
Verrückt ist, dass das bei einem STM32F030 so nicht auftritt, da
benötigt da beträgt das Pause-Puls Verhältnis ca. 220 ns : 220 ns
Selbst bei einem ATmega328p erreiche ich Zeiten um 280 ns (bei 16 MHz
Takt).
Die Fragen also:
Warum sind die Zeiten unterschiedlich ?
Welche Methode kann ich noch verwenden (ausser über BSRR) um evtl.
schnellere Schaltzeiten zu erreichen ?
Gruß,
JJ
Lasse den Code zumindestens im RAM laufen. Oder besser, lade die
Basisadresse des GPIO Block in ein Register und toggle durch setzen der
entsprechenden BSSR Bits mit Codeausfuehrung aus dem RAM
Uwe B. schrieb:> Lasse den Code zumindestens im RAM laufen. Oder besser, lade die> Basisadresse des GPIO Block in ein Register und toggle durch setzen der> entsprechenden BSSR Bits mit Codeausfuehrung aus dem RAM
Puuuuuh... aus dem RAM laufen lassen ... erfordert für mein Setup
grundsätzliche Änderungen (weil bisher nicht vorgesehen und bisher auch
nicht notwendig war).
Okay, wollte ich irgendwann sowieso einmal machen.
Beim Togglen bin ich gerade dabei (allerdings mit Code aus dem Flash)
und das schaut nicht wirklich besser aus.
Kann sein, dass mit der Codeausführung aus dem RAM das besser wird, es
erklärt aber nicht, warum die Pausezeit länger ist.
Ralph S. schrieb:> Welche Methode kann ich noch verwenden (ausser über BSRR) um evtl.> schnellere Schaltzeiten zu erreichen ?
Es ist nicht klar, wie schnell nun die APB2 Clock ist. Zumindest sieht
es so aus, als würdest du die 72MHz gleich wieder durch 8 teilen (als
AHB Clock) und damit auch die APB2 Clock darauf begrenzen. die
verbleibenden 9 Mhz sind dann wirklich langsamer als ein AVR bei 16MHz.
Das muss aber nicht sein, denn die AHB Clock kann ruhig 72Mhz sein und
ebenso APB2. Siehe dazu im RM0008 Reference Manual den Clocktree auf
Seite 90.
Nur APB1 muss per Vorteiler auf 36Mhz und weniger begrenzt werden. Poste
mal dein startup File.
Wenn du dieses
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8);
durch 8 teilen meinst, das geschieht ja nur in
oid systick_setup(void)
und ist in der sys_init auskommentiert und wird nicht aufgerufen (weil
ich ja wirklich alles ausschalten wollte).
Ein herkömmliches Startup-File gibt es bei libopencm3 nicht, es werden
mit vector.c und nvic.c die Interruptvektoren festgelegt.
Takteinstellungen geschehen innerhalb eines Projektes.
Mit dem Einstellen des Taktes wie oben im Anhang (und einem aufgesetzten
UART) zeigt mit das Programm für die Systemeinstellung das hier an:
1
-------------------------------------
2
3
STM32F103 / 72 MHz 19200bd 8N1
4
Januar 2020 R. Seelig
5
6
APB1 = 36 MHz
7
APB2 = 72 MHz
8
AHB = 72 MHz
9
-------------------------------------
(und ich habe was weiß ich wie oft AHB, APB1 und APB2 überprüft). Ein
Indiz dafür, dass das mit voller Geschwindigkeit läuft ist auch, dass
ich wesentlich höhere Taktraten erreiche, wenn ich ein einzelnes Bit
über DMA und SPI befeuere.
Aaaaaber, ich werde mal die HAL installieren und sehen, wie es sich da
verhält (für den Fall, dass im Setup der libopencm3 etwas nicht stimmt).
Ich persönlich weiss jetzt nicht, wie die Funktionien nun ausgeführt
werden, ich kenne das von anderen startup files so, das man direkt
sieht, welche Register mit welchen Werten gefüllt werden, also mit
deutlich weniger Abstraktion als deine Lib.
Allerdings kann es beim Porthandling sinnvoll sein, statt der Shifterei
zum Resetten eines Bits einfach das GPIO->BR Register zu benutzen.
Besser, du suchst mal andere Benutzer der libopencm3, ich bin da erstmal
raus.
Matthias S. schrieb:> Matthias S. schrieb:> GPIO->BR>> Wird auch GPIO->BRR genannt.
Wird doch im Code sogar schon benutzt, in den IOPIN_SET und IOPIN_CLR
Makros.
Stimmt, es ist BSRR und nicht BRR. Der einzige Unterschied ist, dass
0x100 und nicht 0x1 geladen werden muss. Das dürfte
geschwindigkeitstechnisch kein Unterschied sein.
Programmierer schrieb:> Das dürfte> geschwindigkeitstechnisch kein Unterschied sein.
Immerhin muss was gemodelt werden. Wie das gemacht wird, hängt vom
Compiler ab und könnte man im Kompilat mal untersuchen. Da der TE aber
die max. Geschwindigkeit rausholen möchte, sollte man meine Variante
zumindest mal ausprobieren, denn selbst wenn ein schlauer Compiler ein
SWAP oder so benutzt, kostet es Zeit und würde die längere Zeit beim
Resetten erklären (siehe Threadtitel).
Programmierer schrieb:> Stimmt, es ist BSRR und nicht BRR. Der einzige Unterschied ist, dass> 0x100 und nicht 0x1 geladen werden muss. Das dürfte> geschwindigkeitstechnisch kein Unterschied sein.
Klar macht das einen RIESENunterschied. movs geht nur für 8-Bit
Konstanten.
Je nachdem, wie der Compiler das macht (einmal vor der Schleife bei
Konstanten in verschiedene Register laden oder jedesmal die Konstanten
nei laden) ... Ohne Assembler-Output ist das alles Kaffeesatzleserei.
A. B. schrieb:> Klar macht das einen RIESENunterschied. movs geht nur für 8-Bit> Konstanten.
Ja, das andere mov welches 0x100 kann ist eine 32bit Instruktion. Die
braucht aber auch nur 1 Takt.
so, nachdem Karneval vorbei ist, habe ich mich meinem "Problem" wieder
gewidmet und aufgrund eines anderen Threads
Beitrag "STM32F103C8T6 - Fälschung von ST bestätigt"
habe ich mir den Chip angesehen und siehe da, es ist auch einer mit der
Bezeichnung MYS807 und den beiden "zusätzlichen" Vertiefungen.
Danach habe ich mein Testprogramm auf meiner eigenen Platine und einem
Nucleoboard getestet und siehe da:
Die Pausezeit ist nicht mehr heftig länger !!!
Bei den "Erkenntnissen" zur Fälschung wurde auch etwas über den ACK bei
I2C gesagt: Prompt funktionieren meine I2C Routinen auch nicht !
Somit hat sich mein Problem erledigt.
Vielen Dank für die Gedanken aus dem Forum
Matthias S. schrieb:> Um die Veroder- und Verunderei auszuschliessen, kannste auch mal, wie> o.a., die GPIO->BSRR und GPIO->BRR Register schreiben.
Damit erreiche ich Zyklus-Zeiten von ca 55nsec, 25nsec high und
30nsec low (abstrahiert von der zusätzlichen Zeit für die Schleife),
bei einer Optimierungsstufe des Compilers von -O3.
STM Apprentice schrieb:> Damit erreiche ich Zyklus-Zeiten von ca 55nsec, 25nsec high und> 30nsec low (abstrahiert von der zusätzlichen Zeit für die Schleife),> bei einer Optimierungsstufe des Compilers von -O3.
Kann ich bestätigen. Habs grade nochmal getestet und komme ebenfalls auf
etwa 25/30ns.
Matthias S. schrieb:> Das sieht also nach einer zuverlässigen Methode aus, um Fake und> Original zu unterscheiden.
Das geht für mich aus dem Thread nicht hervor. Welche Methode?
Bitte erkläre das genauer.
Ich glaube ehrlich gesagt nicht an diese Fake-Geschichte. Ich vermute
eher, dass der TO den uc falsch programmiert hat.
Wenn er sich nochmal meldet, kann ich ihm ein entsprechendes HEX-File
zukommen lassen. Wenn er ein Bluepill-Board nutzt, kann ich ihm das
geben, was auch ich hier getestet habe. Erst dann lasse ich mich
überzeugen.
Bei Bedarf könnte ich ein Bildchen des Dies machen.
...muss heute diesbezüglich auch noch was hochladen...
Spoiler: Es gibt STM32, die einen CKS32 enthalten. :)
... ich bin m Moment nicht zu Hause. Ob du das mit dem Fake glaubst oder
nicht ist unintetessant. Es ist sogar uninteressant ob ichs falsch
programmiert habe oder nicht.
Interessant isr, dass ich auf einem neueren BluePill Board (welches ein
Testprogramm als Fake ausgewiesen hat) und ein anderes Board (welches
lt. Testprogramm kein Fake ist) mit ein und derselben Firmware
unterschiedliche Laufzeiten generiert.
Das Testprogramm auf Fake oder nicht Fake ist hier zu finden:
Beitrag "Re: STM32F103C8T6 - Fälschung von ST bestätigt"
Wie unterschiedlich sind die Laufzeiten in etwa?
Hier konnte ich ca 15% langsamer für den Fake-Chip ermitteln bei
harmlosen GPIO-Spielchen, also nix mit DMA, ADC oder IRQs
UART zum PC paßte allerdings oder der PC war gutmütig genug das Signal
noch zu akzeptieren.
NichtWichtig schrieb:> Wie unterschiedlich sind die Laufzeiten in etwa?
Ich habe nicht weiter nachgeforscht, nachdem das, was ich machen wollte
auf einem originalen STM lief.
Ich für mich weiß noch nicht, was ich mit den Fake-Chips machen werde.
Die meisten Programme laufen auf den Fake-Chips.
Ich muß nur wissen, dass eben nicht alles auf den Chips läuft.