Day19 - I2C Sensor Driver (Kernel)¶
Overview¶
In this lab, we implemented a Linux I2C sensor driver using:
- STM32 as a fake I2C slave device
- Raspberry Pi as I2C master
- Linux kernel i2c_driver framework
Key topics:
- I2C driver probe/remove lifecycle
- Device Tree binding
- Register-based device abstraction
- sysfs interface design
- Synchronization using mutex
System Architecture¶
STM32 (I2C slave)
↓
Register Map (fake sensor)
↓
Linux I2C Driver
↓
sysfs (/sys/bus/i2c/devices/1-0048/)
↓
User Space (cat / echo)
Register-Based Device Model¶
The sensor is designed as a register-based device.
| Address | Name | Description |
|---|---|---|
| 0x00 | CHIP_ID | Device ID |
| 0x01 | CONFIG | Configuration |
| 0x02 | TEMP_MSB | Temperature MSB |
| 0x03 | TEMP_LSB | Temperature LSB |
| 0x04 | STATUS | Status flags |
| 0x05 | UPDATE_PERIOD | Update interval |
| 0x06 | COMMAND | Command register |
I2C Driver Lifecycle¶
Probe¶
- Called when device is matched via Device Tree
- Initialize driver context
- Verify CHIP_ID
- Create sysfs attributes
Remove¶
- Remove sysfs group
- Release allocated resources
Device Tree Binding¶
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2712";
fragment@0 {
target = <&i2c1>;
__overlay__ {
status = "okay";
myi2c_sensor@48 {
compatible = "myvendor,myi2c-sensor";
reg = <0x48>;
};
};
};
};
Sysfs Interface Design¶
Data Plane vs Control Plane¶
This driver separates:
- Data plane → sensor readings
- Control plane → configuration / commands
Sysfs Attributes¶
| Attribute | Type | Description |
|---|---|---|
| chip_id | RO | Device ID |
| temp_raw | RO | Raw sensor value |
| temp_input | RO | Temperature (milli-degree Celsius) |
| update_once | WO | Trigger measurement |
| config | RW | Configuration register |
| status | RO | Status register |
| update_period | RW | Update interval |
Temperature Representation¶
The driver exports temperature in milli-degree Celsius (m°C).
Example:
- raw value = 2529 → 25.29°C
- temp_input = 25290
Reason:
- sysfs is a stable kernel ABI
- values must be machine-readable
- formatting should be done in user space
Synchronization¶
All I2C operations are protected using a mutex:
This prevents race conditions between concurrent sysfs accesses.
Key Design Decisions¶
- Use register abstraction (real hardware model)
- Separate control/data plane
- Use sysfs instead of ioctl
- Use milli-degree for standardization
- Use mutex for safe access
Known Limitations¶
- No interrupt-based data ready
- No caching mechanism
- Not integrated with hwmon subsystem
- Polling-based update
Next Step¶
- Convert driver to hwmon subsystem
- Support standard interface: