Saturday, April 21, 2018

Tracing a Bluepill

Did you know the lowly STM32F103C8 has non-invasive trace logic along for the ride? Did you also know that via program control:

1) Trace can be enabled out to a pin on the board (PB3).
2) 32 channels can be used to emit 32, 16 or 8bit (char) values from running code. Useful to monitor values from your code.
3) A cycle count can be emitted
4) Data Watchpoints can also be reported. See a picture below.

Showing SysTick exception handling:

Showing a sensor range value being emitted on channel 16 (that's the max 1FFE in mm's btw)

Showing a watchpoint on the read modify write of the Green LED on PC13 (HW watchpoint on: BSRR @0x40011010).

Also an Overflow is seen (first time I have seen that actually). Can be mitigated by bumping the output rate.

Bluepill shown with a VL53L10X range sensor. The trace is the yellow wire connected to TRACESWO PB3 and green wire is connected to GPIO1 from the sensor. That is plumbed up to go low when a new sample is ready. Based on the range value, the green LED is lit or not. (a version of this is used in my garage to detect if the car is far enough along to close the door w/o striking the rear or the vehicle).


So a board that can cost $1.27 on Taobao has all this and more.

One omission on such an inexpensive design is ETM (Embedded Trace Macrocell). This is featured on many of the larger ST designs. Its easy to check if it exists as the register space at E0041000 will have non-zero contents. On a bluepill, that space is all zero.

No matter, Instruction Trace Macrocell (ITM) is available. This can report the PC of the running program at a sub-sampled rated.

ITM also reports when the code dips into the exception handler as shown above.

Usually though when configured, the diet is a steady stream of PC's.

Some observations of this technology.

1) You need background/sample code. A hackaday post in 2015 on the great work by Petteri Aimonen:
a)  Showing how enable the Trace Port Interface Unit TPIU/ITM and ETM
b) Adding .py scripts to Pulseview to permit GUI viewing of trace output as seen above in the images.
2) ETM, Petteri used an F1 Value Line part per his blog. I had no luck getting ETM data out of that part.

Some observations:1) You must have a debug connection to the target to get SWO to emit trace.
2) It's possible to muck around with rate settings. You can get a rate that is unreal, I had a Bluepill+ with trace @80Mhz coupled with a minimally subdivided PC. You get a firehose of PCs coming out. Perhaps one very 20-30instrs or so. Amazing.
3) My code is a translation of Petteri's C example into Ada.

Using Pulseview

The pretty picture above is done with Petteri's work. You can install Pulseview for Linux or Windows (also you can build the source (as I did to a Raspberry pi3)). The trick to decoding the trace is to have a UART capture of PB3 off of the traceswo port. Get that UART capture into Pulseview. For my path, I use an unsupported logic capture, the Salae logic pro 16. No matter, it exports binary and then its a simple matter to convert it to a .sr file that Pulseview can read:

Hedley@FASTER ~/trace
$ split --numeric-suffixes=1 --suffix-length=1 --bytes=4M untitled.bin logic-1-

Hedley@FASTER ~/trace
$ zip version metadata logic-1-*
updating: version (stored 0%)
updating: metadata (deflated 8%)
updating: logic-1-1 (deflated 97%)
updating: logic-1-2 (deflated 97%)
updating: logic-1-3 (deflated 97%)
updating: logic-1-4 (deflated 97%)
updating: logic-1-5 (deflated 97%)
updating: logic-1-6 (deflated 97%)
updating: logic-1-7 (deflated 100%)
updating: logic-1-8 (deflated 100%)
updating: logic-1-9 (deflated 100%)

Hedley@FASTER ~/trace
$ cat metadata
sigrok version=0.3.0

[device 1]
total probes=8
samplerate=50 MHz

So once in Pulseview we can add a decoder to the UART. Just add ARM ITM and set the baudrate to your capture speed (in my case, 8Mhz). Then let Pulseview's decoder show you the trace. 


No comments:

Post a Comment