17 July 2010

Tutorial 06: Getting the Bugs Out

The debugging features of the MSP430 are one of the most helpful tools you'll have in developing your projects. Let's take a look at how to use some of the basic features here.  Load up your Blinky program and start the debugger, but this time don't push the 'Run' button, just leave it in a hold state.  Your screen should look something like the image here.  Note a few things to start.  There are six windows opened here by default. The one on the far right, the 'Cheat Sheets', gives tips and help if you need it.  You can also just close this window.  (If you really get annoyed with it, just choose Disable All Cheatsheets on that window.)

The five remaining windows are Debug, Variables (labeled Local in this screenshot), the code, Dissasembly, and a Console.  The console, again, shows results and errors that come from compiling, loading, and in some cases the code itself.  The code window should be self-explaning, but note that the void main(void) { line is highlighted and has an arrow next to it.  This shows where in the code the debugger is sitting.  When you first load code into the flash memory of the chip, it turns on and holds everything right at the start.  The variables window shows current values of code variables and (we'll see in a little while) of registers in the MSP430.  The Debug window shows where we are in the hierarchy of the project itself.  (Ours is simple, only one source file, so this window isn't as helpful right now.)

Note the collection of icons in the Debug window.  You can see the 'Run' button there.  The other important ones for this tutorial follow the 'Run' button.  There's 'Halt' (looks like a pause button, should be grayed out when the debugger holds, lights up while 'Run' grays out when the chip is running), then 'Terminate All'.  These control the debugger, like a play, pause, and start button.  Next come a series of arrows, the first of which is 'Step Into'.  We'll use that button today.  A little farther, there's an icon that looks like a chip with two cycling arrows.  This button resets the CPU in the MSP430 and sends the debugger back to the beginning.

Before we start debugging our code, let's change the number of loops in our delay to 6.  You'll see why in a bit.  Scroll through the code in the code window until you find the right line, and change the count to end at 6 rather than 60000.  Up at the top of the CCS window, you'll see icons similar to what we had in the compiler environment.  Next to the 'Build Active Project' icon, there's a 'Rebuild Active Project' icon.  After you make simple changes in the code here, click that button to recompile and reload the updated code to the MSP430. (If you need to make significant changes to the code, it's easier to terminate the debugger and work in the compiler environment.)  Go ahead and tell CCS to reload the code into your MSP430, and the debugger will start over again.

Now we'll use the 'Step Into' button of the debugger to step through the code line by line.  One click of the button, and you should see the arrow move down two lines, to WDTCTL.  You may have noticed that the count variable already appeared in the Local Variables window; CCS loads that information automatically before debugging.  The value of count is probably just some random value that we won't be using.  We'll get back to that window soon.

Before we 'Step Into' the WDTCTL line, let's open up another useful window.  Go to View → Registers, and you'll see another variable window pop up with all the registers in your device.  (This feature is so useful for learning from!  We'll make extensive use of this as we learn about the MSP430 peripherals, so remember how to do this part.)  To the bottom of the list, you'll find Watchdog_Timer.  Open up this section, and you'll find the WDTCTL register.  The debugger is showing that the register currently has the hex value 0x6900.  Opening the WDTCTL register shows the individual bits.  Note that all of them are set to 0 when you power up the MSP430.  This setting uses the watchdog timer normally, and running like this would reset the CPU periodically.  Now step into the next line of our code and see what happens.

Stepping into the next line, you see the WDTHOLD turns to 1 (and turns red, signifying something changed in this clock cycle) and the value of WDTCTL is now 0x6980.  You may recall that setting the WDT requires a password of 0x5a.  When you read the password byte of WDTCTL, however, it returns 0x69.

(Want to force a reset in your code?  Try writing WDTCTL = WDTCTL.  Reading WDTCTL returns a value that is not the right password and you give the incorrect key to be able to write to the register; the MSP430 resets if this happens.)

See if you can find the P1 registers and then step into the next two lines to see what happens there.  The debugger should now be on the LED toggle line in the infinite loop.  Before we go further, change the variable window back to the local variables.  Note that count still has some random value in it.  Now, stepping into the LED toggle line, we should change P1OUT to light up the LED!  We are now at the for loop for the delay.  Step once into this; the debugger goes right back to the same line, but note the change in the value of count in the variable window.  Count increments by 1 each time you press 'Step Into'.  When it reaches count==6, the debugger moves on to the next line.  One more step brings you back to the LED toggle.  (Glad I had you change the delay to 6 instead of 60000?)  You can then step through the code to turn off the LED, delay again, then repeat as much as you wish.  At any time you can hit 'Run' and set the MSP430 off on its own.  If you want to show someone that your LaunchPad is working, don't forget to increase the value in the delay loop.  The MSP430 is fast enough that your eye won't pick up the frequency with counting up to 6.  =)

The debugger is a very useful tool, though keep in mind it won't always work for what we want it to do.  The MSP430 is designed to interface with the outside world.  While the debugger can pause the clock inside the MSP430, it can't pause the clock in our world.  Later on we'll look at what to do when you're debugging code that relies on outside timings.  But I hope you can see just how helpful the debugger can be in your project.  If you know of or discover any other features of the CCS debugger that you find very helpful, send a comment and let us know!

This post concludes the initial collection of tutorials on the MSP430.  You now have enough knowledge to be able to write a program, download the code into an MSP430, and create some basic projects.  Good luck on your next project, and join in our growing community to let people know what you're able to do and learn with the MSP430!  Come back often as I'll be posting new tutorials on the peripherals of the MSP430 soon.

Reader Exercise:  Try out the code you wrote in Tutorial 04.  Does it behave how you expected?  Use the debugger to step through it (change any delay loops to something manageable) and be sure everything runs as it should.


UsuallyDrunk said...

Many thanks David.

Received my Launchpad boards this morning, and you've juts got me up and running very quickly. Much appreciated!!


David said...

I'm glad to hear the tutorial is helpful! I just received my LaunchPads this morning as well, so I should be getting around to updating the current tutorials to match that platform soon. I'm also working on the next tutorial on the BCS+ system, should be up in a day or two. (Depends on how soon I can get out of the lab today...)

Ashen said...

Hey David,
Great tutorial!! Thanks a lot :)

Ashen from Sri Lanka

Anonymous said...

What happens if I forget to change 6000 to 6 and am stuck inside the loop while debugging? Is it possible to get out of the step into state in this case?

David said...

That's an excellent question; I haven't learned as much about the debugger as I would like thus far. I know that you can step out of it easily by running the code. It would makes sense that there should be a way to step out of a loop, but I haven't found a way to do that yet. In the case of this tutorial, you can at least exit the debugger and reflash the code when you realize the error.

If anyone knows of some helpful resources for learning about the CCS debugger, let me know!

Travis said...

I want to thank the author for this great tutorial as I have learned much from reading through them. I realize this post is over a year old but a simple way to jump to the end of a loop is to simply change the value of the variable within the debugger. In this example change the count value to say 5999 which should cause the next "step into" to end the loop.

Anonymous said...

if u forget to change 60000 to 6 and u get stuck in the loop while debugging line by line....simply write something in between where the compiler lets u....the code will get modified and then u will be asked to confirm the rebuild the project automaically

Anonymous said...

just wanna say thanks. you're awesome.