stm32-rs / stm32h7xx-hal

Peripheral access API for STM32H7 series microcontrollers
BSD Zero Clause License
227 stars 104 forks source link

Examples use ITM #7

Closed richardeoin closed 4 years ago

richardeoin commented 5 years ago

May cause a hang when running examples, if debugger is removed or mis-configured.

Feature gating ITM usage is a possible solution.

hargoniX commented 5 years ago

Another option would be to add a .gdbinit file which automatically sets up itm for us like the stm32f1xx-hal does it.

hargoniX commented 5 years ago

Also I'm currently struggling to set up ITM for my chip, I'm running the blinky example and it works just fine (the blinky part) however I'm not able to receive any ITM output, I'm currently running

monitor tpiu config internal itm.fifo uart off 64000000

and then itmdumping itm.fifo, but it's just empty.

richardeoin commented 5 years ago

automatically sets up itm for us like the stm32f1xx-hal does it.

I'd rather not assume everyone is using OpenOCD for programming. There's ST-LINK and several other options. But a .gdbinit with commented out examples for popular programmers would be excellent.

then itmdumping itm.fifo, but it's just empty.

I've never tried OpenOCD with the H7. You might want to check that OpenOCD is setting up the SWTF correctly.

jordens commented 5 years ago

You need to set up SWO and SWTF explicitly. The way openocd sets up the TPIU doesn't seem to apply IIRC. I had gotten it to work once but I can't find the code anymore.

hargoniX commented 5 years ago

So I've you're not using openocd on the h7 how else are you debugging it? @richardeoin

richardeoin commented 5 years ago

I'm using a blackmagic probe at the moment. @hargoniX

hargoniX commented 5 years ago

So, I'd be up for the feature gating thing, would that be a feature gate which allows optional semihosting vs itm or something different? Because if we can't output anything at all, examples like the ADC ones wouldnt make a whole lot of sense.

jordens commented 5 years ago

Note to self: old patch playing with itm on stm32h7 and openocd with a st-link is here: https://gist.github.com/jordens/7cdf6748573088cf1cd7cd2ae35e3fae

astraw commented 4 years ago

I recently got a Black Magic Probe 2.1 and I'm trying to get ITM going - so far without success - on my nucleo-h743zi2 board with h743 revision V. The BMP seems to work for flashing and general debugging (although with occasional glitches). Based on the above comments, I understand that I need to set SWO and SWTF explicitly, but I have not been able to do that. In the gist, I see GDB commands like set *0x5C004FB0 = 0xC5ACCE55, which I gather poke the correct values in. When I run that, however, GDB prints Attempt to take contents of a non-pointer value.. I am using gdb-multiarch as packaged in ubuntu 18.04 and BMP firmware nightly (rev c3a3f77). Instead of poking the memory values with GDB, I could also try to set this in my code. Any examples of doing this with our stack here in rust? The examples I have seen online are in C.

richardeoin commented 4 years ago

Yes ITM isn't the simplest thing to get working, especially with the SWO and SWTF both needing to be configured. Poking the right registers from the debugger is especially brittle, so currently I prefer the option of setting it during init. Here's a gist for that.

astraw commented 4 years ago

Thanks very much! That seems to get me most of the way there. I am using bmp_traceswo to print the ITM output and it is printing data, albeit almost exclusively "bad packets". For example, I modified blinky_random.rs to include your gist (commenting out setting the dbgsleep_d2 bit, which I think is not present on the h743) and start main() so:

#[entry]
fn main() -> ! {
    let cp = cortex_m::Peripherals::take().unwrap();
    let dp = pac::Peripherals::take().expect("cannot take peripherals");

    let swo_enable = true;
    low_level_itm(&dp.DBGMCU, swo_enable);

    let mut log = InterruptSyncItm::new(Itm::new(cp.ITM));

    // Constrain and Freeze power
    println!(log, "Setup PWR...                  ");
    // ...

The dumped output from bmp_traceswo is:

bad packet: 01 53 03 65 74 75 70 03
bad packet: 20 50 57 52 03 2e 2e 2e
bad packet: 20 03 20 20 20 20 03 20
bad packet: 20 20 20 03 20 20 20 20
bad packet: 03 20 20 20 20 01 20

this corresponds to Setup PWR...  . So it seems to be just about working (it should print Setup PWR...) but the structure is something that bmp_traceswo does not expect. I guess this method is not exactly compatible with what bmp_traceswo expects. How are you reading the ITM output?

richardeoin commented 4 years ago

Ah yes, this area could really do with some more work.

What you're seeing in the packet dump are Instrumentation Packets from the ITM, which are described in the ARM®v7-M Architecture Reference Manual (ARM DDI 0403E.b), Section D4.2.8. As it is, bmp_traceswo doesn't understand these.

Since the port number is 0, one hack would be replacing this:

-      if (count & 1)
-        goto bad_packet;
-      for (int j = 0; j < count; j += 2)
-        if (dataUp[j] != 1)
-          goto bad_packet;
-      for (int j = 0; j < count; j += 2)
-        putchar(dataUp[j + 1]);

with this

+      for (int j = 0; j < count; j++) {
+        if (dataUp[j] > 7) {    /* Crude, Awful */
+          putchar(dataUp[j]);
+        }
+      }

Better contributions very welcome :)

astraw commented 4 years ago

Thanks - again very helpful. This hack works for now and the documentation pointer is useful. I see japaric's itm crate looks like it should be able to parse these. I'll work on that, but this is extremely useful already.

maxekman commented 4 years ago

Have anyone here got ITM to work on the Nucleo-144 STM32H743 board with the built in ST-Link V2? I have tried a lot of configurations and mixes of the above comments and other info found on the Internet, so far without luck. Any help would be appreciated!

astraw commented 4 years ago

I gave up trying and have it working on the ZI2 board with a black magic probe. (The ZI2 board has st-link v3 I think, but the black magic probe bypasses this). The last time I checked, I think OpenOCD support for the stm32h7 did not seem complete. I am very interested to hear if you get it working. For now, the only way I can use ITM is with the black magic probe.

Edit: with the black magic probe, I am using a recent git snapshot build.

maxekman commented 4 years ago

Thanks for the info @astraw, I'll report back any progress on it.

diondokter commented 4 years ago

So I've been trying as well with the tips here, but I can't get the PB3 pin moving in any way. It just keeps floating. I was using the STLINKv3. Sad to see that it's so difficult for this line of MCU's.

richardeoin commented 4 years ago

Hey @diondokter - For the single core parts (743/753/750 etc..) you should be able to see something on the PB3 pin with:

I'd be interested to hear if that doesn't generate any waveform on PB3. Getting ITM to work with various debuggers is always a pain, hence this issue to suggest we remove it from the examples completely to avoid distracting new users.

diondokter commented 4 years ago

@richardeoin Thanks for responding. I've been experimenting more and I've found the following:

If I start with OpenOCD, then the pin remains floating. However, if I use the SWO viewer of the old STLINK Utility, then the pin gives signals and they get read by the software correctly.

So to me it seems like the debugger must give some command before ITM is truly enabled.

BTW: ITM and OpenOCD does work on my Nucleo F4 boards.

richardeoin commented 4 years ago

Interesting that OpenOCD actually manages to break a working configuration.

It seems that OpenOCD sets some bits in DBGMCU:CR that are now reserved in the latest version of RM0433 (see page 3304 of rev 7). ST often makes these changes to hide hardware bugs. You could try editing OpenOCD to see if those bits are the problem, maybe try 0x0000005F or even 0x00000007.

diondokter commented 4 years ago

@richardeoin Thank you! That did work (setting it to 0x07). The pin is now signalling something. But now OpenOCD is reading garbage... Gotta figure out why. But I don't want to bother you too much 😉

richardeoin commented 4 years ago

Ok, it's nice to fix the problem! I'll to submit a PR to the PAC crate so the bits ST have hidden can't be accessed from safe Rust. I guess you could submit a PR to OpenOCD too, I'll leave that up to you if you want to.

diondokter commented 4 years ago

So I've finally got it to work. Making sure my clocks and config are correct and changing the OpenOCD script did the job. Made a ticket at OpenOCD to fix it: https://sourceforge.net/p/openocd/tickets/266/

maxekman commented 4 years ago

Very good news @diondokter, really great work! Finally I can move up to working with the H7 instead of the F4 for my project. 🙂

maxekman commented 4 years ago

@diondokter BTW, do you have a branch/gist/diff with the OpenOCD changes needed?

maxekman commented 4 years ago

We should probably also amend the readme or ITM example that users must use the master branch of OpenOCD for it to work. They have not done a versioned release of OpenOCD in about two years I believe..

diondokter commented 4 years ago

@maxekman This should help: https://gist.github.com/diondokter/5740aeb145e123c5b4dac7c7b32e36f6

maxekman commented 4 years ago

@diondokter Thanks for the Gist, I tried it out briefly but didn't get it to work fully. I did get some random/scrambled output on the ITM though, needs more experimentation. Do you have the ST-Link v3 board? I have the old v2 one..

diondokter commented 4 years ago

@maxekman Yes I have the V3. For me, it works better when I set the speed to just 1Mhz.

maxekman commented 4 years ago

@diondokter I'll try some lower speeds then, could be why I get the scrambled output. Thanks for input.

maxekman commented 3 years ago

I finally got ITM working on the Nucleo-144 STM32H743ZI board! I'm using the latest OpenOCD target.cfg and the enable ITM from @diondokter. I can't see no other reason for it to start working now than the updated OpenOCD config file..