Electronics > Microcontrollers

ST 32F4xx debugging

(1/6) > >>

peter-h:
I am working on a project using the Cube IDE and the ST-Link isolated adaptor.

It all works fine but I have some fairly basic questions which the docs I have read don't address. Well, they contain huge complicated explanations which make sense only if you already know the environment.

Various different breakpoints can be set - Regular / Temporary / Hardware / Hardware Temporary.

From my embedded days (decades of it, Z80 etc era) breakpoints are either implemented on the CPU, with a breakpoint address register, or in software by replacing (or inserting) a bit of the code with a jump. On this chip the code runs out of FLASH so the only way to do the latter is to recompile the program each time there is any change of breakpoints, and the Debug As function does indeed seem to do this. Of course none of the old chips had hardware breakpoints. Actually there were even ways to single step through ROM code, by copying the ROM code to RAM a piece at a time and setting a breakpoint in RAM, and then copying over some more...

Now these breakpoints obviously slow down the code running, once they are hit. And since you are then single stepping, of course the program stops :) There is no real time trace, like one used to have on the in circut emulators of many years ago.

So what is the difference with a "hardware" breakpoint? It may run faster IF there is an associated skip count but does the 32F400 support a hardware skip counter? If not, what is the difference?

A skip counter which runs at full CPU speed, or something anywhere near close, could be useful. But one can attach expressions to breakpoints and obviously they can't be implemented on-chip. Where are they evaluated? For single stepping it doesn't matter because the program is not running at any speed anyway, but it could be handy if one could skip a breakpoint until say i=20, and do this at a fair speed.

In this thread
https://www.eevblog.com/forum/microcontrollers/st-32f4xx-spi-weird-behaviour-with-multiple-slaves-and-clock-polarity-phase/new/#new
it was suggested that the Segger adaptor is much better than ST-Link but apart from their eye watering pricing I find it hard to work out if there is anything useful there. Can anyone give concrete example? I wonder if this is related to my questions above.

newbrain:

--- Quote from: peter-h on March 05, 2021, 04:22:55 pm ---From my embedded days (decades of it, Z80 etc era) breakpoints are either implemented on the CPU, with a breakpoint address register, or in software by replacing (or inserting) a bit of the code with a jump. On this chip the code runs out of FLASH so the only way to do the latter is to recompile the program each time there is any change of breakpoints, and the Debug As function does indeed seem to do this. Of course none of the old chips had hardware breakpoints.

--- End quote ---
In general, there's no need to recompile anything to change/add/remove breakpoints.
It's probably an artefact of Eclipse bone-headedness, if you inhibit flashing (in one of the eleventythousand panels and dialogs) you'll see that your breakpoints still work as expected.

Arm MCUS have a variable number of HW breakpoints and watchpoints, e.g. the STM32F4xx, as most Cortex-M4s, has 6 breakpoints and 4 watchpoints.

The debugger SW (say, gdb) will communicate with the probe through a debug server (can be skipped for some type of probes, e.g. Blackmagic), which will talk to the probe.
The probe, through its SWD or JTAG interface, will  set the internal comparator registers of the Flash Patch and Breakpoint Unit (FPB) for breakpoints or the Data Watchpoint and Trace Unit for watchpoints (they can do more than watch and break points, but let's keep it to the basics).

Look at what happens when setting more than the HW provides (this is an STM32L476, also with 6 HW breakpoints and 4 watchpoints):

--- Code: ---C:\Users\newbrain> pyocd cmd --target stm32l476rgtx
Connected to STM32L476RGTx [Running]: 0674FF535752877167093659
pyocd> break 0x80000C0
Set breakpoint at 0x080000c0
pyocd> break 0x80001C0
Set breakpoint at 0x080001c0
pyocd> break 0x80002C0
Set breakpoint at 0x080002c0
pyocd> break 0x80003C0
Set breakpoint at 0x080003c0
pyocd> break 0x80004C0
Set breakpoint at 0x080004c0
pyocd> break 0x80005C0
Set breakpoint at 0x080005c0
pyocd> break 0x80006C0
Failed to set breakpoint at 0x080006c0
pyocd>
pyocd> watch 0x20000000
Set watchpoint at 0x20000000
pyocd> watch 0x20000080
Set watchpoint at 0x20000080
pyocd> watch 0x20000100
Set watchpoint at 0x20000100
pyocd> watch 0x20000140
Set watchpoint at 0x20000140
pyocd> watch 0x20000190
0100032:ERROR:dwt:No more watchpoints are available, dropped watchpoint at 0x20000190
Failed to set watchpoint at 0x20000190
pyocd>

--- End code ---

For breakpoints, when the address programmed in a comparator register is hit by the PC, the processor stops.
As communications on the SWD interface can only be initiated by the probe, it's its task to poll the debug registers to understand when the the breakpoint has been hit.

Hard breakpoints are useful for code running in flash, while soft breakpoints (= replace an instruction with the BKPT op code, as you mentioned) can be used in RAM.
Temporary breakpoints are simply breakpoints that the debugger SW will cancel once hit, and it's still a function of the debugger SW to take care of complex breakpoints with hit counter or a guard expression.

Arm processors offer also advanced tracing support, in the form of the ETM and ITM for more complex debugging.

peter-h:
Thanks for your explanation and the links. Interesting indeed. The 32F can feed a BRK opcode to the CPU when it gets an address match, which is damn clever because it enables "software" breakpoints in FLASH.

Both "standard" and "hardware" breakpoints offer the option of a condition and a count



Based on what I read and what you say, that the debugger should be able to reprogram the breakpoints dynamically via Jtag. And you are quite right; it can. One can add and delete breakpoints and just run it (with F8 etc). It is only the Debug (F11) or Debug As... functions which do a Make.

peter-h:
It appears that the main thing you get on the expensive Stegger debuggers is the dynamic flash patching, which enables unlimited breakpoints with code running in flash
http://www.segger.com/products/debug-probes/j-link/technology/flash-breakpoints/

Their top model has a 64MB trace buffer. Does anyone know the performance hit when using this feature? Clearly it is not an old-style ICE (zero perf hit); it must be setting breakpoints, and processing the data, as fast as it can.

Siwastaja:
Those are like sports cars, they are entertainment devices.

A professional drives a normal reliable car; or mostly uses other strategies than advanced debugging probes. 99% of the work with MCUs does not involve using a debugger of any kind. Remaining 1% does not require specialized high-end features, 6 breakpoints is more than fine, and it's completely irrelevant whether adding a breakpoint takes a millisecond or a second. Even having to add BKPT in your code and reflash isn't a real problem, if you find it slows your workflow down the solution is to fix the workflow.

Of course you can always use a golden hammer decorated with diamonds, to drive a screw.

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version