Per default ist uwTick eine 32bit variable?!? Mit 1ms tick time wird diese zwangsläufig nach 49.7 Tagen überlaufen. Im HAL sehe ich keine Vorkehrungen diesbezüglich (z.b. in der HAL delay funktion).
Folgende Fragen:
WTF ST?!?
Giebts irgendwo eine Einstellung, dass diese per default als 64bit variable ausgeführt wird?
Falls dies nicht möglich:
3. Wenn ich HAL_IncTick sowie HAL_GetTick im usercode überschreibe, was muss ich alles beachten, damits weiterhin kompatibel ist mit dem HAL?
4. Wie kann ich sicherstellen, dass das HAL nicht nach 49.7 Tagen crasht?
Wieso “crasht” der deiner Meinung nach?
Solange Du keine Zeitspannen größer als 49 Tage messen willst ist das ja kein Problem. Solange Du den alten Vergleichswert im gleichen UINT32 speicherst kannst Du die ohne weiteres voneinander abziehen. Kannst ja mal zwei UINT32 definieren und 0x00000010-0xFFFFFFF0 ausrechnen lassen.
Giebts irgendwo eine Einstellung, dass diese per default als 64bit
variable ausgeführt wird?
WTF? Die 64 Bit laufen auch irgendwann über. Damit verschiebst du das Problem nur auf später (ja ich weiß, bis dahin sind wir eh alle tot). Außerdem sind dann alle Zugriffe nicht mehr Atomar, brauchen also zusätzlich Semaphoren. Bei so kleinen Intervallen ist das keine gute Idee. Der Mikrocontroller soll schließlich noch etwas anderes machen können, als nur Millisekunden zu zählen.
Es handelt sich hier um ms.
Wenn es zum Überlauf kommt, einfach einen Rundenzähler bei Bedarf erhöhen.
Das reicht dann bis zur Ewigkeit und darüber hinaus. :)
Vielleicht so? Dann scheint es zu funktionieren. Wir nehmen mal an, dass der Zähler nur 3 Bit breit ist und dass die Subtraktion intern als Addition mit dem negativen Wert ausgeführt wird.
zum Beispiel 2 minus 1:
2 ist 010;
das Komplement von 1 ist 110, plus 1 ergibt 111;
010 plus 111 ergibt 1001, das wird bei 3 Bit abgeschnitten, ergibt 001
1
angenommen, start ist 011, das Komplement davon 100, plus 1 macht 101.
2
Zähler -start Zähler+(-start) 3 Bit
3
100 101 1001 001 // 4 - 3 = 1
4
101 101 1010 010
5
110 101 1011 011
6
111 101 1100 100 // 7 - 3 = 4
7
000 101 101 101 // 0 - 3 = 5
8
001 101 110 110 // 1 - 3 = 6
Aber auf einem Cortex-M4 ist nicht einmal ein 32-Zähler garantiert atomar, wenn nämlich die Variable nicht word aligned ist. Oder ist sie das immer? Ehrlich? Umgekehrt kann auch ein 64-Bit Zähler funktionieren, wenn man zum Lesen LDRD nimmt und die Timer-Interupt-Routine nicht unterbrochen werden kann. Oder?
Umgekehrt kann auch ein 64-Bit Zähler funktionieren,
wenn man zum Lesen LDRD nimmt und die Timer-Interupt-Routine nicht
unterbrochen werden kann. Oder?
Es geht nicht nur um die Timer ISR, sondern um die Konsumenten des Zählerstandes. Da musst du immer mit Unterbrechungen rechnen, es sei denn, du blockierst sie absichtlich.
Umgekehrt kann auch ein 64-Bit Zähler funktionieren,
wenn man zum Lesen LDRD nimmt und die Timer-Interupt-Routine nicht
unterbrochen werden kann. Oder?
Es geht nicht nur um die Timer ISR, sondern um die Konsumenten des
Zählerstandes. Da musst du immer mit Unterbrechungen rechnen, es sei
denn, du blockierst sie absichtlich.
Ja, genau. Der LDRD Befehl kann unterbrochen werden, aber er wird danach neu gestartet. Ob sich der Zählerstand während der Unterbrechung ändert, ist egal. Erst wenn beide Hälften des 64-Bit-Zähler geladen wurden, kann der Konsument weiter laufen. Oder wie soll ich das Handbuch¹ verstehen:
1
A3.5.3 Atomicity in the ARM architecture
2
In ARMv7-M, the single-copy atomic processor accesses are:
3
• All byte accesses.
4
• All halfword accesses to halfword-aligned locations.
Per default ist uwTick eine 32bit variable?!? Mit 1ms tick time wird
diese zwangsläufig nach 49.7 Tagen überlaufen. Im HAL sehe ich keine
Vorkehrungen diesbezüglich
Ich werde dich bei passender Gelegenheit deswegen mal gebührend bedauern.
Aber wozu so eine blöde Überlegung?
Normalerweise sollte man für eine Anwendung auch die Funktionalität (die man sich SELBER erarbeitet) planen. Und wenn du Verzögerungszeiten von 50 Tagen oder mehr benötigst, dann brauchst du ganz gewiß nicht die Auflösung in Millisekunden.
Ganz generell: einfach nur stur zu brüllen "ich brauche mehr Bitbreite" ist das Gegenteil von klugem Programmieren. Jede Variable, die nicht unendlich viele Bit breit ist, läuft irgendwann mal über. Und der Ansatz "wenn's nur weit genug von jetzt ist, dann ist's mir egal - nach mir die Sintflut" mag praktikabel sein, ist aber im Kern unschön.
Ich habe sowas anders gelöst, hab das auch hier mal gepostet, falls du Bedarf haben solltest, dann suche einfach danach.
der Ansatz
"wenn's nur weit genug von jetzt ist, dann ist's mir egal - nach mir die
Sintflut" mag praktikabel sein, ist aber im Kern unschön.
Ich erinnere nur an den Jahr 2000 Bug. Das nächste Problem steht bereits für Januar 2038 an, weil dann die 32 Bit Systemzeit (in Sekunden seit 1.1.1970) überläuft.
Wer damals "Nach mir die Sinntflut" dachte, den hasse ich jetzt schon dafür.