
#004 - FreeRTOS - template dla STM32L4 #2 - SEGGER System viewer
Co to SEGGER System Viewer?
Jest to prosty tool do “tracingu” - czyli możemy podejrzeć eventy w naszej aplikacji. Dla mnie podstawowym wykorzystaniem jest podgląd na zajętość CPU, podgląd na wywłaszczanie się tasków w RTOSie - co za tym idzie podgląd na ich czasy wykonywania.
Oczywiście to narzędzie nie jest dedykowane tylko do aplikacji opartych o jakiś RTOS - do “baremetalowych” także możemy to wykorzystać - SEGGER udostępnia bardzo dobrą dokumentację jak używać ich biliotek.
W dalszej części tekstu zamiast nazwy SEGGER SystemViewer używam skrótu SSV.
Przykład użycia tego programu można też znaleźć we wpisie numer 002.
Konfiguracja
Jak skonfigurować SSV do działania w STMkach? Zademonstruję na przykładzie projektu z wpisu o uruchomieniu FreeRTOSa na nucleo L4.
W internecie dostępna jest ogólna instrukcja do tego pod tym linkiem: link na oficjalnej stronie.
Jak uruchomić SSV:
- uruchamiamy stronę z plikami do pobrania: https://www.segger.com/downloads/systemview/
- pobieramy/instalujemy aplikację - aktualnie to wersja 3.10
- pobieramy źródła do projektu - oznaczone jako “Target Source”
- oczywiście pobieramy też dokumentacje
- struktura pobranego archiwum jest bardzo prosta:
Katalogi to:
- “SEGGER” jest to katalog z źródłami do umieszczenia jako katalog ze źródłami, ale do includów też go trzeba podciągnąć ze względu na główny plik “.h”.
- “Config” jest “per aplikacja” - do umieszczenia w sekcji plików konfiguracyjnych naszego projektu.
- “Sample” zawierają dodatkowe pliki “per RTOS”, lub też “NoOS” na przykładzie FreeRTOSV10
znajdziemy tam:
- “Config” - z dodatkowym plikiem konfiguracyjnym do przeklejenia jak wcześniejsze Configi
- 2 pliki “luzem” do dorzucenia do źródeł
- Katalog z Patchem - jest to zestaw modyfikacji, które trzeba wprowadzić do określonego RTOS-a, można to łatwo zrobić z terminala - o tym w osobnym wpisie
W rezultacie otrzymamy taką strukturę plików:
Widzimy też co będzie problemem po kompilacji - error: conflicting types for ‘_write_r’ - aktualnie poradźmy sobie z tym w ten sposób, że dopasujmy typ w pliku od SEGGER’a aby się zgadzał z bibliotecznymi.
Po tej zmianie projekt się kompiluje - musimy uruchomić teraz wszystko w mainie przez wywołaniem OSa:
SEGGER_SYSVIEW_Conf();
SEGGER_SYSVIEW_Start();
xTaskCreate( vTask1, "Task1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
xTaskCreate( vTask2, "Task2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
xTaskCreate( vTask3, "Task3", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
vTaskStartScheduler();
Zerknijmy jeszcze do ciała funkcji “SEGGER_SYSVIEW_Conf()” - w “_cbSendSystemDesc” możemy dodawać wektory przerwań i będą też wyświetlone w aplikacji z podpisem.
Po wgraniu nie wszystko zadziała - musimy “zaaplikować” patcha - jest to modyfikacja FreeRTOSa udostępniona przez SEGGERa, w projekcie do pobrania gotowa wersja, a więcej o patchach w innym wpisie.
Potem na końcu pliku FreeRTOSConfig.h dodajemy: #include “SEGGER_SYSVIEW_FreeRTOS.h” - bez tego nie zobaczymy taskow, jedynie moment inicjalizacji rzeczy RTOSowych.
Dalej w tym samym pliku (FreeRTOSConfig.h) dodajemy:
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_pxTaskGetStackStart 1
Na tym etapie wszystko powinno działać, aczkolwiek w runtime pojawił się problem z zablokowaniem pracy mikrokontrolera przez funkcję uruchamiającą SSV - fix na to można znaleźć tutaj: fix na forum. Dla lepszej demonstracji działania dodałem “dummy” delaye do tasków z poprzedniego projektu, tak aby działały blokująco i symulowały ważne/długie operacje:
void dummyDelay(void)
{
for(volatile uint32_t i = 0; i < 0xffff; i++)
{
i++;
}
}
void vTask1( void * pvParameters )
{
for (;;)
{
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
dummyDelay();
vTaskDelay(100);
}
}
void vTask2( void * pvParameters )
{
for (;;)
{
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
dummyDelay();
vTaskDelay(150);
}
}
void vTask3( void * pvParameters )
{
for (;;)
{
HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin);
dummyDelay();
vTaskDelay(160);
}
}
Możemy uruchomić aplikację SSV. Jeśli przy uruchomieniu dostaniemy error “Target DLL …JLink_x64.dll not found !” to musimy dograć pakiet tooli do J-Linka ze strony SEGGERa - jest to tzw “J-Link Software and Documentation Pack”.
Po połączeniu widoczny jest taki efekt:
Tu zbliżenie na sytuację gdy wszystkie 3 taski chcą uzyskać dostęp do rdzenia i wykorzystywany jest mechanizm roud robin:
Tracowanie aplikacji - niekoniecznie z użyciem tej apki może często “uratować dupe”, ale nie traktujmy tego jako narzędzie, które zastąpi wszystkie inne - jest to kolejny młotek do skrzynki narzędziowej.
Jeszcze na szybko przyszedł mi jeszcze jeden pomysł na fajne “demo” - ustawmy 2 taski na taki sam priorytet i jeden na wyższy - więc powinien on przerwać pozostałe, a tamte 2 gdyby uruchomiły się jednocześnie - powinien zadziałać RoundRobin. I tak to wygląda:
I to widać w pierwszym zaznaczeniu. W drugim mamy sytuacje, że task 1 i 2 zaznaczone są do uruchomienia, ale czekają z powodu taska numer 3 o wyższym priorytecie.
Projekt do pobrania tutaj: pobierz projekt.