cancel
Showing results for 
Search instead for 
Did you mean: 

Use STM32H7 ETM without debugging tool

Gpeti
Senior II

I need to use the ETM on a STM32H753 but without debugging tool. The idea is to record the execution trace all the time, and when the firmware encounter a critiical issue, output the trace to an external tool or program it to flash for later analysis. It is designed to work in operational mode, not through a debugging tool.

The documentation of ARM is very confusing on the topic. Some documents mentions the ETB (Embedded Trace Buffer) other documents mentions the ETF (Embedded Trace FIFO) but I couldn't really understand which is doing what.

I don't really understand what functionality of the STM32 to use to implement what I need, and also how to do it. Strangely enough, I didn't find any code example of discussion about this online. it's surprising because recording execution trace sounds like a very interesting functionality in safety critical environments in particular.

24 REPLIES 24

Tends to be the domain of debugger writers, ARM should have app notes, but presupposes familiarity with HW/SW at this level.

http://infocenter.arm.com/help/topic/com.arm.doc.ddi0242b/DDI0242.pdf

Others on the forum have built trace HW, so might have some specific insight.

@Bob Boys​ any thoughts on the internal mechanics ARM can share?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Gpeti
Senior II

Thank you Clive. So I've read again the related section in the ref Manual. What I deduced is that ARM provides several ways to store the execution trace and among them ST chose to implement the ETF.

This ETF can be setup in Circular Mode, which looks like the mode I need:

"3. Circular buffer mode

The trace memory is used as a circular buffer. Trace data is captured into the Trace

memory starting from the location pointed to by the write pointer register. Even when

the trace memory is full, incoming trace data continues to be overwritten into the trace

memory until a stop condition occurs.

In this mode, the ETF stores the trace data on-chip, so the trace log size is limited to

that of the ETF SRAM, 4 Kbytes in this case. Being a circular buffer, if the FIFO

becomes full, incoming trace data overwrites the oldest stored data and the oldest

stored data is lost. Therefore the contents of the trace buffer represent the most recent

activity of the processor, up to the point when the buffer was stopped, rather than all

the activity since the trace was started.

There are three possible methods to read out the buffer contents once the trace stops:

– via the Trace port - with the TPIU enabled, the contents of the buffer are output

over the Trace port. This can be done by setting the DRAINBUF bit in the

ETF_FFCR register.

– via the Debug port - the debugger can read the buffer via the RRD register that is

accessible over the system APB-D.

– by software - the processor can read the buffer via the RRD register, since the

APB-D is accessible from the system bus."

The reference manual also gives the description of the ETF registers. I will try to implement the functionality based on this but I find the documentation ia bit "light" to do so without wasting days. So I would still appreciate tips, code examples or application notes.

Like I said, I think ARM has app notes it shares with debugger developers. You might find reference to them via open source debugger projects, things like Open OCD spring to mind. ARM's forums may be a better place to ask, and might have debugger specific sub-forums.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

These have been suggested, perhaps a bit heavy going

http://infocenter.arm.com/help/topic/com.arm.doc.ddi0494d/DDI0494D_coresight_etm_m7_r0p1_trm.pdf

http://static.docs.arm.com/ihi0064/d/IHI0064D_etm_v4_architecture_spec.pdf

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

The "Debug Infrastructure" has some coverage here

https://www.st.com/content/ccc/resource/technical/document/reference_manual/group0/82/40/1a/07/c9/16/40/35/DM00176879/files/DM00176879.pdf/jcr:content/translations/en.DM00176879.pdf

Likely has material that "ARM® Cortex®-M7 Integration and Implementation Manual" would have, but you don't qualify to access (not a licensor of chip IP).

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Gpeti
Senior II

So I've based my implementation on two documents, the section on ETF in STMicro STM32 reference manual and ARM's Trace Memory Controller Reference Manual. In the latter in particular there is a sequence to setup the ETF:

Circular Buffer mode

The recommended standard usage model in this mode is as follows:

1. Wait until TMCReady is equal to one.

2. Program the MODE Register for Circular Buffer mode.

3. Program the FFCR Register. ARM recommends that you set the TrigOnTrigIn,

FOnTrigEvt, StopOnFl, EnTI, and EnFt bits. This enables formatting, inserting a trigger

when a trigger is observed on TRIGIN, and following a delay corresponding to the value

of the TRG Register, flushing and then stopping the TMC.

4. Program the TRG Register, to control the amount of buffer to be dedicated to the period

after a trigger is observed.

5. Set the TraceCaptEn bit in the CTL Register. This starts the trace session.

6. Wait until TMCReady is equal to one. This indicates that the trace session is over.

7. Read the contents of the trace buffer by performing successive reads to the RRD Register,

until the value 0xFFFFFFFF is returned.

8. Clear the TraceCaptEn bit in the CTL Register.

The notion of triggers is more or less incomprehensible so I've stupidly written the registers as described without really understanding what's going on.

But actually I can't go very far in my debug: it looks like the ETF registers are not accessible (they're all read to 0 either through the debugger or through my embedded software). There is probably an "enable" bit somewhere to activate or clock the TMC or ETM or ETF or who knows what macrocell.

Here is the piece of quick and dirty code I tried, every register is read to 0 and not modified by this code

HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART3_UART_Init();
 
// enable ETM trace
*ETM_PRGCTRL = 1;
 
// enable ETF circular mode
*ETF_FFCR = 0x00001123; // ARM recommends to set bits TRIGONTRIGIN FONTRIGEVT STOPONFL ENTI AND ENFT
*ETF_TRG = 16; // number of 32 words to capture
*ETF_CTL = 1; // enable trace
  
i = 1000;
while(i--)
  asm("nop"); // ******** processing just to fill the trace
 
while ( ((*ETF_STS) & (1<<2)) == 0 );
 
printf("*ETF_RRD=0x%x\r\n", *ETF_RRD);
printf("*ETF_RRD=0x%x\r\n", *ETF_RRD);
printf("*ETF_RRD=0x%x\r\n", *ETF_RRD);
printf("*ETF_RRD=0x%x\r\n", *ETF_RRD);
 
*ETF_CTL = 0; // disable trace

I'd expect you'd need to unlock each unit via it's LAR (Lock Access Register) on CM7 chips.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Indeed ! There is an ETM_LAR and an ETF_LAR, i've just found it. So now I can write in ETM registers but not in ETF :(

To be continued 🙂

Gpeti
Senior II

I've found this comment on the Segger forum:

"(...) unfortunately ST made the decision with the STM32H7 to "hide" some trace related modules behind the APB instead of AHB as it is usual for Cortex-M7. That way the generic trace init process becomes highly ungeneric."

ST people, could you comment on that ?