Atollic TRUEStudio STM32 – jak zacząć? [2]
W drugiej części artykułu na temat pakietu TrueSTUDIO (pierwsza jest dostępna pod adresem) skupimy się na omówieniu debugowania pracy programu.
Debugowanie
Debugowanie programu w TrueSTUDIO jest bardzo istotnym elementem pracy nad projektem. Żeby było możliwe to potrzebny jest odpowiedni program uruchomiony na komputerze i współpracujący z nim sprzętowy połączony zazwyczaj interfejsem USB układ debugera sprzężony z układami programatora/debugera z mikrokontrolerze.
Debuger pakietu TrueSTUDIO jest oparty o standard GDB (GNU debugger). Serwer GDB łączy środowisko graficzne TrueSTUDIO ze sprzętowym debugerem przez interfejs USB – rysunek 15.
Rys. 15. Idea działania debuggera Atollic TrueSTUDIO
Przykładowy program
Proces debugowania pokażemy na prostym przykładzie. Szkielet programu wygenerowany przez kreatora projektu uzupełnimy o prostą funkcjonalność polegającą na cyklicznym zapalaniu i gaszeniu diody LED2 zabudowanej w module NUCLEO-F401 RE. Dioda jest połączona anodą z linią portu PORTA5 (PA5). Żeby sterowanie linią portu było możliwe to trzeba wykonać kilka prostych czynności konfiguracyjnych:
- Włączyć taktowanie modułu portów
- Ustawić kierunek linii PA5 jako wyjściową
- Ustawić typ portu jako push-pull
- Określić maksymalną częstotliwość pracy portu
Konfiguracja portu i nieskończona pętla, w której jest cyklicznie zmieniany stan linii GPA5 zostały pokazane na listingu 1.
List. 1. Konfiguracja linii PA5 i pętla cyklicznego sterowania diodą LED2
int main(void) { /* TODO - Add your application code here */ //struktura konfiguracji portów GPIO_InitTypeDef GPIOInit; //wypełnienie struktury konfiguracji portów GPIOInit.GPIO_Pin =GPIO_Pin_5; //linia GPIOA_5 GPIOInit.GPIO_Mode= GPIO_Mode_OUT; //wyjściowa GPIOInit.GPIO_OType= GPIO_OType_PP; //push-pull GPIOInit.GPIO_PuPd= GPIO_PuPd_NOPULL; //bez podciągania GPIOInit.GPIO_Speed = GPIO_Speed_50MHz; //max.czestotliwosc pracy portow //inicjalizacja systemu (rdzen, taktowanie itd) SystemInit(); wykonywana w startup przed funkcją main() //wlaczenie taktowania modulu portow GPIOA RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //inicjalizacja linii GPIOA_5 GPIO_Init(GPIOA, &GPIOInit); /* Infinite loop */ while (1) { //stan wysoki na linii GPIO_5 - LED2 zapaloana GPIO_SetBits(GPIOA, GPIO_Pin_5); //opoznienie Delay(2000000); //stan niski na linii GPIO_5 - LED2 zgaszona GPIO_ResetBits(GPIOA, GPIO_Pin_5); //opoznienie Delay(2000000); } }
List. 2. Programowe opóźnienie
void Delay(uint32_t del) { uint32_t del1, i; for(i=0; i<del; i++) { for(del1=0; del1<10000;del1++) del1=del; } }
Przed uruchomieniem sesji debugowania trzeba podłączyć moduł NUCLEO–F401RE do portu USB komputera na którym jest uruchomiony Atollic TrueSTUDIO.
Testowy projekt trzeba skompilować z opcją kompilacji Debug ustawiana w opcjach kompilatora – rysunek 16.
Rys. 16. Opcja kompilacji Debug
Początek sesji
Sesję debugowania uruchamia się klikając na ikonę Debug umieszczona w pasku narzędziowym – rysunek 17.
Rys. 17. Uruchomienie sesji debugowania
Przy pierwszym uruchomieniu sesji pojawi się okno konfiguracji, w którym najważniejsza jest zakładka Debugger – rysunek 18. Dla modułu Nucleo trzeba wybrać ST-LINK i interfejs SWD. Konfigurowanie debugowania jest dość rozbudowane i dokładnie opisane w dokumentacji TrueSTUDIO. My skorzystamy z domyślnych ustawień oferowanych przez program.
Rys. 18. Konfiguracja debugera
Po kliknięciu na Debug uruchomi się sesja debugowania z automatycznie otwieraną perspektywą Debug. Łączy się to z automatycznym załadowaniem pliku wynikowego kompilacji do pamięci mikrokontrolera. W pasku narzędziowym umieszczono podstawowe ikony wykorzystywane w pracy z debugerem. – rysunek 19.
Na początku wskaźnik ustawia się na pierwszą instrukcję funkcji main(). Kliknięcie na ikonę „Start Programu” program zaczyna się wykonywać do momentu kliknięcia na „zatrzymanie wykonywania programu”, lub do natrafienia na ustawiony punkt zatrzymań Breakpoint. Kolejne instrukcje w języku C są wykonywane po każdym kliknięciu na ikonę „praca krokowa” (alternatywnie klawisz F5).
Rys. 19. Podstawowe komendy debuggera
W domyślnych ustawieniach perspektywy Debug otwiera się okno z zakładkami, w których umieszczono:
- Punkty zatrzymań – Breakpoints
- Podgląd zmiennych globalnych – Variables
- Podgląd zmiennych Expressions i Live Expressions
Na rysunku 20 pokazano podgląd w oknie Variables struktury konfiguracyjnej GPIOInit po krokowym wykonaniu instrukcji zapisywania jej składowych z funkcji main().
Rys. 20. Podgląd struktury konfiguracyjnej GPIOInit w oknie Variables
Punkty zatrzymań można ustawiać w bardzo wygodny sposób przez klikanie obok instrukcji w oknie z wykonywanym plikiem źródłowym. Na rysunku 21 pokazano ustawienie punktu zatrzymania na linii 85 w pliku źródłowym main.c oraz okno z zakładka Breakpoints.
Rys. 21. Ustawianie punktów zatrzymań i zarządzanie nimi w zakładce Breakpoints
W czasie wykonywania programu można też podglądać wykonywanie kodu w asemblerze. Okno Disassembly otwiera się po kliknięciu na ikonkę Podgląd instrukcji asemblera (rysunek 22).
Rys. 22. Podgląd wykonywanego kodu w asemblerze
Tomasz Jabłoński