Power profiling with the MSP430-JTAG-ISO-MK2
Olimex’s MSP430-JTAG-ISO-MK2 has power profiling functionality which can be used from MSPDebug. When a chip is running, the debugger continuously captures current consumption and MAB (program counter) samples, which can be read and analysed.
As of 4 Oct 2012, MSPDebug contains support for the following power profiling functionality:
- Basic statistics (average current, run time, charge consumption).
- Time-domain analysis, including exporting of raw samples to CSV format.
- Disassembly annotations, which show power consumption on a per-instruction basis.
- Hotspot/profile analysis to discover which functions are consuming the most power.
The driver for this device supports both raw USB and tty access, and can be used to perform firmware updates.
Firmware
After compiling a version of MSPDebug which supports power profiling (as of today, this must be a git snapshot), you will need to ensure that your debugger is running up-to-date firmware. The driver name for this debugger is olimex-iso-mk2
, and the preamble displayed on startup will show the debugger version:
Olimex firmware version: 1312d04
If your firmware is older than the version shown, you’ll need to update it, using the following binary image:
Update your device as follows (note that the driver also accepts the -d
option if you’d prefer to use your operating system’s serial driver):
$ mspdebug olimex-iso-mk2 --require-fw-update msp430_jtag_iso_mk2-01312D04.bin
MSPDebug version 0.20 - debugging tool for MSP430 MCUs
Copyright (C) 2009-2012 Daniel Beer <dlbeer@gmail.com>
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Firmware image version: 1312d04: 167936 bytes at offset 0x8000
Writing: 8192/ 167936 [ 4%]
...
Writing: 163840/ 167936 [ 97%]
Verifying: 8192/ 167936 [ 4%]
...
Verifying: 163840/ 167936 [ 97%]
Firmware update successful
Resetting, please wait...
Olimex firmware version: 1312d04
Resetting Olimex command processor...
Initializing FET...
Note that the reset will take a while to complete (about 15 seconds). At this point, you should have a fully functional debugger with power profiling capability.
Basic use
During startup, you should see a message like the following in the preamble:
Power profiling enabled: bufsize = 512 bytes, 55 us/sample
If so, power sampling will occur automatically each time you run the chip. Every invocation of the run
command will start the sampler. As the chip runs, samples are read from the debugger and stored into a rolling buffer maintained by MSPDebug. The buffer holds a maximum of 131,072 samples (about 7 seconds worth of run-time).
At any time, you can inspect the state of the collected data with the power info
command:
(mspdebug) power info
Sample granularity is 55 us
2 sessions:
Session #1: Thu Oct 4 13:49:54 2012
32921 samples (spanning 1810.655 ms)
3742.2 uA average (6775.8 uAs total charge)
Session #0: Thu Oct 4 13:49:58 2012
13990 samples (spanning 769.450 ms)
3730.1 uA average (2870.1 uAs total charge)
Sessions are numbered in reverse chronological order (0 is the most recent) and listed in forward chronological order. To reset the buffers, use the power clear
command.
You can see current consumption as a function of time using the power session
command, which takes as arguments a session number and an approximate granularity (in microseconds):
(mspdebug) power session 1 100000
Session #1: Thu Oct 4 13:49:54 2012
32921 samples (spanning 1810.655 ms)
3742.2 uA average (6775.8 uAs total charge)
Time (us) Current (uA) MAB
------------------------------------------------
0 3122.3 0x0000
99990 3455.7 wait_idle+0xa
199980 3459.9 wait_idle+0xe
299970 3455.2 wait_idle+0xe
399960 3457.8 wait_idle+0xe
499950 3462.4 wait_idle+0xe
599940 3469.5 wait_idle+0x8
699930 4766.9 wait_idle+0xa
799920 4879.1 pulse_led+0x14
899910 3451.8 wait_idle+0x8
999900 3458.0 wait_idle+0xc
1099890 3460.3 wait_idle+0x8
1199880 3460.3 wait_idle+0xe
1299870 3464.2 wait_idle+0x8
1399860 3464.2 wait_idle+0xe
1499850 3611.1 wait_idle+0xa
1599840 5354.9 pulse_led+0x12
1699830 4139.0 pulse_led+0x14
The raw data can also be exported for further analysis:
(mspdebug) power export-csv 1 data.csv
Exported 32921 samples to data.csv
Profiling
The collected data is cross-referenced with the executing code in two ways. The first, and simplest way, is that the disassembler will show, for each instruction, the average current over all collected samples. It also shows a summary for the disassembled block at the end. For example:
(mspdebug) dis pulse_led 0x20
pulse_led:
08082: 5f 42 21 00 MOV.B &0x0021, R15
08086: 5f d3 BIS.B #0x0001, R15
08088: c2 4f 21 00 MOV.B R15, &0x0021
0808c: 3f 40 c8 00 MOV #0x00c8, R15
08090: 3e 40 d0 07 MOV #__wdt_clear_value+0x5d0, R14 ;; 5382.3 uA
08094: 1e 83 DEC R14 ;; 5373.8 uA
08096: 03 43 NOP ;; 5379.4 uA
08098: fd 23 JNZ pulse_led+0x12 ;; 5377.5 uA
0809a: 3f 53 ADD #__ivtbl_16+0x1f, R15 ;; 5381.6 uA
0809c: f9 23 JNZ pulse_led+0xe
0809e: 5f 42 21 00 MOV.B &0x0021, R15 ;; 5495.0 uA
;; Total over this block: 6722.1 uAs in 1249.9 ms (5378.0 uA avg)
(mspdebug) dis wait_idle 0x20
wait_idle:
080ac: 3f 40 e8 03 MOV #__wdt_clear_value+0x1e8, R15
080b0: 3e 40 d0 07 MOV #__wdt_clear_value+0x5d0, R14 ;; 3486.0 uA
080b4: 1e 83 DEC R14 ;; 3483.8 uA
080b6: 03 43 NOP ;; 3485.8 uA
080b8: fd 23 JNZ wait_idle+0x8 ;; 3483.8 uA
080ba: 3f 53 ADD #__ivtbl_16+0x1f, R15 ;; 3484.1 uA
080bc: f9 23 JNZ wait_idle+0x4
080be: 30 41 RET ;; 3580.8 uA
080c0: 00 13 RETI
080c2: ff ff ff ff AND.B @R15+, __ivtbl_16+0x1f(R15)
080c6: ff ff ff ff AND.B @R15+, __ivtbl_16+0x1f(R15)
080ca: ff ff
;; Total over this block: 20758.3 uAs in 5957.5 ms (3484.4 uA avg)
If you have a symbol table available, you can use it to construct a profile report, which lists functions in order of power consumption:
(mspdebug) sym import power-test.elf
(mspdebug) power profile
Addr Name Charge (uAs) Time (ms) Current (uA)
------------------------------------------------------------------------
0x080ac wait_idle 20762.4 5958.7 3484.4
0x08082 pulse_led 6723.6 1250.2 5378.0