EmbeddedRelated.com
Forums

Micro Trace Buffer (MTB) in Cortex-M0+ (e.g. LPC812)

Started by capiman26061973 March 13, 2013
Hello,

just want to point you to a nice new feature in Cortex-M0+
(like LPC812):

Micro Trace Buffer (MTB)

MTB is a trace mechanism. Once enabled it collects
addresses e.g. of jumps in a configured area in SRAM.
(ring buffer)
It can be enabled/disabled via software (or SWD i think)
and can be read out afterwards.

Example use case:
Trace execution of your code
and dump latest executed code when hardfault handler
is called.
Details: Start tracing at startup, stop it in hardfault handler
and dump the addresses comparable like a call stack.

Description in user manual of LPC812 is almost not available,
but at least it mentions the feature and address ranges,
registers and memory areas are not described in much detail.
(at least in current version of user manual).

But with an example on KEIL website

http://www.keil.com/support/man/docs/ulink2/ulink2_mkl25z12_mtb.htm
(example there is not for LPC812!)

and a PDF from ARM website

http://infocenter.arm.com/help/topic/com.arm.doc.ddi0486b/DDI0486B_coresight_mtb_m0p_r0p1_trm.pdf

or look here (HTML version of above PDF)

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0486b/CHDBHCJC.html

one get it running.

What is needed to get it running:

A trace buffer (size is configurable but must fit registers):

unsigned char MyTraceArea[1024 + 8];
(must be aligned, 8 is only a quick hack)

Activation/start tracing
(based on KEIL website, but modified for LPC812):

{
unsigned long position;
unsigned long master;
unsigned long watermark;
unsigned long _flow;

master = 0x80000005;
position = ((unsigned long)&MyTraceArea) + 8;
_flow = 0x00000000;

position &= 0xFFFFFFF8; // Mask POSITION.POINTER field
watermark = position + ((16 << (master & 0x1F)) - 32);
_flow |= watermark;

*(uint32_t *)0x14000004 = 0x00000000; // MASTER
*(uint32_t *)0x14000000 = position; // POSITION
*(uint32_t *)0x14000008 = _flow;
*(uint32_t *)0x14000004 = master;

LPC_SYSCON->EXTTRACECMD = (1 << 0);
}

Deactivation/stop tracing:

LPC_SYSCON->EXTTRACECMD = (1 << 1);
*(uint32_t *)0x14000004 = 0x00000000; // MASTER

Now you can dump traced addresses:
they are located in MyTraceArea
*(uint32_t *)0x14000000 // Register POSITION
point to next entry which would have been written
each entry is 2 * 4 Bytes
(2 addresses: "to" address, "from" address),

No SWD (debugger) connection is needed to use MTB,
but of course you are then forced to lookup addresses
in mapfile manually. Perhaps useful when customer
reports a crash and you want to get more details,
why and where it crashed.

I hope this posting saves you time
and makes your software development a bit easier.

Best regards,

Martin

An Engineer's Guide to the LPC2100 Series

I've just started using the MTB stuff in NXPs lpcxpresso product. It shows a disassembly of the trace code and links to source, so you can see how your code executed. Pretty neat.
--- In l..., "capiman26061973" wrote:
>
> Hello,
>
> just want to point you to a nice new feature in Cortex-M0+
> (like LPC812):
>
> Micro Trace Buffer (MTB)
>
> MTB is a trace mechanism. Once enabled it collects
> addresses e.g. of jumps in a configured area in SRAM.
> (ring buffer)
> It can be enabled/disabled via software (or SWD i think)
> and can be read out afterwards.
>
> Example use case:
> Trace execution of your code
> and dump latest executed code when hardfault handler
> is called.
> Details: Start tracing at startup, stop it in hardfault handler
> and dump the addresses comparable like a call stack.
>
> Description in user manual of LPC812 is almost not available,
> but at least it mentions the feature and address ranges,
> registers and memory areas are not described in much detail.
> (at least in current version of user manual).
>
> But with an example on KEIL website
>
> http://www.keil.com/support/man/docs/ulink2/ulink2_mkl25z12_mtb.htm
> (example there is not for LPC812!)
>
> and a PDF from ARM website
>
> http://infocenter.arm.com/help/topic/com.arm.doc.ddi0486b/DDI0486B_coresight_mtb_m0p_r0p1_trm.pdf
>
> or look here (HTML version of above PDF)
>
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0486b/CHDBHCJC.html
>
> one get it running.
>
> What is needed to get it running:
>
> A trace buffer (size is configurable but must fit registers):
>
> unsigned char MyTraceArea[1024 + 8];
> (must be aligned, 8 is only a quick hack)
>
> Activation/start tracing
> (based on KEIL website, but modified for LPC812):
>
> {
> unsigned long position;
> unsigned long master;
> unsigned long watermark;
> unsigned long _flow;
>
> master = 0x80000005;
> position = ((unsigned long)&MyTraceArea) + 8;
> _flow = 0x00000000;
>
> position &= 0xFFFFFFF8; // Mask POSITION.POINTER field
> watermark = position + ((16 << (master & 0x1F)) - 32);
> _flow |= watermark;
>
> *(uint32_t *)0x14000004 = 0x00000000; // MASTER
> *(uint32_t *)0x14000000 = position; // POSITION
> *(uint32_t *)0x14000008 = _flow;
> *(uint32_t *)0x14000004 = master;
>
> LPC_SYSCON->EXTTRACECMD = (1 << 0);
> }
>
> Deactivation/stop tracing:
>
> LPC_SYSCON->EXTTRACECMD = (1 << 1);
> *(uint32_t *)0x14000004 = 0x00000000; // MASTER
>
> Now you can dump traced addresses:
> they are located in MyTraceArea
> *(uint32_t *)0x14000000 // Register POSITION
> point to next entry which would have been written
> each entry is 2 * 4 Bytes
> (2 addresses: "to" address, "from" address),
>
> No SWD (debugger) connection is needed to use MTB,
> but of course you are then forced to lookup addresses
> in mapfile manually. Perhaps useful when customer
> reports a crash and you want to get more details,
> why and where it crashed.
>
> I hope this posting saves you time
> and makes your software development a bit easier.
>
> Best regards,
>
> Martin
>

Hi,
There is already an Application Note (from Keil) for MTB on the LPC800.

See the following link:

http://www.lpcware.com/content/nxpfile/lpc800-lpcxpresso-board-various-keil-examples-incld-mtb

Cheers,
Ken

--- In l..., "capiman26061973" wrote:
>
> Hello,
>
> just want to point you to a nice new feature in Cortex-M0+
> (like LPC812):
>
> Micro Trace Buffer (MTB)
>
> MTB is a trace mechanism. Once enabled it collects
> addresses e.g. of jumps in a configured area in SRAM.
> (ring buffer)
> It can be enabled/disabled via software (or SWD i think)
> and can be read out afterwards.
>
> Example use case:
> Trace execution of your code
> and dump latest executed code when hardfault handler
> is called.
> Details: Start tracing at startup, stop it in hardfault handler
> and dump the addresses comparable like a call stack.
>
> Description in user manual of LPC812 is almost not available,
> but at least it mentions the feature and address ranges,
> registers and memory areas are not described in much detail.
> (at least in current version of user manual).
>
> But with an example on KEIL website
>
> http://www.keil.com/support/man/docs/ulink2/ulink2_mkl25z12_mtb.htm
> (example there is not for LPC812!)
>
> and a PDF from ARM website
>
> http://infocenter.arm.com/help/topic/com.arm.doc.ddi0486b/DDI0486B_coresight_mtb_m0p_r0p1_trm.pdf
>
> or look here (HTML version of above PDF)
>
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0486b/CHDBHCJC.html
>
> one get it running.
>
> What is needed to get it running:
>
> A trace buffer (size is configurable but must fit registers):
>
> unsigned char MyTraceArea[1024 + 8];
> (must be aligned, 8 is only a quick hack)
>
> Activation/start tracing
> (based on KEIL website, but modified for LPC812):
>
> {
> unsigned long position;
> unsigned long master;
> unsigned long watermark;
> unsigned long _flow;
>
> master = 0x80000005;
> position = ((unsigned long)&MyTraceArea) + 8;
> _flow = 0x00000000;
>
> position &= 0xFFFFFFF8; // Mask POSITION.POINTER field
> watermark = position + ((16 << (master & 0x1F)) - 32);
> _flow |= watermark;
>
> *(uint32_t *)0x14000004 = 0x00000000; // MASTER
> *(uint32_t *)0x14000000 = position; // POSITION
> *(uint32_t *)0x14000008 = _flow;
> *(uint32_t *)0x14000004 = master;
>
> LPC_SYSCON->EXTTRACECMD = (1 << 0);
> }
>
> Deactivation/stop tracing:
>
> LPC_SYSCON->EXTTRACECMD = (1 << 1);
> *(uint32_t *)0x14000004 = 0x00000000; // MASTER
>
> Now you can dump traced addresses:
> they are located in MyTraceArea
> *(uint32_t *)0x14000000 // Register POSITION
> point to next entry which would have been written
> each entry is 2 * 4 Bytes
> (2 addresses: "to" address, "from" address),
>
> No SWD (debugger) connection is needed to use MTB,
> but of course you are then forced to lookup addresses
> in mapfile manually. Perhaps useful when customer
> reports a crash and you want to get more details,
> why and where it crashed.
>
> I hope this posting saves you time
> and makes your software development a bit easier.
>
> Best regards,
>
> Martin
>