ARM, SWD, printf() i Keil uVision

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:

  1. SWDIO (Serial Wire Data Input Output): linia danych,
  2. 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:

  1. 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

  1. W oknie Options for target, w zakładce Debug
    • Zaznacz Use (w moim przypadku) ST-Link Debugger i kliknij Settings,
  2. 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,
  1. 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),
  1. 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) ,
  2. 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++;
		}
	}
}

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *