Witam.
Dla ćwiczebności napisałem sobie funkcję zwracającą ilość cykli zegara w celu pomiaru długości wykonywania funkcji itp.
Aby to osiągnąć odczytuję "PENDSTSET" oraz stan licznika SysTick. Jednak pomiędzy tymi dwoma odczytami upływa trochę czasu i wartość licznika jestem w stanie skorygować znając czas jaki upłynął miedzy tymi dwoma instrukcjami oraz stan licznika ms wiedząc czy miała nastąpić aktualizacja czy też nie. Wszystko to oczywiści w sekcji krytycznej bo wywołanie przerwania zaburzy w sposób znaczący pomiar.
Moje pytanie więc brzmi: czy wykonując 2 instrukcję ldr jedna po drugiej mogę mieć pewność, że zostaną one wykonane zawsze w tym samym czasie?
Przy okazji miałbym także kilka innych pytań:
- Czy aby mieć pewność, że flaga PENDSTSET jest aktualna muszę wcześniej wykonać dsb,isb? Albo czy w ogóle istnieje ryzyko, że ta flaga wystąpi z pewnym opóźnieniem?
- flaga PENDSTSET zapala się w momencie kiedy licznik dojdzie do 0 czy zaraz potem?
- jak we wstawkach mogę bezpośrednio wykorzystywać rejestry np jako tymczasowa zmienna ale tak aby nie nadpisać jakiegoś rejestru i żeby nie musieć deklarować zmiennej poza wstawka (w moim przykładzie jest to "priMsk")? W momencie kiedy zamiast %[priMsk] użyję np R5 to zostaje on potem nadpisany przez pbrOut który także jest zapisywany w R5, czyli kompilator w żaden sposób nie widzi tego, że we wstawce mogło dojść do nadpisania jakiś danych jeśli nie zadeklaruję wcześniej jakiejś zmiennej.
Jest to moja pierwsza wstawka asm oraz przy okazji pisania tej funkcji dowiedziałem się, że CORTEX nie koniecznie wykonuje czynności w spodziewanej kolejności czy w spodziewany sposób, przekonałem się o tym dobitnie po kilku dniach nieustającej próby napisania tego w c/c++ bez podglądu na wygenerowany kod (tzn algorytm działał jednak występowały jittery nie spowodowane przerwaniami a przewidywanie stanu licznika zależało od ustawionego stopnia optymalizacji kompilatora oraz sposobu wykorzystania funkcji)
W chwili obecnej funkcja wydaję się już działać poprawnie, wolę jednak rozwiać wszelkie wątpliwości szczególnie jeśli chodzi o pierwsze pytanie
Moja platforma to "BluePill" STM32F103C
Arduino IDE + biblioteki STM https://github.com/rogerclarkmelbourne/Arduino_STM32
Kod wygenerowany po kompilacji:
Dla ćwiczebności napisałem sobie funkcję zwracającą ilość cykli zegara w celu pomiaru długości wykonywania funkcji itp.
Aby to osiągnąć odczytuję "PENDSTSET" oraz stan licznika SysTick. Jednak pomiędzy tymi dwoma odczytami upływa trochę czasu i wartość licznika jestem w stanie skorygować znając czas jaki upłynął miedzy tymi dwoma instrukcjami oraz stan licznika ms wiedząc czy miała nastąpić aktualizacja czy też nie. Wszystko to oczywiści w sekcji krytycznej bo wywołanie przerwania zaburzy w sposób znaczący pomiar.
Moje pytanie więc brzmi: czy wykonując 2 instrukcję ldr jedna po drugiej mogę mieć pewność, że zostaną one wykonane zawsze w tym samym czasie?
Przy okazji miałbym także kilka innych pytań:
- Czy aby mieć pewność, że flaga PENDSTSET jest aktualna muszę wcześniej wykonać dsb,isb? Albo czy w ogóle istnieje ryzyko, że ta flaga wystąpi z pewnym opóźnieniem?
- flaga PENDSTSET zapala się w momencie kiedy licznik dojdzie do 0 czy zaraz potem?
- jak we wstawkach mogę bezpośrednio wykorzystywać rejestry np jako tymczasowa zmienna ale tak aby nie nadpisać jakiegoś rejestru i żeby nie musieć deklarować zmiennej poza wstawka (w moim przykładzie jest to "priMsk")? W momencie kiedy zamiast %[priMsk] użyję np R5 to zostaje on potem nadpisany przez pbrOut który także jest zapisywany w R5, czyli kompilator w żaden sposób nie widzi tego, że we wstawce mogło dojść do nadpisania jakiś danych jeśli nie zadeklaruję wcześniej jakiejś zmiennej.
Jest to moja pierwsza wstawka asm oraz przy okazji pisania tej funkcji dowiedziałem się, że CORTEX nie koniecznie wykonuje czynności w spodziewanej kolejności czy w spodziewany sposób, przekonałem się o tym dobitnie po kilku dniach nieustającej próby napisania tego w c/c++ bez podglądu na wygenerowany kod (tzn algorytm działał jednak występowały jittery nie spowodowane przerwaniami a przewidywanie stanu licznika zależało od ustawionego stopnia optymalizacji kompilatora oraz sposobu wykorzystania funkcji)
W chwili obecnej funkcja wydaję się już działać poprawnie, wolę jednak rozwiać wszelkie wątpliwości szczególnie jeśli chodzi o pierwsze pytanie
REKLAMA
Moja platforma to "BluePill" STM32F103C
Arduino IDE + biblioteki STM https://github.com/rogerclarkmelbourne/Arduino_STM32
Kod: C / C++
Kod wygenerowany po kompilacji:
...
800215e: 4a26 ldr r2, [pc, #152] ; (80021f8 <_Z4loopv+0x9c>)
8002160: 4926 ldr r1, [pc, #152] ; (80021fc <_Z4loopv+0xa0>)
8002162: f3ef 8010 mrs r0, PRIMASK
8002166: b672 cpsid i
8002168: 680d ldr r5, [r1, #0]
800216a: 6813 ldr r3, [r2, #0]
800216c: f380 8810 msr PRIMASK, r0
...