AOSP Framework & Internals
5 min read

Sensors Driver (IIO)

Explore how Android reads environmental data like acceleration and light using the Industrial I/O subsystem.

Hardware sensors generate analog physical data that needs a path into the digital Android framework. Early on, sensor drivers on Android were incredibly fragmented. Hardware manufacturers either wrote completely custom character drivers or abused the Linux input subsystem. The kernel needed a standardized way to handle environment sensors without requiring custom C code just to read basic light levels. This chaos is why Android adopted the Industrial I/O subsystem.

The Industrial I/O subsystem provides a unified interface in sysfs. It treats hardware sensors as standard devices that output formatted data streams. Android's sensor HAL can read a standardized file path to get the current sensor value. The kernel driver handles the hardware-specific communication behind the scenes. This standardization means the framework does not care whether the sensor uses I2C or SPI.

This diagram shows how the IIO subsystem bridges user space and hardware. It clarifies where the kernel boundaries sit. Notice how sysfs acts as the translation layer between the raw kernel driver and the Android framework.

The HAL reads the standard sysfs files exposed by IIO. Core kernel code then translates those requests into physical bus transactions.

You can inspect this directly on any rooted Android device. The IIO subsystem exposes its devices under a standard directory path. Reading a file gives you the raw output from the analog converter.

# List all IIO devices exposed by the kernel
adb shell ls /sys/class/iio:device0/

# Read the raw X-axis value from an accelerometer
adb shell cat /sys/class/iio:device0/in_accel_x_raw

Common Mistake: Do not rely on sysfs polling for high-frequency data. Reading a text file 200 times a second creates massive CPU overhead.

Reading single values via sysfs works for occasional checks. But how does an application handle continuous data, like a game reading head position at 120Hz?

Interrupts and Ring Buffers

Blindly reading sensor files in a loop wastes battery life. In a naive polling setup, the CPU sets a timer and constantly wakes up to check if the sensor has new values. If the phone is sitting flat on a desk, the CPU burns power asking for data that has not changed. The system needs a way to sleep until actual physical movement occurs.

Modern sensor drivers solve this using hardware interrupts and ring buffers. The kernel configures the sensor chip to generate a signal only when new data is ready. When movement occurs, the sensor pulls a dedicated GPIO pin low. This hardware interrupt wakes up the IIO driver precisely when needed.

Once awake, the IIO driver reads the new values over the I2C bus. It pushes these values into an in-kernel ring buffer. The Android sensor service in user space waits on this buffer using an event loop. It consumes batches of sensor events efficiently without busy-waiting.

This interrupt-driven approach saves power when the device is idle. But even with interrupts, waking up the main application processor for every single footstep while walking will drain the battery quickly.

Offloading to the Context Hub

The main Android CPU consumes far too much power to handle continuous background tasks. Pedometer step counting and orientation calculations require constant data processing. If the main processor stays awake to process these events, standby battery life drops to zero. The system needs a dedicated, low-power component to handle this relentless stream of data.

Android architectures offload sensor management to a Context Hub. A Context Hub is a tiny microcontroller embedded alongside the main CPU. It runs a dedicated real-time operating system optimized for ultra-low power consumption. The main processor and Linux kernel can go into deep sleep while the Context Hub stays awake.

The Context Hub continuously reads the accelerometer and gyroscope over its own private bus. It performs all the heavy math for sensor fusion locally. This coprocessor only fires an interrupt to wake up the main kernel when something important happens, like the user picking up the phone.

The following sequence diagram shows the communication flow between the hardware and the main CPU. It demonstrates how the Context Hub isolates the main processor from high-frequency sensor noise. Pay attention to the interrupt that finally wakes the kernel.

The sensor talks to the Context Hub continuously. In contrast, the main kernel only wakes up to receive a processed batch of data.

In this modern architecture, the Linux IIO driver does not actually talk to the hardware sensors directly. Instead, the kernel driver acts solely as a communication bridge to the Context Hub firmware. The IIO subsystem still exposes the same sysfs files and ring buffers to Android. Higher-level framework code gets standard data while the main processor sleeps. But raw numbers in a kernel buffer are useless to an application developer. The system still needs a central service to coordinate multiple apps asking for sensor data simultaneously without granting them direct hardware access.