2015-07-28 7 views

risposta

6

questo può essere fatto utilizzando la seguente procedura:

  1. Luogo debugger in modalità SWD. Se si utilizza J-Link Segger su Linux, questo può essere fatto con JLinkGDBServer -if swd
  2. Aggiungere codice alla MCU per abilitare la traccia. Imposta la velocità in bit su un valore adatto alle tue esigenze (ho usato 8 MHz). Esempio di codice Ada è sotto.
  3. Utilizzare l'analizzatore logico per acquisire i dati di traccia sulla linea TRACESWO dal processore SAM4S. Ho usato una Saleae Logic Pro 16 con frequenza di campionamento di 100 MHz.
  4. Converti i dati in un formato utilizzabile da sigrok. Utilizzando le Saleae per acquisire i dati, questo comprende i seguenti passaggi:

    • Acquisisci utilizzando solo i primi 8 canali (quindi viene esportato un byte per campione).
    • Esportare i dati come binari su trace.bin, scrivendo un byte per ogni campione.
    • convertirli in un file utilizzando trace.sr:

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

  5. Aprire il file trace.sr in PulseView.
  6. Aggiungi decodificatore UART al canale TRACESWO, bit rate 8000000.
  7. Decodificatore ARM-ITM stack.

Vedere http://www.sigrok.org/blog/new-protocol-decoders-arm-tpiu-itm-etmv3 per ulteriori informazioni.

codice

Esempio Ada per 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; 
5

Come si contrassegnati con "analizzatore logico" , questo potrebbe essere off-topic, ma ho trovato il seguente estremamente utile. Con Keil uVision (e probabilmente anche con altri IDE) è possibile reindirizzare i dati ITM su file utilizzando un file .ini personalizzato.

Abilitare SWJ nel debugger, utilizzare la porta SW. Abilita traccia, abilita le porte di stimolo che si desidera utilizzare.

scrivere un file .ini con un contenuto simile a questo:

ITMLOG 0 > "debug.log" 
ITMLOG 1 > "testlog.xml" 

Questo wil reindirizzare canale ITM 0 in un file denominato "debug.log", e il canale 1 su "testlog.xml" (sintassi dei file da here).

Per utilizzare i canali facilmente con fprinf in te c-codice che utilizzo seguente configurazione:

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); 
} 

e il loro utilizzo nell'ambito del progetto:

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"); 
} 

Riferimento: link

Problemi correlati