Debug monitor exception and FPB unit on MBED (LPC1768)

12 Oct 2010

Hi,

I'm trying to use the FPB unit on the LPC1768 to activate a debug monitor exception on address match, and I can't make it to work apparently. The exception is never executed. I was wondering, does mbed do something special with the debug monitor? I'm asking because I noticed that FP_CTRL has ENABLE (bit 0) set to 1 when my application starts, which shouldn't happen according to the documentation.

 

Thanks,

Bogdan

12 Oct 2010

Hmmm, interesting. It seems that C_DEBUGEN is set in DHCSR, which probably renders all my debug monitor attempts futile. Furthermore, it seems that I'm unable to clear that bit for some reason. I must be doing something wrong somewhere...

13 Oct 2010

mbed library uses semihosting calls for stuff like LocalFileSystem. They're implemented using BKPT opcodes and (as far as I understood) the debug exceptions are handled by the interface chip using the JTAG interface. I guess the interface chip gets your debug exception but doesn't know what to do with it.

13 Oct 2010

user Igor Skochinsky wrote:

mbed library uses semihosting calls for stuff like LocalFileSystem. They're implemented using BKPT opcodes and (as far as I understood) the debug exceptions are handled by the interface chip using the JTAG interface. I guess the interface chip gets your debug exception but doesn't know what to do with it.

Thank you, that clears part of the mistery. My debug monitor doesn't ever get activated as long as C_DEBUGEN is set. What I don't undestand now is why I can't clear C_DEBUGEN. I'm writing 0xA05F << 16 to DHCSR, which should in theory clear C_DEBUGEN, but it doesn't. I wonder if mbed has some sort of mechanism to prevent C_DEBUGEN from being cleared. I sure hope it doesn't.

13 Oct 2010

Hmmm, I think I got it. The core can't set this bit directly, you need a debugger that works over AHB-AP to clear it. So, my question becomes: is there any way to clear this bit in mbed?

13 Oct 2010 . Edited: 13 Oct 2010

Hi Bogdan,

Great to hear someone is looking at montor mode :) A very under-utilised feature of M3 IMO, and the potential for some great things!

As Igor has explained, we attach to the target as a debugger (HALT mode), so we can respond to semihosting requests via JTAG, just like a host based debugger would. This allows us to do things like service semihosted file requests which is pretty neat.

We don't actively stop you messing with anything; it turns out after a little investigation it is actually the core itself that is not allowed to write this register. See:

That is a bit of a gotcha, so here are some ideas to ungotcha us. One is that we provide a call to disconnect the debugger. I have a build of something like this which actually turns the whole interface off assuming USB is disconnected, but then you'd loose the USB serial/power, which may not be so neat. So perhaps a call to detach the debugger only could be a start.

As an alternative, maybe we could cascade it in some way? I've not looked to see if it is actually possible, but maybe when a HALT mode unhalts, it could cascade to the monitor if enabled? It sounds like it doesn't do this by default from your experiments, so it'd need some investigation to see if this is possible/sensible/a good idea.

If it is of interest, I could provide you the powerdown interface build, as long as you realise you'll have to run your tests with it disconnected from USB. But it may be interesting to see what is possible.

Simon

13 Oct 2010

Hi Simon,

Thanks for the detailed reply. Yes, I'm actually looking at something potentially cool to do using the debug features, but I'm a bit afraid that people will think I'm crazy if I say what it is :), so I'd like to to make more experiments first, to understand if it is at all possible in practice.

About completely removing USB, I wouldn't have a problem with that if I could still program the mbed using the serial bootloader. I'm not sure this is possible though, at least not easily. The schematic suggests that the bootloader enable pin (P2.10) isn't routed to the headers, but goes to the MBED-IF01 chip instead (and to a pullup resistor). Maybe there's some other way to use the bootloader that I don't know of?

About cascading, I'm not sure how that could be done. The halt mode and the debug monitor are somehow parallel, in that they have separate single stepping features (for example), so I'm guessing that simply jumping to the debug monitor won't do the trick. On the other hand, it is my understanding that the core won't call the debug monitor if C_DEBUGEN is enabled (paragraph C1.5 in the ARM v7-M architecture reference manual - DDI0403D). So chaining might be a bit difficult :)

Thanks,
Bogdan

13 Oct 2010

Hi Bogdan,

Take a look at http://mbed.org/users/simon/notebook/interface-powerdown/ for something you can play with. Should be enough to let you experiment :)

Simon

13 Oct 2010

Thanks, Simon! I'll give it a try as soon as I get home. Fortunately I realised that I don't really need a serial bootloader for this :)

13 Oct 2010 . Edited: 13 Oct 2010

Me again. I copied the new firmware to my mbed, and tried again, but C_DEBUGEN is still 1. Come to think of it, the debugger should explicitly set this to 0 before shutting itself down, otherwise this wouldn't help (as the core would still be unable to set this bit to 0, just like before). Do you know if the debugger does this?

This is the output of my test program BTW:

Starting tests...
Remove USB cable and press any key to continue.
Semihosting result: 0
DHCSR: 1010001

As you can see, the last bit of DHCSR (C_DEBUGEN) is 1.

14 Oct 2010

This is funny actually :) I have the mbed LPC1768 that has a MPU (and I need that) but I can't use the debug monitor. And I have a STM32 on which I can use the debug monitor perfectly, but it doesn't have a MPU. Now, if I can just find a way to melt them together into a superchip ...

14 Oct 2010 . Edited: 14 Oct 2010

This is extremely weird. I just tried, and now my DHCSR appears as 1010000. Not that I'm complaining :), but I don't understand what happened. I didn't modify the source code. It's true that I re-flashed the experimental firmware meanwhile. Anyway, thanks for the firmware, and sorry for the noise. I can definitely experiment with this.

EDIT: That was short. I read that damn bit as 0 exactly one time (when I posted this reply). Now it's 1 again. I have no idea what happens anymore.

15 Oct 2010

I _finally_ got it (for real this time, promise :) ). This is the (wrong) sequence that I've been using:

1. Power the mbed from both USB and an external power supply
2. Write my firmware
3. Remove the USB cable
4. Run my program (which includes the semihosting call)

With this sequence, although the semihosting call returns 0, C_DEBUGEN is still enabled and the main blue LED doesn't go off. It turns out that I need to completely power off the board and turn it back on again, as described below:

1. Power the mbed from USB (the external power supply can be present too, but it won't help much)
2. Write my firmware
3. Remvove ALL the power supplies (USB cable and the external power supply if that is present)
4. (Re)attach external power suply
5. Run the program and enjoy :) (after the semihosting call, C_DEBUGEN is 0 and the main blue LED goes off. Also the button doesn't

Which makes sense now that I think about it. For some weird resume I assumed than when the USB interface is disconnected C_DEBUGEN is also explicitly set to 0. Obviously, it's not.
Thanks again for your help, and sorry for the noise :)

Best,
Bogdan