-
Notifications
You must be signed in to change notification settings - Fork 94
Using the debug interface with linux
Make sure to always remove the battery before attaching the watch module to the debug interface!
Be aware that you can easily overwrite your information memory where some calibration data unique to your device has been placed at the factory. It is recommended to take a backup of that memory area as your first step and store that in a safe place.
The debug interface (one of the USB devices that comes with the watch) can be used to
- erase and write the flash memory
- read the flash memory
- debug running programs
- run a program step by step
- run and stop at specified breakpoints
- see the state of CPU registers
- see the content of the RAM
- manipulate RAM or CPU registers
There are many sources on the Internet that suggest the use of the ti_usb_3410_5052 kernel module with the debug interface. This is not necessary (and likely not even possible, at least I found no way to make it work). Instead the user space program MSPDebug can be used. It communicates with the debug interface through libusb.
You need to have permission to write to the usb device ID 0451:f432 .
Building MSPDebug is very simple and the program can be run from anywhere (no need to do “make install”).
When run with “mspdebug rf2500” the program should attach to the debug interface and if the watch module is connected you should get some information about the debug interface and the attached microcontroller. In this case
Device ID: 0×6137
Device: CC430F6137
What follows is a list of available commands, some really short usage instruction, and you are on the command line and ready to go.
The most important commands here are
- prog : write the content of to memory. This can be *.elf files or memory content in Intel-HEX or TI-HEX. The main flash memory always gets erased, you also have to rewrite main flash memory even when you only want to rewrite the information memory. Information memory and BSL memory are not erased unless you try to rewrite them.
- hexout : dump memory content to hex file (as Intel-HEX). Take a look at the users guide to find out what memory areas are available (“hexout 0×1800 512 infomem.hex” dumps the content of the information memory to a file named infomem.hex)
- reset : clear RAM and reset all CPU registers
- run :
- gdb : run in GDB proxy mode to allow connection by msp430-gdb or msp430-insight from the mspgcc4 project
Interactive debugging can better be done with the Insight GUI instead of the mspdebug command line.
Be aware that the maximum number of breakpoints is three. Even if you can add more in a debugger that uses the mspdebug proxy, mspdebug will refuse to run with too many breakpoints set.
- run mspdebug
- use “prog” to write the elf file to the watch module
- use “gdb” to add proxy mode
- run msp430-insight
- open the elf file (with debug info!)
- use “run→connect to target” to connect to GDBserver at port 2000
- debug what you want to
- downloading of code to the watch, do it directly from mspdebug command line
- free running (clicking the “run” icon), msp430-insight might become unresponsive
- changing to a different program (e.g. newly compiled after a change in code) without restarting Insight
- answering “Yes” to “Make breakpoint pending on future shared library load?” makes Insight crash
- make sure you compile your program with debug info (add option “-g” to msp430-gcc)
- when you want to debug a function in isolation, do something with the result, otherwise the function will be optimized away, you might also add “-O0” and hope that that does not change your problem you want to debug and still fits in memory
- It is sometimes very hard to follow the value of variables when they are located in changing cpu registers. add code lines like “MPY=variable;” to write the values to a hardware register (here a register of the hardware multiplier, take anything you can write to without consequences). When you add a breakpoint at these instructions you exactly know in which register your value is located. This is also the ideal thing you can do with return values of functions so that the function call does not get optimized away.
- If you do not want your constants to be compiled in, try to read them from a hardware register with known content