Chciałbym przechwytywać, dekodować i wyświetlać informacje śledzenia ITM dla MCU Cortex-M4 (w moim przypadku Atmel SAM4S). W szczególności chcę przechwytywać wyjątki i dane śledzenia użytkownika w stosunku do innych sygnałów na mojej tablicy (tj. Pokazać wszystkie sygnały i informacje śledzenia na tej samej linii czasu).Jak przechwytywać i wyświetlać informacje śledzenia ITM na jednostce MCU Cortex-M4?
Odpowiedz
Można to zrobić za pomocą następujących czynności:
- Place debugera w trybie SWD. Jeśli korzystasz z Segregatora J-Link w systemie Linux, można to zrobić za pomocą
JLinkGDBServer -if swd
- Dodaj kod do MCU, aby włączyć śledzenie. Ustaw szybkość transmisji na wartość odpowiednią do twoich potrzeb (użyłem 8 MHz). Przykładowy kod Ada znajduje się poniżej.
- Użyj analizatora logicznego do przechwytywania danych śledzenia na linii TRACESWO z procesora SAM4S. Użyłem Saleae Logic Pro 16 z częstotliwością próbkowania 100 MHz.
Konwertuj dane do formatu używanego przez sigrok. Używanie Saleae do przechwytywania danych obejmuje następujące kroki:
- Przechwytuj przy użyciu tylko pierwszych 8 kanałów (eksportowany jest więc jeden bajt na próbkę).
- Eksportuj dane jako pliki binarne do
trace.bin
, zapisując bajt dla każdej próbki. Konwersja do pliku trace.sr używając:
sigrok-cli -i trace.bin -I binary:samplerate=100000000,numchannels=4 -o trace.sr
- Otwórz plik w PulseView
trace.sr
. - Dodaj dekoder UART do kanału TRACESWO, przepływność 8000000.
- Dekoder ARM-ITM stosu.
Aby uzyskać więcej informacji, zobacz http://www.sigrok.org/blog/new-protocol-decoders-arm-tpiu-itm-etmv3.
kodPrzykład Ada dla SAM4S Ślad:
sam4s-trace.ads:
with Interfaces;
package SAM4S.Trace is
pragma Preelaborate;
type Channel_Type is new Integer range 0 .. 31;
type Value_Type is new Interfaces.Unsigned_32;
procedure Initialize;
procedure Put (Channel : Channel_Type;
Value : Value_Type);
procedure Put (Channel : Channel_Type;
Message : String);
end SAM4S.Trace;
SAM4S-trace.adb:
with System;
with System.Storage_Elements; use System.Storage_Elements;
package body SAM4S.Trace is
procedure Initialize is
ITM_LAR : Interfaces.Unsigned_32
with Address => System'To_Address (16#E000_0FB0#), Volatile;
ITM_TCR : Interfaces.Unsigned_32
with Address => System'To_Address (16#E000_0E80#), Volatile;
ITM_TER : Interfaces.Unsigned_32
with Address => System'To_Address (16#E000_0E00#), Volatile;
ITM_TPR : Interfaces.Unsigned_32
with Address => System'To_Address (16#E000_0E40#), Volatile;
DEMR : Interfaces.Unsigned_32
with Address => System'To_Address (16#E000_EDFC#), Volatile;
TPIU_SPP : Interfaces.Unsigned_32
with Address => System'To_Address (16#E004_00F0#), Volatile;
TPIU_FFCR : Interfaces.Unsigned_32
with Address => System'To_Address (16#E004_0304#), Volatile;
TPIU_ACPR : Interfaces.Unsigned_32
with Address => System'To_Address (16#E004_0010#), Volatile;
DWT_CTRL : Interfaces.Unsigned_32
with Address => System'To_Address (16#E000_1000#), Volatile;
use Interfaces;
begin
-- Enable write access via the Lock Access Register.
ITM_LAR := 16#C5AC_CE55#;
-- Enable the ITM, enable SWO mode behavior, enable synchronization
-- packets, enable DWT event submission, enable timestamps.
ITM_TCR := 16#0001_001F#;
-- Enable access in user mode to all 32 channels.
ITM_TPR := 16#0000_0000#;
-- Enable all 32 trace channels.
ITM_TER := 16#FFFF_FFFF#;
-- Set TRCENA bit to 1 in Debug Exception and Monitor Register.
DEMR := DEMR or 16#0100_0000#;
-- Select NRZ serial wire output.
TPIU_SPP := 16#0000_0002#;
-- Deactivate formatter.
TPIU_FFCR := 16#0000_0100#;
-- Set prescalar (/10).
-- TPIU_ACPR := 16#0000_0009#;
-- Set prescalar (/15).
TPIU_ACPR := 14;
-- Enable exception trace and exception overhead.
DWT_CTRL := DWT_CTRL or 16#0005_0000#;
end Initialize;
procedure Put (Channel : Channel_Type;
Value : Value_Type) is
Port_Reg : Value_Type with Address => System'To_Address (16#E000_0000#) +
4 * Channel_Type'Pos (Channel), Volatile;
begin
-- Port register lsb is set when the the FIFO can accept at least one
-- word.
while Port_Reg = 0 loop
null;
end loop;
Port_Reg := Value;
end Put;
procedure Put (Channel : Channel_Type;
Message : String) is
Port_Reg : Value_Type with Address => System'To_Address (16#E000_0000#) +
4 * Channel_Type'Pos (Channel), Volatile;
begin
-- Port register lsb is set when the the FIFO can accept at least one
-- word.
for Index in Message'Range loop
while Port_Reg = 0 loop
null;
end loop;
Port_Reg := Value_Type (Character'Pos (Message (Index)));
end loop;
end Put;
end SAM4S.Trace;
Jak określili to "analizatora logicznego" może to być nie na temat, ale uważam, że poniższe bardzo pomocne. Z Keil uVision (i prawdopodobnie także z innymi IDE) możesz przekierować dane ITM do pliku przy użyciu niestandardowego pliku .ini.
Włącz SWJ w debugerze, użyj portu SW. Włącz śledzenie, włącz porty bodźców, których chcesz użyć.
Napisz ini plik o zawartości takich jak to:
ITMLOG 0 > "debug.log"
ITMLOG 1 > "testlog.xml"
wil Ten kanał 0 ITM przekierować do pliku o nazwie "debug.log" i kanału 1 na "testlog.xml" (składni pliku od here).
Aby łatwo wykorzystywać kanały z fprinf w was C-kod za pomocą następujących ustawień:
struct __FILE { int channel; };
#include <stdio.h>
#define ITM_Port8(n) (*((volatile unsigned char *)(0xE0000000+4*n)))
#define ITM_Port16(n) (*((volatile unsigned short*)(0xE0000000+4*n)))
#define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*n)))
#define DEMCR (*((volatile unsigned long *)(0xE000EDFC)))
#define TRCENA 0x01000000
int fputc(int ch, FILE *f) {
if (DEMCR & TRCENA) {
while (ITM_Port32(f->channel) == 0);
ITM_Port8(f->channel) = ch;
}
return(ch);
}
i użytkowania w ramach projektu:
FILE debug_stream = { .channel = 0 };
FILE test_stream = { .channel = 1 };
int main(void) {
fprinf(&debug_stream, "this is a debug message, it will be rerouted to debug.log");
fprinf(&test_stream, "this is a test message, it will be placed in testlog.xml");
}
referencyjny: link
- 1. Dane śledzenia zdarzeń - jak długo należy wyświetlać?
- 2. Jak wyświetlać informacje za pomocą R-screen?
- 3. Jak mogę przechwytywać dane wyjściowe i wyświetlać je w tym samym czasie w Pythonie?
- 4. Informacje dotyczące śledzenia stosu wydruku z C#
- 5. cURL: Jak wyświetlać informacje o postępie podczas przesyłania?
- 6. Jaka jest logika systemów śledzenia i śledzenia?
- 7. Hibernacja: wiele filtrów na jednostce
- 8. projekt open source o implementacji MCU WebRTC na serwerze
- 9. Jak przechwytywać formularz niezawodnie?
- 10. Jak wyświetlać MKOverlay na MKMapView
- 11. Jak przechwytywać ludzki podpis
- 12. Jak przechwytywać zdarzenia przewijania?
- 13. Jak wyświetlać/wyświetlać błędy krytyczne w przeglądarce na HHVM
- 14. Jak przechwytywać aktywność przeglądarki?
- 15. Jak mogę wyświetlać funkcje lambda na śladach wstecz?
- 16. Jak przechwytywać ruch w pythonie
- 17. Jak przechwytywać ramki sieciowe w module jądra
- 18. Jak przechwytywać zdarzenie zamknięcia przeglądarki?
- 19. Jak przekazywać informacje z serwletu na stronę JSP?
- 20. OpenCV: Jak przechwytywać ramki z kamery Ethernet
- 21. Obraz szynowy i ochrona śledzenia
- 22. Jak wyświetlać alert na Apple Watch
- 23. Jak wyświetlać treści HTML na UIWebView IOS
- 24. Implementacja śledzenia wstecznego na Haskell
- 25. Jak zdefiniować element rozszerzenia na jednostce miary F #?
- 26. HashSet w jednostce testuje
- 27. MacOSX: jak przechwytywać zdarzenia sieciowe? Lub: jak działa Private-Eye?
- 28. Jak wyświetlać współrzędne i używać ginput
- 29. Jak wyświetlać wyskakujące okienka na Emacs?
- 30. Jak wyświetlać obowiązkowe pola na formularzu okna?