Skip to content

Instantly share code, notes, and snippets.

@mthierry
Created March 23, 2016 18:09
Show Gist options
  • Save mthierry/ec1379359964fabb1167 to your computer and use it in GitHub Desktop.
Save mthierry/ec1379359964fabb1167 to your computer and use it in GitHub Desktop.
#!/bin/sh
#
# Tool for running a suspend/resume on android
# Copyright (c) 2014, Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
#
# Authors:
# Todd Brandt <[email protected]>
#
KVERSION=""
MODES=""
MODE="mem"
RTCPATH=""
TPATH="/sys/kernel/debug/tracing"
EPATH="/sys/kernel/debug/tracing/events/power"
FTRACECHECK="yes"
TRACEEVENTS="yes"
HEADER=""
FTRACE="ftrace.txt"
DMESG="dmesg.txt"
LOGFILE="log.txt"
WAKETIME=""
DISPLAY=""
checkDisplay() {
SCRSTAT=`dumpsys power 2>&1 | grep mScreenOn`
if [ -n "$SCRSTAT" ]; then
for i in $SCRSTAT; do break; done
if [ $i = "mScreenOn=false" ]; then
DISPLAY="OFF"
else
DISPLAY="ON"
fi
fi
}
checkFileRead() {
if [ ! -e $1 ]; then
onError "$1 not found"
fi
if [ ! -r $1 ]; then
onError "$1 not readable"
fi
}
checkFileWrite() {
if [ ! -e $1 ]; then
onError "$1 not found"
fi
if [ ! -w $1 ]; then
onError "$1 not writeable"
fi
}
writeToSysFile() {
if [ ! -e $1 ]; then
onError "$1 not found"
fi
if [ ! -w $1 ]; then
onError "$1 not writeable"
fi
echo "$2" > "$1"
logEntry "$1 = \"$2\""
}
checkStatus() {
CHECK="no"
for m in $MODES; do
if [ $m = "$MODE" ]; then
CHECK="yes"
fi
done
if [ $CHECK != "yes" ]; then
onError "mode ($MODE) is not supported"
fi
if [ $FTRACECHECK != "yes" ]; then
echo " ERROR: ftrace is unsupported {"
echo " Please rebuild the kernel with these config options:"
echo " CONFIG_FTRACE=y"
echo " CONFIG_FUNCTION_TRACER=y"
echo " CONFIG_FUNCTION_GRAPH_TRACER=y"
echo " }"
exit
fi
if [ $TRACEEVENTS != "yes" ]; then
echo " ERROR: trace events missing {"
echo " Please rebuild the kernel with the proper config patches"
echo " https://github.com/01org/suspendresume/tree/master/config"
echo " }"
exit
fi
if [ -n "$WAKETIME" -a -z "$RTCPATH" ]; then
onError "rtcwake isn't available"
fi
if [ ! -w $PWD ]; then
onError "read-only permissions for this folder"
fi
}
printStatus() {
echo "host : $HOSTNAME"
echo "kernel : $KVERSION"
echo "modes : $MODES"
checkDisplay
if [ -n "$DISPLAY" ]; then
echo "display : $DISPLAY"
fi
if [ -n "$RTCPATH" ]; then
echo "rtcwake : SUPPORTED"
else
echo "rtcwake : NOT SUPPORTED (no rtc wakealarm found)"
fi
if [ $FTRACECHECK != "yes" ]; then
echo " ftrace: NOT SUPPORTED (this is bad) {"
echo " Please rebuild the kernel with these config options:"
echo " CONFIG_FTRACE=y"
echo " CONFIG_FUNCTION_TRACER=y"
echo " CONFIG_FUNCTION_GRAPH_TRACER=y"
echo " }"
else
echo "ftrace : SUPPORTED"
echo "trace events {"
files="suspend_resume device_pm_callback_end device_pm_callback_start"
for f in $files; do
if [ -e "$EPATH/$f" ]; then
echo " $f: FOUND"
else
echo " $f: MISSING"
fi
done
if [ $TRACEEVENTS != "yes" ]; then
echo ""
echo " one or more trace events missing!"
echo " Please rebuild the kernel with the proper config patches"
echo " https://github.com/01org/suspendresume/tree/master/config"
fi
echo "}"
fi
if [ $FTRACECHECK = "yes" -a $TRACEEVENTS = "yes" ]; then
echo "status : GOOD (you can test suspend/resume)"
else
echo "status : BAD (system needs to be reconfigured for suspend/resume)"
fi
}
init() {
if [ -z "$HOSTNAME" ]; then
HOSTNAME=`hostname 2>/dev/null`
fi
checkFileRead "/proc/version"
# sometimes awk and sed are missing
for i in `cat /proc/version`; do
if [ $i != "Linux" -a $i != "version" ]; then
KVERSION=$i
break
fi
done
checkFileRead "/sys/power/state"
MODES=`cat /sys/power/state`
RTCPATH="/sys/class/rtc/rtc0"
if [ -e "$RTCPATH" ]; then
if [ ! -e "$RTCPATH" -o ! -e "$RTCPATH/since_epoch" -o \
! -e "$RTCPATH/wakealarm" ]; then
RTCPATH=""
fi
fi
files="buffer_size_kb current_tracer trace trace_clock trace_marker \
trace_options tracing_on available_filter_functions \
set_ftrace_filter set_graph_function"
for f in $files; do
if [ ! -e "$TPATH/$f" ]; then
FTRACECHECK="no"
fi
done
files="suspend_resume device_pm_callback_end device_pm_callback_start"
for f in $files; do
if [ ! -e "$EPATH/$f" ]; then
TRACEEVENTS="no"
fi
done
STAMP=`date "+suspend-%m%d%y-%H%M%S"`
HEADER="# $STAMP $HOSTNAME $MODE $KVERSION"
}
setAlarm() {
if [ -z "$WAKETIME" ]; then
return
fi
checkFileRead "$RTCPATH/since_epoch"
writeToSysFile "$RTCPATH/wakealarm" "0"
NOW=`cat $RTCPATH/since_epoch`
FUTURE=$(($NOW+$WAKETIME))
writeToSysFile "$RTCPATH/wakealarm" "$FUTURE"
}
printHeader() {
echo ""
echo "------------------------------------"
echo " Suspend/Resume timing test "
echo "------------------------------------"
echo "hostname : $HOSTNAME"
echo "kernel : $KVERSION"
echo "mode : $MODE"
echo "ftrace out : $PWD/$FTRACE"
echo "dmesg out : $PWD/$DMESG"
echo "log file : $PWD/$LOGFILE"
echo "------------------------------------"
}
printHelp() {
echo ""
echo "USAGE: android.sh command <args>"
echo ""
echo "COMMANDS:"
echo ""
echo " help"
echo " print this help text"
echo ""
echo " status"
echo " check that the system is configured properly"
echo ""
echo " capture-start"
echo " prepare the system to capture data on the next suspend/resume"
echo " the user should then initiate a normal suspend/resume"
echo ""
echo " capture-end"
echo " collect the data that's been captured in ftrace"
echo " the data can then be processed by analyze_suspend"
echo ""
echo " suspend <mem/freeze/standby/disk> [waketime]"
echo " force a suspend/resume and gather ftrace/dmesg data"
echo " - mode : suspend mode (required)"
echo " - waketime : wakeup alarm time in seconds (optional)"
echo ""
}
onError() {
echo "ERROR: $1"
exit
}
logStart() {
echo "------------------------------------" > $LOGFILE
echo "hostname : $HOSTNAME" >> $LOGFILE
echo "kernel : $KVERSION" >> $LOGFILE
echo "mode : $MODE" >> $LOGFILE
echo "ftrace out : $PWD/$FTRACE" >> $LOGFILE
echo "dmesg out : $PWD/$DMESG" >> $LOGFILE
echo "log file : $PWD/$LOGFILE" >> $LOGFILE
echo "------------------------------------" >> $LOGFILE
date "+%T: logging started" >> $LOGFILE
}
logEnd() {
date "+%T: logging finished" >> $LOGFILE
}
logEntry() {
LINE=`date "+%T: $1"`
echo "$LINE" >> $LOGFILE
if [ "$2" = "show" ]; then
echo "$LINE"
fi
}
suspendPrepare() {
printHeader
checkDisplay
if [ "$DISPLAY" = "OFF" ]; then
logEntry "waking up the display" "show"
input keyevent 26
fi
logEntry "ftrace setup start" "show"
#rm -f $DMESG
#rm -f $FTRACE
echo -n `date "+%T: ftrace is being configured"`
writeToSysFile "$TPATH/tracing_on" "0"
echo -n "."
writeToSysFile "$TPATH/trace_clock" "global"
echo -n "."
writeToSysFile "$TPATH/current_tracer" "nop"
echo -n "."
writeToSysFile "$TPATH/buffer_size_kb" "1000"
echo -n "."
writeToSysFile "$EPATH/suspend_resume/enable" "1"
echo -n "."
writeToSysFile "$EPATH/device_pm_callback_end/enable" "1"
echo -n "."
writeToSysFile "$EPATH/device_pm_callback_start/enable" "1"
echo -n "."
writeToSysFile "$TPATH/trace" ""
echo -n "."
dmesg -c > /dev/null
echo "done"
logEntry "ftrace setup complete" "show"
writeToSysFile "$TPATH/tracing_on" "1"
logEntry "ftrace is ON"
logEntry "waiting to capture suspend/resume data..." "show"
}
suspendComplete() {
echo ""
logEntry "checking for suspend/resume data..." "show"
logEntry "ftrace is OFF"
checkFileRead "$TPATH/trace"
writeToSysFile "$TPATH/tracing_on" "0"
logEntry "capturing $FTRACE" "show"
echo $HEADER > $FTRACE
cat $TPATH/trace >> $FTRACE
logEntry "flushing the ftrace buffer"
writeToSysFile "$TPATH/trace" ""
logEntry "capturing $DMESG" "show"
echo $HEADER >> $DMESG
logEntry "flushing the dmesg buffer"
dmesg -c > $DMESG
n=0
while read -r line
do
n=$(($n+1))
if [ $n -gt 12 ]; then break; fi
done < $FTRACE
if [ $n -le 12 ]; then
logEntry "NO FTRACE DATA FOUND" "show"
echo ""
echo "There's been no PM activity since capture-start was called"
echo ""
else
logEntry "FTRACE DATA IS AVAILABLE" "show"
echo ""
echo "You can retrieve the data with adb"
echo "adb pull $PWD/$FTRACE"
echo "adb pull $PWD/$DMESG"
echo "adb pull $PWD/$LOGFILE"
echo ""
echo "Run analyze_suspend on the ftrace data to produce an output.html"
echo "analyze_suspend.py -ftrace ftrace.txt"
echo ""
fi
}
forceSuspend() {
checkFileWrite "/sys/power/state"
checkFileWrite "$TPATH/trace_marker"
suspendPrepare
NOW=`date "+%T"`
if [ -z "$WAKETIME" ]; then
echo "SUSPEND START @ $NOW (press a key to resume)"
else
echo "SUSPEND START @ $NOW (rtcwake in $WAKETIME seconds)"
setAlarm
fi
echo "<adb connection will now terminate>"
writeToSysFile "$TPATH/trace_marker" "SUSPEND START"
logEntry "suspend start"
writeToSysFile "/proc/sys/kernel/printk" "8 8 8 8"
# execution will pause here
writeToSysFile "/sys/power/state" "$MODE"
logEntry "resume end"
writeToSysFile "$TPATH/trace_marker" "RESUME COMPLETE"
writeToSysFile "/proc/sys/kernel/printk" "7 4 1 7"
suspendComplete
}
if [ $# -lt 1 ]; then
printHelp
exit
fi
COMMAND=$1
shift
case "$COMMAND" in
help)
printHelp
;;
status)
init
printStatus
;;
capture-start)
init
checkStatus
logStart
suspendPrepare
echo ""
echo "READY TO GO!"
echo ""
echo "1) exit adb shell"
echo "2) disconnect the usb cable"
echo "3) allow the device to suspend by timing out"
echo "4) wake the device back up"
echo "5) reconnect and run 'sh android.sh capture-end'"
echo ""
;;
capture-end)
init
checkStatus
suspendComplete
logEnd
;;
suspend)
if [ $# -lt 1 ]; then
printHelp
echo ""
onError "suspend requires a mode (i.e. mem)"
fi
MODE=$1
if [ $# -gt 1 ]; then
WAKETIME=$2
CHECK=$((0+$WAKETIME))
if [ $CHECK -le 0 ]; then
onError "$WAKETIME is not a valid positive integer"
fi
fi
logStart
init
checkStatus
forceSuspend
logEnd
;;
*)
printHelp
echo ""
onError "Invalid command ($COMMAND)"
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment