Add common, media_ctrl and v4l2_ctrl modules with CLI drivers and docs

Modules (src/modules/):
- common/error: App_Error struct with structured detail union, error codes,
  app_error_print(); designed for future upgrade to preprocessor-generated
  location codes
- media_ctrl: media device enumeration, topology query (entities/pads/links),
  link enable/disable via Media Controller API (/dev/media*)
- v4l2_ctrl: control enumeration (with menu item fetching), get/set via
  V4L2 ext controls API, device discovery (/dev/video*)

All modules use -std=c11 -D_GNU_SOURCE, build artifacts go to build/ only.
Kernel-version-dependent constants guarded with #ifdef + #warning.

CLI drivers (dev/cli/):
- media_ctrl_cli: list, info, topology, set-link subcommands
- v4l2_ctrl_cli: list, controls, get, set subcommands

Docs (docs/cli/):
- media_ctrl_cli.md and v4l2_ctrl_cli.md with usage, examples, and
  context within the video routing system

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 21:40:37 +00:00
parent bf18054a2c
commit a29c556851
17 changed files with 1650 additions and 1 deletions

129
docs/cli/media_ctrl_cli.md Normal file
View File

@@ -0,0 +1,129 @@
# media_ctrl_cli
A development tool for exploring and configuring the Linux Media Controller pipeline. It wraps the `media_ctrl` module and provides a command-line interface to the Media Controller API (`/dev/media*`).
This tool is the counterpart to `media-ctl` from the `v4l-utils` package. It covers the same ground but is built on our own `media_ctrl` translation unit.
---
## Build
From the repository root:
```sh
make
```
Or from `dev/cli/` directly:
```sh
make media_ctrl_cli
```
The binary is placed in `dev/cli/`.
---
## Commands
### `list`
Enumerate all media devices present on the system.
```sh
./media_ctrl_cli list
```
Example output:
```
Media devices:
/dev/media0
/dev/media1
```
---
### `info <device>`
Show identification information for a media device.
```sh
./media_ctrl_cli info /dev/media0
```
Example output:
```
Device: /dev/media0
Driver: unicam
Model: unicam
Serial:
Bus info: platform:fe801000.csi
Media version: 5.15.0
Hardware rev: 0x00000000
Driver version: 5.15.0
```
---
### `topology <device>`
Show the full pipeline topology: all entities, their pads, and all links between them. This is the main tool for understanding how a camera pipeline is structured.
```sh
./media_ctrl_cli topology /dev/media0
```
Example output on a Raspberry Pi with an IMX477 camera:
```
Device: unicam (/dev/media0)
Entity 1: imx477 4-001a
type: v4l2-subdev (0x00020001)
flags: 0x00000000
pads: 1 links: 1
pad 0: source
link: entity 1 pad 0 -> entity 2 pad 0 [enabled]
Entity 2: unicam-image
type: devnode (0x00010001)
flags: 0x00000000
pads: 1 links: 1
device: 81:1
pad 0: sink
link: entity 1 pad 0 -> entity 2 pad 0 [enabled]
```
Each entity shows:
- **type** — the kernel entity function code and its human-readable name
- **pads** — each pad with its direction (source or sink)
- **links** — connections to other entity pads, with enabled/disabled state and whether the link is immutable
---
### `set-link <device> <src_entity>:<src_pad> <sink_entity>:<sink_pad> <0|1>`
Enable or disable a link between two pads. Entity IDs and pad indices are the numeric values shown in the `topology` output.
```sh
# Enable a link
./media_ctrl_cli set-link /dev/media0 1:0 2:0 1
# Disable a link
./media_ctrl_cli set-link /dev/media0 1:0 2:0 0
```
Immutable links cannot be changed and will return an error.
---
## Relationship to the Video Routing System
`media_ctrl_cli` exercises the `media_ctrl` module, which is used in the video routing system for:
- **Remote device enumeration** — a connecting node can query the media topology of a remote host to discover available cameras before opening any streams
- **Pipeline configuration** — setting pad formats and enabling links is required before a V4L2 capture node can be used, particularly on platforms like the Raspberry Pi where the sensor and capture node are separate media entities
See also: [`v4l2_ctrl_cli.md`](v4l2_ctrl_cli.md) for runtime camera parameter control.

147
docs/cli/v4l2_ctrl_cli.md Normal file
View File

@@ -0,0 +1,147 @@
# v4l2_ctrl_cli
A development tool for listing and adjusting V4L2 camera controls. It wraps the `v4l2_ctrl` module and provides a command-line interface for enumerating, reading, and writing camera parameters on `/dev/video*` devices.
This tool is the counterpart to `v4l2-ctl` from the `v4l-utils` package. It covers the same core functionality but is built on our own `v4l2_ctrl` translation unit.
---
## Build
From the repository root:
```sh
make
```
Or from `dev/cli/` directly:
```sh
make v4l2_ctrl_cli
```
The binary is placed in `dev/cli/`.
---
## Commands
### `list`
Enumerate all video devices present on the system.
```sh
./v4l2_ctrl_cli list
```
Example output:
```
Video devices:
/dev/video0
/dev/video1
```
---
### `controls <device>`
List all controls available on a device, including their current values, valid ranges, and — for menu controls — all available menu options.
```sh
./v4l2_ctrl_cli controls /dev/video0
```
Example output (Pi camera):
```
Controls on /dev/video0:
0x009e0903 Exposure Time (Absolute) int current=10000 default=10000 min=13 max=11766488 step=1
0x009e0902 Analogue Gain int current=1000 default=1000 min=1000 max=16000 step=1
0x00980913 Horizontal Flip bool current=0 default=0 min=0 max=1
0x00980914 Vertical Flip bool current=0 default=0 min=0 max=1
0x009e0905 Auto Exposure menu current=0 default=0 min=0 max=1
[0] Manual Mode
[1] Auto Mode
0x0098091f Auto White Balance bool current=1 default=1 min=0 max=1
```
Control types:
- `int` — integer value with min, max, and step
- `bool` — 0 or 1
- `menu` — discrete named options (shown with their labels)
- `int-menu` — discrete integer-valued options
- `int64` — 64-bit integer
- `bitmask` — bit field
---
### `get <device> <id>`
Read the current value of a single control by its numeric ID. The ID can be decimal or hexadecimal (with `0x` prefix).
```sh
./v4l2_ctrl_cli get /dev/video0 0x009e0903
```
Example output:
```
0x009e0903 = 10000
```
Control IDs are shown in hex in the `controls` output.
---
### `set <device> <id>=<value>`
Write a value to a control. The ID and value can both be decimal or hexadecimal.
```sh
# Set exposure time
./v4l2_ctrl_cli set /dev/video0 0x009e0903=5000
# Enable horizontal flip
./v4l2_ctrl_cli set /dev/video0 0x00980913=1
# Disable auto exposure (switch to manual)
./v4l2_ctrl_cli set /dev/video0 0x009e0905=0
```
The device will return an error if:
- The value is out of the control's min/max range
- The control is read-only
- The control does not exist on the device
---
## Common Control IDs
These IDs are standardised in the V4L2 specification and are consistent across devices that support them:
| ID | Name |
|---|---|
| `0x00980900` | Brightness |
| `0x00980901` | Contrast |
| `0x00980902` | Saturation |
| `0x00980913` | Horizontal Flip |
| `0x00980914` | Vertical Flip |
| `0x009e0903` | Exposure Time (Absolute) |
| `0x009e0902` | Analogue Gain |
| `0x009e0905` | Auto Exposure |
Camera-specific controls (ISP parameters, codec settings, etc.) will have IDs outside the standard ranges and are best discovered via the `controls` command.
---
## Relationship to the Video Routing System
`v4l2_ctrl_cli` exercises the `v4l2_ctrl` module, which is used in the video routing system for:
- **Remote parameter tuning** — a controlling node can adjust exposure, gain, white balance, and other parameters on a remote camera without SSH or local access
- **Control enumeration** — discovering the full set of parameters a camera supports, returned as structured data over the transport control channel
The Pi in the microscope setup runs a V4L2 control endpoint that accepts these operations via the transport protocol. `v4l2_ctrl_cli` lets you perform the same operations locally for development and calibration.
See also: [`media_ctrl_cli.md`](media_ctrl_cli.md) for pipeline topology and pad format configuration.