VTOR unexpectedly set in debug session

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

VTOR unexpectedly set in debug session

1,841 Views
lstu
Contributor II

Hi,

I have been trying to update the code for my current LPC1788-based project to MCUXpresso v10.2.0 from v10.0.2; however, I am encountering issues preventing me from debugging the firmware.  As I state in the description, the source of the problem during a debug session is that the VTOR register has a non-zero value in it at a time when it should not.  It appears that the value in the register is not being cleared on reset.

I'll describe my code setup a bit to try to make things clear.  We are using a custom bootloader for which we generate a separate image that we load at address 0 in internal flash; we reserve the first 0x4000 for it.  Our main application occupies the rest of flash.  The bootloader is the only place in our code where we set the VTOR, which the bootloader does once its work is finished (it sets it to 0x4000).

The bootloader needs to communicate over SSP0 to determine if it needs to do a firmware update.  Our interrupt-driven SPI communication is in a static library that both the bootloader and application reference, so they each have a copy of (among other things) the SSP0 IRQ handler and the associated state variable, XfrMode, that the IRQ handler reads and updates as it runs. 

The problem I am having occurs when I attempt to run a debug session on our main application.  Since resetting the processor clears the VTOR, the bootloader runs after the debug probe flashes the main application.  The bootloader is getting stuck waiting on XfrMode, which is never changing (I verified the address I was stuck at was where the bootloader waits on XfrMode to be set to its "done" value).  I found that, at this point in time, the VTOR (address 0xE000ED08 according to the LPC1788 User's Guide) has 0x4000 in it, which is causing the main application's instance of the SSP0 IRQ handler to run (instead of the bootloader's), which will not update the instance of XfrMode that the bootloader uses; hence, why it gets stuck.

If I force the VTOR to 0 at the start of the bootloader, it resolves this issue.  However, I am trying to figure out why this behavior occurs now when it did not in the older IDE version.

The settings in my debug configuration are the default settings the IDE generated when I first started a debug session.  I tried, among other things, changing the "Reset Handling" parameter from VECTRESET to both SOFT and SYSRESETREQ.  Setting it to SOFT yielded some results: the VTOR value was apparently 0 for most of the bootloader, since the debugger successfully stopped at main() (of the application).  Sadly, the SOFT reset introduced another problem I can not find a workaround for: in the application, the SSP0 interrupt is not being generated despite being enabled (SSP0->IMSC.TXIM and SSP0->RIS.TXRIS are both set; NVIC indicates SSP0 interrupt is priority 0; and PRIMASK register is 0).

I did see that the BASEPRI register (which we never modify in our code) is set to an invalid value (1) when the debugger breaks at main(), and the value does not change when I try to write it with the CMSIS __set_BASEPRI() call (we are running in privileged mode, CONTROL register is 0, so it should work to my knowledge).  I'm guessing this invalid BASEPRI value is keeping the SSP0 interrupt from being serviced.

Thanks for reading this far!  I am more interested in why VTOR is the wrong value inside the bootloader, but if anybody has any thoughts on the SOFT reset and BASEPRI stuff, I'm curious about that as well.  Let me know additional info you might need.

Thanks for your help,

Luke

8 Replies

1,381 Views
lstu
Contributor II

Thank you very much for your quick and helpful responses, and for digging into this.

I suppose the takeaway if you're using a bootloader is to be sure to explicitly set VTOR to the proper value in your bootloader if the bootloader uses any interrupts.  That way, VTOR is guaranteed to be the value you need it to be.

That works for me.  Thanks again for your help.

0 Kudos

1,381 Views
lpcxpresso_supp
NXP Employee
NXP Employee

Hi Luke,

Thank you for your debug log.

I have done some more investigation on this issue and now better understand what is occurring. The LPC-Link2/LinkServer 'debug world' is essentially trying to be helpful in that is 'sees' that an image has been loaded to an address offset from 0x0 and so sets the expected VTOR for an image running from that address. Now typically this would be an invisible setting since the image would most likely set the VTOR value required within its startup sequence - however in your case this will fail because the image will never actually be run following a reset.

The way forward as you say is to set VTOR within the code that executes from reset (your bootloader). 

You may also have seen the debug shortcuts that now feature as part of the updated QuickStart panel.

Using these an option would be to use the LinkServer Debug shortcut to perform a program (not debug) operation. This will program the selected projects image into flash and perform a reset (but not change VTOR). Next, choose the option to attach, and this will attach a debug session to the executing target (and set the attach option within the launch configuration - shown by a superimposed 'A'). Now a debug session would be a two step operation. First perform a program, then simply click the debug button to 'attach' - since this is now set within the launch configuration.

Yours,

MCUXpresso IDE Support

0 Kudos

1,381 Views
lpcxpresso_supp
NXP Employee
NXP Employee

The launch configuration "Reset Handling" setting is intended as SYSRESETREQ. Note the difference to the "Flash Driver Reset Handling" setting.

Thanks and regards,

MCUXpresso Support

0 Kudos

1,381 Views
lstu
Contributor II

Here is the output of my debug log:

MCUXpresso IDE RedlinkMulti Driver v10.2 (May 10 2018 18:10:59 - crt_emu_cm_redlink build 510)
Found chip XML file in PROJECT_PATH\LPC1788.xml
Reconnected to existing link server
Connecting to probe 3 core 0:0 (using server started externally) gave 'OK'
Probe Firmware: LPC-LINK2 CMSIS-DAP V5.182 (NXP Semiconductors)
Serial Number: I3FSNZMW
VID:PID: 1FC9:0090
USB Path: \\?\hid#vid_1fc9&pid_0090&mi_00#7&140ef531&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
Using memory from core 0:0 after searching for a good core
debug interface type = <unknown> (DAP DP ID 2BA01477) over <error> TAP 0
processor type = Cortex-M3 (CPU ID 00000C23) on DAP AP 0
number of h/w breakpoints = 6
number of flash patches = 2
number of h/w watchpoints = 4
Probe(0): Connected&Reset. DpID: 2BA01477. CpuID: 00000C23. Info: <None>
Debug protocol: SWD. RTCK: Disabled. Vector catch: Disabled.
Content of CoreSight Debug ROM(s):
RBASE E00FF000: CID B105100D PID 0000000000 ROM dev (type 0x1)
ROM 1 E000E000: CID B105E00D PID 04002BB000 ChipIP dev SCS (type 0x0)
ROM 1 E0001000: CID B105E00D PID 04002BB002 ChipIP dev DWT (type 0x0)
ROM 1 E0002000: CID B105E00D PID 04002BB003 ChipIP dev FPB (type 0x0)
ROM 1 E0000000: CID B105E00D PID 04002BB001 ChipIP dev ITM (type 0x0)
ROM 1 E0040000: CID B105900D PID 04002BB923 CoreSight dev TPIU-Lite type 0x11 Trace Sink - TPIU
ROM 1 E0041000: CID B105900D PID 04002BB924 CoreSight dev ETM-M3 type 0x13 Trace Source - core
Inspected v.2 On-chip Flash Memory LPC177x_8x_407x_8x_512.cfx
Image 'LPC177x_8x_407x_8x (512K) May 10 2018 18:16:41'
NXP: LPC1788
Connected: was_reset=true. was_stopped=false
Awaiting telnet connection to port 3330 ...
GDB nonstop mode enabled
Opening flash driver LPC177x_8x_407x_8x_512.cfx
Sending VECTRESET to run flash driver
Writing 488368 bytes to address 0x00004000 in Flash
Erased/Wrote page 4-29 with 488368 bytes in 5142msec
Closing flash driver LPC177x_8x_407x_8x_512.cfx
Flash Write Done
Flash Program Summary: 488368 bytes in 5.14 seconds (92.75 KB/sec)
Starting execution using system reset and halt target
Stopped: Halt

I noticed the line I highlighted in red and made bold above.  I changed the "Flash Driver Reset Handling" field of my debug configuration to SYSRESETREQ, so that, when I debugged again, that line changed in the debug log:

Sending SYSRESETREQ to run flash driver

Unfortunately, my debug session still got stuck in the same place in the bootloader as before.

Thanks,

Luke

0 Kudos

1,381 Views
lpcxpresso_supp
NXP Employee
NXP Employee

Hi Luke,

Please could you post a copy your debug log for investigation.

https://community.nxp.com/message/630852 

Yours,

MCUXpresso IDE Support

0 Kudos

1,381 Views
lstu
Contributor II

Thanks for the quick reply.

This project is not based on LPCOpen.  In our startup code (also in a SystemInit function called from ResetISR), there is conditionally compiled code for __RAM_MODE__ that modifies the VTOR; however, we are not using it.

Using v10.2.0, I just tried using SYSRESETREQ in place of VECTRESET on my debug configuration.  Unfortunately, it does not appear that the VTOR was actually reset.  The PC is stuck at the same location in our bootloader as before, and looking at the VTOR address, I see it has 0x4000.

I also went back to v10.0.2 (this is on a separate copy of the code), debugged my main application (using VECTRESET, then SYSRESETREQ), but I placed a breakpoint at an address inside the bootloader, so it would break before getting to main().  I looked up VTOR, and in both cases, it was 0.

I can definitely work around the problem by setting the VTOR to 0 in our bootloader, so I'll do that for sure.  And based on what you said about the MEMMAP setting, I'll start using SYSRESTREQ with other projects as well.

Thanks,

Luke

0 Kudos

1,381 Views
lpcxpresso_supp
NXP Employee
NXP Employee

If your project is based on the LPCOpen (e.g. lpcopen_2_10_lpcxpresso_ea_devkit_1788) examples, you'll find a VTOR setting in the SystemInit (sysinit.c) code. SystemInit can be called from the ResetISR startup code, if so configured. ResetISR is the typical reset vector, and your bootloader may have its' own version of ResetISR.

I suspect the problem may be a side effect of the VECTRESET (core reset) signal in your launch configuration. If the debugger uses this signal, the VTOR register does not reset to the zero address default as it would if you used  SYSRESETREQ. ARM defines SYSRESETREQ as a vendor implementation. The implementation can vary between parts, and this reset does not always behave consistently. Another factor which can potentially come into play is the MEMMAP setting. This controls whether the LPC1788 Boot ROM is mapped at address zero (after reset), or to user flash. Your secondary bootloader is also user flash.The consideration here is you want the part to execute through the Boot ROM to user code. A VECTRESET does not reset the MEMMAP setting, this bypasses the Boot ROM setup (IRC trim, etc.). Use SYSRESETREQ when possible.

The question is what does the IDE reset/restart have to do with your firmware update? In any case, I recommend you explicitly configure the VTOR as appropriate in the secondary bootloader, and application code.

Thanks and regards,

MCUXpresso Support

0 Kudos

1,381 Views
lstu
Contributor II

Forgot to mention, I am debugging with an LPC-Link2 CMSIS-DAP v5.182 over SWD.