Skip to content
Libre Computer
Platform

Module 11 ยท Lab 8

Drivers

You write a driver for a part twice over: first as a tested userspace library, then by comparing it with what a kernel driver gives, and, as a stretch, by building and loading a minimal kernel module.

Key ideas

  • User space and kernel space: applications run at EL0 with no direct access to hardware; the kernel runs at EL1 and owns it.
  • The driver model: buses, devices and drivers. The kernel matches a driver to a device (from the device tree in module 9) and calls its probe function.
  • Interfaces such as spidev and i2c-dev let a userspace program talk to a bus directly. That is quick to write and safe to crash, and is often right for one program and one part.
  • A kernel driver is better when several programs share a part, when it needs fast interrupt handling, or when it should appear through a standard interface. The kernel already has a driver for the MCP3008 ADC in its industrial I/O subsystem; part of the lab is explaining what it adds.
  • A kernel module is code loaded into the running kernel: an init function, an exit function and whatever it registers in between.

On the bench

In short, what you do in lab 8, where the steps are given in full:

  1. Write a userspace library for the MCP3008 with a clean API, unit tests against a mocked SPI bus, and a small command-line tool.
  2. Bind the kernel's own MCP3008 driver with an overlay, read the same channel through /sys, and compare.
  3. Stretch: build and load a minimal module that registers a character device reporting a counter, and read its messages in dmesg.

Resources

ResourceUse in this module
Kernel driver API documentationThe driver model, SPI and I2C
Kernel industrial I/O documentationThe subsystem the kernel's ADC drivers use
libretech-wiring-toolOverlays to bind a kernel driver to a part