Choć duże pokrycie kodu testami jednostkowymi powinno zminimalizować prawdopodobieństwo pojawienia się błędów, czasami i tak, konieczne jest przedebugowanie się przez kod. W takich sytuacjach, oprócz breakpoint’ów, pomocnym narzędziem może okazać się „wyrzucenie”, w określonych punktach programu, danych na „konsolę”. Na desktopie nie ma z tym problemu. Co jednak, jeżeli debugujemy firmware na docelowym sprzęcie?
Standard SWD
SWD, czyli Serial Wire Debug, to protokół umożliwiający programowanie i debugowanie mikrokontrolerów z rdzeniami ARM (jak się można domyśleć, stworzony przez firmę ARM). Do poprawnej pracy wymaga obsługi zaledwie dwóch pinów:
- SWDIO (Serial Wire Data Input Output): linia danych,
- SWCLK (Serial Wire Clock): linia zegarowa.
Aby móc skorzystać z dodatkowej opcji jaką jest możliwość „wyrzucenia” danych na „konsolę” (debug (printf) viewer) przy pomocy funkcji printf(), należy wykorzystać jeszcze:
- SWO (Serial Wire Output): w założeniach jest to linia jednokierunkowa, więc nie ma możliwości przesyłania danych do procesora.
printf() w Keil
- W oknie Options for target, w zakładce Debug
- Zaznacz Use (w moim przypadku) ST-Link Debugger i kliknij Settings,
- W oknie Target Driver Setup, w zakładce Trace:
- Zaznacz Trace Enable,
- Ustaw Core Clock na częstotliwość z jaką będzie pracował układ docelowy,
- W oknie Menage Run-Time Enviroment zaznacz Compiler::I/O::STDOUT->ITM (redefiniuje funkcję fputc() ze standardowej biblioteki stdio.h tak aby podczas debugowania printf() przekazywał ciągi znaków do View->serial Windows-> debug (printf) viewer),
- Sprawdź konfigurację zawartą w startup_stm32fxxxx.s. Plik służy między innymi do ustawienia rozmiaru sterty używanej przez funkcje alokacji pamięci (ponieważ printf() używa dynamicznego przydziału pamięci rozmiar sterty nie może być równy 0) ,
- Załącz do projektu „stdio.h” i ciesz się „konsolą”.
#include "stdio.h"
int main(void) {
int j = 0;
int i =0;
while (1) {
j++;
if (j==1000000) {
j = 0;
if (i==0xFFFF) i = 0;
printf("%d\r\n", i);
i++;
}
}
}