2019-10-07 02:25 AM
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.
2019-10-09 04:05 AM
The multicore nature of the H7 was not disclosed for many years, this adds to the complexity significantly and explains some of the awkwardness in the design/structure. I suspect ARM and ST experimented with some things.
I wouldn't expect ST engineers familar with internals at this level to wade into open forum discussions.
2019-10-09 04:50 AM
In which way is the H7 multicore ?
2019-10-09 05:36 AM
"I wouldn't expect ST engineers familar with internals at this level to wade into open forum discussions." I can understand that. But on the other hand I'm just trying to use a functionality that they sell on their product.
2019-10-09 05:37 AM
An interesting point to note: the ID registers of ETM can be read properly from the debugger (even without unlocking ETM_LAR). The ID registers of ETF are read to 0...
2019-10-09 06:02 AM
Great ! Just noticed that the STM32H7 ref manual is inconsistent on debug mappings !
2019-10-09 06:49 AM
So if I use the address 0x5C014000 I can at least read/write ETF registers properly.
2019-10-14 10:01 AM
Hello
Sorry to take so long to reply to this - it was Arm TechCon show time last week.
The best way to do this is to access the circular RAM and read it with your software.
This way you do not need external hardware to read the 4 bit + clk signals of the TracePort output.
This method has the advantage to track the instructions no matter how fast your CPU is running.
There are CoreSight registers you need to configure to get trace data stored in this buffer.
I believe the trace data is comprised of the program flow changes, not each individual instruction executred. You, like the debbugger, must reconstruct the executed instruction details. The timestamps are not output with every instruction - I am not sure of the rule used here.
A good way to see how the ETM trace works is to use Keil uVision (free eval version will work) and a ULINKpro (US$ 1,250).
Good luck !
Bob Boys
Arm
*******************************************************************
See RM0433 (Rev6), page 3104:
https://www.st.com/content/ccc/resource/technical/document/reference_manual/group0/c9/a3/76/fa/55/46/45/fa/DM00314099/files/DM00314099.pdf/jcr:content/translations/en.DM00314099.pdf
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.
2019-10-14 12:03 PM
It has always been a multi-core design, it goes a long way to explaining why it is otherwise significantly more complex/convoluted in design compared to the F7, and why most of the resources are a bus ride away from where you would normally put them. It uses a SWD protocol capable of talking to multiple access ports.
2019-10-14 12:16 PM
If you're familiar with Python, this project can be useful: https://github.com/cortexm/pyswd
-- pa
2019-10-14 11:42 PM
Thank you for your answer. I don't understand how buying a $1000 device will help me to understand how the ETF/DWT/ETM registers need to be programmed, as their programming by the ULINKPRo and Keil will be hidden and anyway different than what I need to do (since ULINK uses the Trace pins).
Here is the status of my work on the topic.
I configure the ETF as follows:
*ETF_LAR = 0xC5ACCE55;
*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
Then the ETM:
*ETM_LAR = 0xC5ACCE55;
*ETM_CONFIG = (*ETM_CONFIG) | 0x00031F30;
*ETM_PRGCTRL = 1;
What is missing is (from what I've been told by a specialist in ARM architectures) to setup the DWT to trigger the trace. This is where it is still confusing as no ARM documents explain clearly the link between DWT and ETM. I understood that DWT uses signals CMPMATCH[N] to signal a match to the ETM (??).
I tried to setup DWT comparator 0 to accept all flash memory accesses like that:
*DWT_COMP0 = 0x08000000; // start fo flash address
*DWT_MASK0 = 24; // ignore 24 least significant bits
*DWT_FUNCT0 = 0x00000008; // b1000 ETM trigger on PC match
It's not working : the bit READY of EFT_STS remains at 0 and the bit EMPTY of same register remains at 1.
However the bit MATCH of DWT_FUNCTION0 is set, meaning that the comparator has matched once
I really feel like I'm playing riddles...
Cheers