N900 software power management

This is a work in progress. It is not yet ready for public consumption. Please don't link it into wiki yet.

Contents

Overview

This page may be useful to application developers, as well as those interested in reducing power usage of software by configuring it correctly.

Why software uses power

Software should use power to do what the user wants in the most battery efficient way, without letting the battery efficiency get in the way unless it's unavoidable.

For example, it might be nice to always keep the backlight on but to get more than a few hours battery life the compromise of blanking the screen when inactive and on battery is usually made.

Direct

Direct power use is quite simple. The intended function of the application uses power. For example, 'flashlight'.

This application turns on the LED Flash so the user can see.

Once it is active, it needs no CPU, and the screen can be blanked. Almost all of the battery usage in this mode is to cause the desired effect.

'Flashlight' as an application could be viewed as 95% efficient - only 5% or so of the battery is used for stuff other than keeping the flash lit.

Indirect

Indirect is when there is no direct hardware way to perform an action, and some part of the system has to be made to do this without the user explicitly turning it on.

For example, a task-list application might want to alert the user if they get within a certain distance of a task, so they could consider doing it.

So, the application needs some means to get a notion of location. For example, it could run the GPS, or scan wifi networks in range.

The user doesn't know or care about how the application does it, but how it is done may have a significant effect on battery life.

User Training

User training is very important, in some ways more important than the rest of this guide.

In some cases, there is no way for the user to avoid battery use.

They need to see - they turn on 'flashlight'.

In others, minor changes to their behaviour, that might even make their experience better, may greatly change battery life.

For example, when listening to audio, if the user knows that instead of streaming programs from their local radio station over 3g, both FM radio or downloading a podcast over wifi would use a tiny fraction of the power, they can make that choice.

Pathological

The application chooses - or the system software only permits - an inefficient way to perform a task.

For example, an alarm application that after it has been told to beep after 12 hours, turns on the audio system immediately to make that beep, then checks every second to see if the 12 hours is up yet.

Details of each case, with examples.

Direct

Indirect

Pathological

Avoidable

  • Not properly becoming idle when the screen is locked.
  • Leaving GPS on when screen is locked, when it does not aid the application. (for example, if the application gets a GPS fix, displays location related data, and does not turn off the GPS, even when the screen is locked).
  • Keeping audio active when idle. Pulseaudio can use a large amount of power in some cases, playing 'silence'.
  • Improper use of timers. If you need to do something every second to update the display, don't do it when the screen is locked, or your window is hidden.
    • If you need to update internal state, and you normally do this every time you update the window, consider carefully how infrequently you can do this when the user is not looking at the display.
  • Listening to events that are irrelevant. When you got a mainloop with a central wait like e.g pause() (2), then you should not create a situation where irrelevant events cause signals sent to the waiting process and cause "active discarding" of the signal. Generally whenever there's a test in a signal handler subroutine that discards certain classes of signalled events, you should check if there's no way to disable the signals from being sent to your process at all. (Example: a widget that doesn't react to any touchscreen events is maybe better off not to receive any X events at all. Especially applicable if this property not to care about touchscreen events is just temporary - don't make the process use CPU time just to decide it's been an event that doesn't matter)

By Design

Unavoidable

Measuring power usage

Tools

Powertop

The output of powertop, when run as root, is shown below, with some comments. Much of the output is probably not directly useful for you.

Powertop 1.13.3
status: Unknown job: pmtrackerdaemon
Sleeping for 11 seconds before sampling
Collecting data for 30 seconds
Sample interval was 00m 30s 18921us

Initial block, with normal error.

C#      | Ratio  | Avg/dura | Frequency | Ratio
--------+--------+----------+-----------+--------+
     C0 |   0.3% |          |   600 MHz |   0.0% |
     C1 |   0.0% |    0.2ms |   550 MHz |   0.0% |
     C2 |   0.4% |    4.7ms |   500 MHz |   0.0% |
     C3 |   4.5% |  134.6ms |   250 MHz | 100.0% |
     C4 |  94.8% | 2032.8ms | 

During this period, the CPU was active 0.3% of the time (in the C0 state). Of this 0.3% of the time, 100% of it - so 0.3% total - was spent at 250MHz.

It spent very little time in the C1 through C3 states, which are increasing depths of sleep, and the majority of the time (94% of the 30s - or about 28s) in the C4 state which is the deepest state that uses least power.

The Average duration is how long it typically spent in each state. In this case the C4 duration indicates that it's spending typically over 2 seconds asleep at a time - this is the most efficient power state.

If you are testing an application, and when idle you get numbers close to these, then battery life is unlikely to be affected by the application. (though there may be ways to make it use power when idle that you've missed).

IRQ#    | Activity   | Type           | Name
--------+------------+----------------+---------------------------
     56 |        129 |           INTC | i2c_omap
     12 |         59 |           INTC | DMA
     37 |         48 |           INTC | gp
     11 |         39 |           INTC | prcm
     57 |         28 |           INTC | i2c_omap
    202 |          3 |           GPIO | wl1251

This shows how many interrupts occurred in the period. Most of these are not influenced directly by user software. The exception may be wl1251 - this is the wireless card.

PID#    | Activity   | Name           | Function Entry (Expire)
--------+------------+----------------+---------------------------
      0 |         20 |  <kernel core> | tick_nohz_restart_sched_tick (tick_sched_timer)
     37 |         14D|            awk | cpufreq_governor_dbs (delayed_work_timer_fn)
      0 |         12 |  <kernel core> | hrtimer_start (tick_sched_timer)
    753 |          7 |      bme_RX-51 | sys_timer_settime (posix_timer_fn)
      0 |          6 |  <kernel core> | queue_delayed_work (delayed_work_timer_fn)
    470 |          3 |         wl12xx | schedule_timeout (process_timeout)

(30 lines deleted)

This is one important bit. It lists process ID (0 is internal kernel), how many times in the 30s it was woken, and what the name of the system waking it up was, as well as what timer ran out.

The 'awk' here is a a kernel bug, it should read '<kernel core>' as this is really the kernel checking if it needs to change CPU speeds.

This shows the only user process is bme_RX-51 - this is BME - the battery managment entity - which wakes every few seconds to monitor the battery.



Power domain activity breakdown
Domain  | % of time spent in states
--------+---------+---------+---------+---------+----------
usbhost |OFF: 100%|RET:   0%|INA:   0%| ON:   0%| now:(OFF)
    sgx |OFF: 100%|RET:   0%|INA:   0%| ON:   0%| now:(OFF)
    per |OFF:  99%|RET:   0%|INA:   0%| ON:   0%| now:(ON)
    dss |OFF: 100%|RET:   0%|INA:   0%| ON:   0%| now:(OFF)
    cam |OFF: 100%|RET:   0%|INA:   0%| ON:   0%| now:(OFF)
   core |OFF:  94%|RET:   4%|INA:   0%| ON:   0%| now:(ON)
   neon |OFF:  94%|RET:   4%|INA:   0%| ON:   0%| now:(ON)
    mpu |OFF:  94%|RET:   4%|INA:   0%| ON:   0%| now:(ON)
   iva2 |OFF: 100%|RET:   0%|INA:   0%| ON:   0%| now:(OFF)

This shows how often various parts of the chip were switched on/off - this will normally not be useful.

Clock activity breakdown at end of period
Domain  | Active clocks
--------+---------------+---------------+------------------
   core |          SDRC | HSOTGUSB_IDLE |      OMAPCTRL 
        |     MAILBOXES |
   wkup |          GPT1 |       32KSYNC |         GPIO1 
        |          WDT1 |
  ckgen |          CORE |          PERI |           96M 
        |           48M |           12M |           54M 
        |      EMU_CORE |
    per |         GPIO2 |         GPIO3 |         GPIO4 
        |         GPIO5 |         GPIO6 |

This is also not usually useful.

Total wakeups   394,  13.1/s | IRQ  306,  10.2/s | Timers   88,   2.9/s
HW wakeups       39,   1.3/s |     Real gp_timers expired   48,   1.6/s



Strace

The utility strace can be downloaded from the sdk/tools repository using

apt-get install strace


strace shows what system calls the process is making. The manpage has more information.

The most basic usage is:

strace ls

Image:strace.png

Though you can also attach to a running process - say process 833.

strace -p 833

Htop

Htop is a much more flexible tool than the installed version of top.

It is in extras, and can be installed simply from the command line by issuing the command

apt-get install htop

Full documentation can be found at the htop project pages on sourceforge


image:htop.png