This document details how developers can use hardware tools like Servo and Sweetberry and software tools within dev-util/hdctools
and other repos to measure power on a Chrome OS device (DUT, device under test).
Servo-like devices, including Servo V2, Servo V4, Micro Servo and Suzy-Qable, can be used to measure power on the DUT with Analog-to-Digital Converters (ADCs) on the board. For simplicity, this doc refers to them as just “Servo” devices.
See Servo for more information on Servo.
Sweetberry or Servo INA adapter can be used when there are no ADCs on the DUT. Sweetberry is the preferred method. A hardware rework on the DUT is often required to place sense resistors on the power rails and to attach ‘Medusa style’ header (HIROSE DF13A-40DP-1.25V(55)) to the sense resistors and ground.
See Sweetberry Configuration for more information on Sweetberry.
Servo and Sweetberry can measure power on the DUT, but they have no awareness of what power rails are being measured, or what size the sense resistors are. Therefore, a configuration file is necessary to provide information about the hardware setup. This configuration file is usually manually created by an engineer and is fed into the power measurement software tool later.
File format: .py
See INA Configuration Files for instructions on how to write the configuration file.
There are some slight differences between configuration files for Servo and that for Sweetberry. See this example for configuration for Servo.
There are two ways to write Sweetberry configuration files. See servo_sweetberry_rails_addr.py
and servo_sweetberry_rails_pins.py
.
The .py
files created in the previous part need to be compiled into formats required by the software tool.
If you created or edited the .py
configuration file, first you need to run:
(chroot) $ cros_workon --host start dev-util/hdctools
This only needs to be run ONCE.
Then, every time after you edit the .py
configuration file, run:
(chroot) $ sudo emerge dev-util/hdctools
To verify that you have generated configuration files successfully, look into this directory:
(chroot) $ cd $(python -c 'import site; print(site.getsitepackages()[-1])')/servo/data/
File format: .xml
for servod, .board
and .scenario
for powerlog.
With servod moved to outside of chroot, build servod after generating configuration and start servod with the local build:
(outside) $ build-servod # For setup with on-board INA chip (outside) $ start-servod -c local -p $PORT_NUMBER --board $BOARD -- --config $CONFIG_FILE.xml # For setup with sweetberry only (outside) $ start-servod -c local -p $PORT_NUMBER -- --config $CONFIG_FILE.xml
Note that $CONFIG_FILE.xml
is generated in the previous step. Both dut-power
and dut-control
are servod clients that talk to servod and fetch power data from the Servo or Sweetberry.
You have to explicitly set $PORT_NUMBER to run servod-based tast test, such as meta.PowerServodWrapper, which by defaults uses 9999.
If the current-sensor data is to be read out from USB-C interface (CCD), the GSC must be configured to forward the I2C current sensor bus to the SBU (USB) interface. You can check whether this is already the case by running ccd
in GSC console:
>> ccd State: Locked Password: none Flags: 0x000000 Capabilities: 0000000000000000 UartGscRxAPTx Y 0=Default (Always) UartGscTxAPRx Y 0=Default (Always) UartGscRxECTx Y 0=Default (Always) UartGscTxECRx - 0=Default (IfOpened) FlashAP - 0=Default (IfOpened) FlashEC - 0=Default (IfOpened) OverrideWP - 0=Default (IfOpened) RebootECAP - 0=Default (IfOpened) GscFullConsole - 0=Default (IfOpened) UnlockNoReboot Y 0=Default (Always) UnlockNoShortPP Y 0=Default (Always) OpenNoTPMWipe - 0=Default (IfOpened) OpenNoLongPP - 0=Default (IfOpened) BatteryBypassPP Y 0=Default (Always) Unused Y 0=Default (Always) I2C - 0=Default (IfOpened) FlashRead Y 0=Default (Always) OpenNoDevMode Y 0=Default (Always) OpenFromUSB Y 0=Default (Always) OverrideBatt - 0=Default (IfOpened) APROCheckVC - 0=Default (IfOpened)
I2C
flag will be set to (Always)
if this bus can be accessed via CCD. (IfOpened)
means the bus is inaccessible by default.
To unlock the I2C bus, run ccd open
and follow the instructions printed on the console. ccd reset factory
will save these flags into GSC's non-volatile memory, so that the unlocked state will be retained. You can revert back to locked mode with ccd reset
(usually required before device leaves the factory).
Recommended, for users who only want measurements in power.
(outside) $ dut-power -- [arguments] # Example arguments for setup with sweetberry only (outside) $ dut-power -- --vbat-rate 0 -t 5
dut-power
queries the selected servod to read power measurements from the Servo or Sweetberry. See dut-power -h
for setting arguments. dut-power
works with both Servo and Sweetberry. It packs configuring the ADCs, reading data, calculating statistics, and saving to file into one command.
dut-power organizes results into a directory ‘power_measurements’ in a temp directory (without TMPDIR in the env, this just defaults to ‘/tmp’). In there, each board receives its own directory, and each measurement its own directory within those. Measurements are labeled by their powerstate and timestamp.
The board name and powerstate are queried from the DUT's EC, though this might fail, either due to EC communication issues, or because the user is using a servo device that is not a dut controller e.g. sweetberry. In those cases, they default to ‘unknown’ for board, and ‘S?’ for the powerstate.
Alternatively, they can be provided as command line arguments. If provided through the command line, they overwrite the EC values (we do not attempt to even read them)
dut-power --powerstate S0ix --board volteer -t 30 -w 10 -p 9998
This would read power wait for 10s before reading power for 30s through servod running at port 9998
and store the result at /tmp/power_measurements/volteer/S0ix_20210210-162609/
Lastly, the board name can also be provided through the environment variable BOARD
. To summarize the priorities of how the boardname is determined (descending priorities)
ec_board
through servodBOARD
environment variable'unknown'
e.g.
/tmp/power_measurements/volteer/S0_20201116-162609/ /tmp/power_measurements/unknown/S?_20201116-163909/
For power users, provides more info than power.
dut-control
can collect power measurements from both EC and on-board ADCs.
dut-control
can query battery power via EC’s connection (I2C) to the battery, namely ppvar_vbat
. On newer devices, same data averaged over 1 minute can be queried by avg_ppvar_vbat
.
dut-control
can query power rails specified in the configuration file.
dut-control
can query power, bus voltage and current for all rails above, and additionally shunt voltage for on-board ADCs.
The on-board ADCs can be configured to more accurately measure power depending on the size of the sense resistors and shunt voltage across the sense resistors. Choose from the follow quick configs:
Config | Context |
---|---|
regular_power | S0 measurements |
regular_power_no_hw_avg | S0 measurements w/out avg (for debug) |
low_power | < S0 measurements |
low_power_no_hw_avg | < S0 measurements w/out avg (for debug) |
Create helper variable, without ppvar_vbat
.
(outside) $ mv=$(dut-control -- bus_voltage_rails | cut -f 2 -d: | tr -d ',') (outside) $ ma=$(dut-control -- current_rails | cut -f 2 -d: | tr -d ',') (outside) $ mw=$(dut-control -- power_rails | cut -f 2 -d: | tr -d ',') (outside) $ cfg_reg=$(echo $mv | sed 's/_mv/_cfg_reg/g')
Configure on-board ADCs (everytime after running servod
).
(outside) $ for cfg in $cfg_reg ; do dut-control -- $cfg:regular_power $cfg; done
Or
(outside) $ for cfg in $cfg_reg ; do dut-control -- $cfg:low_power $cfg; done
Measure each power rail once.
(outside) $ dut-control -- $mv (outside) $ dut-control -- $ma (outside) $ dut-control -- $mw
And
(outside) $ dut-control -- avg_ppvar_vbat_mw (outside) $ dut-control -- avg_ppvar_vbat_ma (outside) $ dut-control -- avg_ppvar_vbat_mw
Or
(outside) $ dut-control -- ppvar_vbat_mv (outside) $ dut-control -- ppvar_vbat_ma (outside) $ dut-control -- ppvar_vbat_mw
Measure power for 1 second 30 times.
(outside) $ dut-control -- -t 30 -z 1000 $mw | grep @@ | cut -b 6-