Gast
#4447474
Ich hatte die IRMP Software für die mbed Bibliothek angepasst. Auf einem LPC1347 und 4088 funktioniert das auch gut, dann wollte ich das auch auf einem STM32F1 testen. Das Ergebnis war negativ obwohl ich ja nur Basisfunktionen benutze. Bei der Fehlersuche bin ich auf einen bekannten Issue gestossen: In IRMP wird mit 15 kHz die Samplingroutine aufgerufen und das geht in mbed einfach mit einem 'Ticker' Objekt. Da fügt man mit attach_us(&prog, period) eine Funktion einer Liste hinzu die dann mit period_time [µs] aufgerufen wird. Der Listenteil ist quasi 'HighLevel' und für alle MCUs gleich. Die Implentierung des Timer/Interrupthandlings ist LowLevel und dann MCU abhängig. Die LPC haben 32 Bit Timer und da ist der LowLevel Teil recht einfach und performant, beim STM32F1 wird ein 16 Bit Timer benutzt und über einen 'SlaveCounter' auf 32 Bit erweitert. Hier liegt mMn der Knackpunkt, das ist nicht richtig Interruptfest. Nach einigen 100 ms bis s (abhängig von der Periodenzeit) entstehen 65 ms Pausen in denen der Ticker hängt. Gefühlsmässig würde ich sagen das ist sehr schwer bis unmöglich sauber in Software zu lösen, falls doch, wie? Oder kann man beim STM32F1 Timer kaskadieren um einen echten 32 Bit Zähler zu erhalten? Ich habe schon lange in dem Code herumgestochert, falls da jemand mit reinsehen möchte ist hier die Funktion wie ich sie interpretiere: - in us_ticker.c ist in us_ticker_read() das Aulesen des Timers und erweitern auf 32 Bit. Wenn hier ein 16 Bit Überlauf passiert wird (soll) die Inkosistenz abgefangen. in us_ticker_set_interrupt(timestamp_t timestamp) wird die neue CompareMatch Zeit berechnet und gesetzt. Dazu wird das Delta zur aktuellen Zeit berechnet und kontrolliert ob das noch innerhalb des Timerüberlaufs passiert. Wenn die Zeit > 65ms ist wird in oc_int_part n*65 ms gesetzt. - in hal_tick.c ist die TimerInit und IRQ. Bei Timerüberlauf wird der Slave inkrementiert. Bei Compare Match wird der User-IRQ aufgerufen wenn keine n * 65 ms zu warten ist, sonst wird die restliche Wartezeit berechnet und gesetzt. Die eigentlich Rechnerei sieht ok aus, nur wenn der Timer kurz vor dem Überlaufen ist klappt das mit dem SlaveCounter scheinbar nicht. us_ticker_c: https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F1/us_ticker.c hal_tick.c: https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/hal_tick.c das gemeldete Issue: https://github.com/mbedmicro/mbed/issues/816 im Anhang sieht man die 65 ms Aussetzer im Ausgangssignal. Mein Beispielprogramm sieht so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
Ich weiss das ist nicht alles einfach nachzuvollziehen, aber die Zahl der STM32 Experten wächst hier ja.
