Debug questions: Peripheral registers, stepping through context switches

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

Debug questions: Peripheral registers, stepping through context switches

1,117 Views
scottm
Senior Contributor II

I want to start by saying that the FreeRTOS task-aware debugger is a huge step up from CodeWarrior.  It's the main reason I switched.  The download behavior is also more intelligent and it's already saving me time by not having to download the same code over and over again for repeated debug sessions.

I'm running into some new headaches with MCUX, though.  What's the deal with the peripherals view?  Registers only shows CPU internal registers now.  The Peripherals+ view lets me bring up a peripheral in the memory view (it's slow, though, and takes 5 seconds to react to a click) and it doesn't show as much detail as the CW registers view, but it's something.  But you can't use it to watch anything - as soon as you step to the next instruction, the view clears.  You have to click on the view again and then it resets and you have to scroll back through everything to find your place.

Is this the right view to be using?  I can't imagine that it's regressed that far backwards in functionality since CW 10.  It also clears all of the memory views every time the debug session is restarted.  I find that I can follow specific registers in the expressions view, which is something that didn't seem to work reliably in CW 10, but of course that doesn't give me any decoding of fields.

The other thing I'm having trouble with is that I haven't found a way to step continuously across context switches.  This morning I'm troubleshooting a DMA problem where the transfer somehow continues when it should finish and clear ERQ, and I just want to step one instruction at a time while I watch the registers.  As soon as it hits a context switch, the system resumes running and I miss the critical events I'm watching for.  Surely there must be a way to follow execution through interrupts.  How do I do this?

Thanks,

Scott

Labels (1)
Tags (1)
0 Kudos
9 Replies

734 Views
scottm
Senior Contributor II

Ok, with a little more testing I've determined that the peripheral display in the memory view doesn't actually go away completely - but for a complex peripheral like the DMA controller, it's taking up to 10 seconds to refresh.  It's also resetting the view so that you have to stop and scroll back to the registers you're trying to watch.

The values I'm seeing there don't always make much sense.  I'm attaching an example.  The ACTIVE bit of DMA_TCDx_CSR is bit 6 and it's 1 bit wide, but the value shown in my memory view is 2:

Screenshot 2017-11-06 12.19.07.png

Obviously it's not possible for a 1-bit value to be 2.

Next glitch:  If you accidentally click on a value in that view and then click away to another view, it gives you an error:

Screenshot 2017-11-06 12.21.00.png

If you hit escape to cancel, it's fine.

Scott

0 Kudos

734 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Scott,

Sorry for the inconvenience to you , the register memory view bug will be fixed in the next release version.

the new version is in field trial now.


Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

734 Views
scottm
Senior Contributor II

What about stepping across context switches?  Is there any way to do that?

Thanks,

Scott

0 Kudos

734 Views
lpcxpresso_supp
NXP Employee
NXP Employee

Are you referring to the FreeRTOS plugin, or the FreeRTOS stack aware debug? And, are you debugging your FreeRTOS application in the recommended all-stop mode, or in non-stop mode?

You're in somewhat painful territory, I know, but first answer the question above.

Thanks and regards,

MCUXpresso Support

0 Kudos

734 Views
scottm
Senior Contributor II

In this case I'm not actually interested in the FreeRTOS tasks - I need to step through one instruction at a time, regardless of whether it's in a task or an interrupt, so I can watch hardware registers.  The problem is that stepping seems to be equivalent to setting a breakpoint at the next instruction, and I'll miss what I'm looking for when a context switch happens.

There are also times when I want to just follow the execution across tasks - for example, if a thread blocks and another unblocks I'd like to see execution continue in the new current thread.  The task-aware debugger has about two pages of documentation in the MCUX user's guide and I'm not sure if it's supposed to be able to do this.

Thanks,

Scott

0 Kudos

734 Views
lpcxpresso_supp
NXP Employee
NXP Employee

MCUXpresso masks external interrupts during instruction step. One example is your tick timer. Instruction stepover is a different matter. Like source line stepping, GDB decides whether the debugger instruction steps, or, sets a breakpoint and executes to the break. It’s possible you’re victimized by the latter case. Still, I would think one or two strategically placed breakpoints in the context switch code would prevent the behavior you see. Also, you didn’t answer the question about use of all-stop vs. non-stop debug modes. 

Thanks and regards,

MCUXpresso Support 

0 Kudos

734 Views
scottm
Senior Contributor II

Sorry, it's in all-stop mode - neglected to say that.  When you say GDB decides whether to instruction set or set a breakpoint, how does it decide?  Is it a matter of different strategies depending on how many instructions are to be stepped over?

In the specific case of trying to watch DMA activity with as small a time step as possible, what's the right way to do that?

There are days when I miss working with 40-pin DIP CPUs with all of the buses accessible and the ability to single step the CPU clock - even if the only debug output was a bunch of LEDs.

Thanks,

Scott

0 Kudos

734 Views
lpcxpresso_supp
NXP Employee
NXP Employee

I'm not intimately familiar with the GDB decision tree regarding instruction step. I expect the number of instructions and type (branch instruction/prediction) play in.

You didn't specify your processor, but DMA transfers are, of course, independent of CPU execution. So, DMA activity in terms of execution time is not really valid. You should view DMA debug in terms of events, typically transfer completion, or DMA error. And, you can no doubt change parameters such as burst size, etc., to compare behaviors. Good luck.

Thanks and regards,

MCUXpresso Support

0 Kudos

734 Views
scottm
Senior Contributor II

I'm working with a Kinetis K22F.  I understand that DMA runs independently - and forgetting to have it pause in debug mode has caused me some headaches before!  (Processor Expert's description of the debug disable flag is backwards.)  What I was after in this case was to see why I wasn't getting completion interrupts as expected.  I had one case like that where it turned out to be a non-atomic update to DMA_ERQ elsewhere in the code - something that was provided by Freescale as an example, in fact.

The behavior I want is 'always stop on the very next instruction to be executed' so I can see if an ISR screws up the DMA setup, if it somehow restarts the channel when it's not supposed to, or if I've just masked the INTMAJOR interrupt or something.

I'm on the verge of wiping out MCUXpresso and trying a fresh install.  My Peripherals+ view won't show anything now, and I installed EmbSysRegView and it has all of the register definitions but everything comes up zeroes.

Scott

0 Kudos