本文介绍了如何在 Cortex-M4 MCU 上捕获和查看 ITM 跟踪信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

I would like to capture, decode, and view ITM trace information for a Cortex-M4 MCU (in my case, an Atmel SAM4S). In particular, I want to capture exceptions and user trace data relative to other signals on my board (i.e. show all signals and trace information on same timeline).

解决方案

This can be done using the following steps:

  1. Place debugger in SWD mode. If using J-Link Segger on Linux, this can be done with JLinkGDBServer -if swd
  2. Add code to the MCU to enable trace. Set the bit rate to a value suitable for your needs (I used 8 MHz). Example Ada code is below.
  3. Use logic analyzer to capture trace data on TRACESWO line from SAM4S processor. I used a Saleae Logic Pro 16 with 100 MHz sample rate.
  4. Convert the data to a format usable by sigrok. Using the Saleae to capture the data, this comprises the following steps:

    • Capture using only the first 8 channels (so one byte per sample is exported).
    • Export data as binary to trace.bin, writing a byte for every sample.
    • Convert to a trace.sr file using:

      sigrok-cli -i trace.bin -I binary:samplerate=100000000,numchannels=4 -o trace.sr

  5. Open the trace.sr file in PulseView.
  6. Add UART decoder to TRACESWO channel, bit rate 8000000.
  7. Stack ARM-ITM decoder.

See http://www.sigrok.org/blog/new-protocol-decoders-arm-tpiu-itm-etmv3 for more information.

Example Ada code for SAM4S Trace:

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;

这篇关于如何在 Cortex-M4 MCU 上捕获和查看 ITM 跟踪信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 18:59