ich möchte: einen Timer der per Software gestartet wird und nach Ablauf
einen Interrupt auslöst. Platform ist erstmal ein STM32F407VE board, mit
Mbed OS. Das hat eine Timeout Klasse die so etwas schon macht, ist aber
ineffizient wenn es an die zig kilohertz geht.
Problem: es funktioniert, aber irgendwas ist ungenau. Wenn ich die Zeit
mit dem Systemtimer vergleiche, dann sehe ich einen Offset von +7 µs,
mein Timer scheint irgendwo zu lange zu laufen.
Die HAL Funktionen helfen hier nicht besonders, es gibt einen OnePulse
aber der benutzt compare/capture und ist aufwändiger um per HW
getriggert zu werden. Daher benutze ich nur die init Funktion, die macht
das BaseInit und setzt den OPM-Mode. Dann aktiviere ich den Update
Interrupt und im startHardwareTimeout wird das Reload Register gesetzt
und der Timer gestartet. In der ISR wird nur eine LED getoggelt und der
Timestamp vom Systemtimer geholt. Das ist ein 32 Zähler mit gleicher
Taktquelle und ebenfalls 1 µs Auflösung. Mein Timer ist TIM3, mit 84 MHz
input und per prescaler 83 auf 1 µs heruntergeteilt.
Im main ist ein einfacher Test, Hardwaretimer starten, 1s schlafen
(intern per __WFI) und dann die Differenz der beiden Timer ausgeben.
Bei 168 MHz Systemclock sollte der Interrupt Overhead sehr gering sein,
26 Takte mit FPU wenn ich das richtig verstanden habe. Da sind 7 µs
einfach zu viel, wo können die noch herkommen?
Output vom main:
1 | Hello from STM32F407VE
|
2 | 1 time elapsed: 2007 diff: 7 interrupt count: 1
|
3 | 2 time elapsed: 3340 diff: 7 interrupt count: 2
|
4 | 3 time elapsed: 39 diff: 6 interrupt count: 3
|
5 | 4 time elapsed: 10007 diff: 7 interrupt count: 4
|
6 | 5 time elapsed: 10007 diff: 7 interrupt count: 5
|