Skip to content

drivers/bus_i2c_busdev.h: header not self-contained (uses extDevice_t without including drivers/bus.h) #1115

@nerdCopter

Description

@nerdCopter

Problem

src/main/drivers/bus_i2c_busdev.h uses extDevice_t and uint8_t in its function prototypes but does not #include "drivers/bus.h" (which defines extDevice_t) or any stdint/platform header. The header compiles only if every caller happens to include drivers/bus.h before drivers/bus_i2c_busdev.h.

// src/main/drivers/bus_i2c_busdev.h
#pragma once

bool i2cBusWriteRegister(const extDevice_t *dev, uint8_t reg, uint8_t data);
bool i2cBusReadRegisterBuffer(const extDevice_t *dev, uint8_t reg, uint8_t *data, uint8_t length);
uint8_t i2cBusReadRegister(const extDevice_t *dev, uint8_t reg);

extDevice_t is defined in drivers/bus.h. uint8_t comes from <stdint.h> (usually pulled in transitively). Neither is made available by this header directly.

Current state (not a bug today)

The existing callers of this header (src/main/drivers/bus_i2c_busdev.c, the three I2C sensor init files) happen to include drivers/bus.h first, so the latent issue doesn't fire. Compilation is clean today.

It did fire transiently during the Stage J I2C bus-resource split refactor (see PR for context, stage branched from #1114): adding the include to sensors/compass.c in the file's existing include-block order (bus_i2c → bus_spi → bus) placed bus_i2c_busdev.h before bus.h, which produced:

./src/main/drivers/bus_i2c_busdev.h:23:31: error: unknown type name 'extDevice_t'

The working fix in the Stage J commit was to reorder the include block in compass.c so bus.h precedes bus_i2c_busdev.h. That workaround is brittle — any future include ordering change or new caller can trigger the same error.

This is a hygiene/forward-compat issue, not a functional bug.

Upstream comparison

Betaflight 4.5-maintenance has the same latent issue in the equivalent header (betaflight/src/main/drivers/bus_i2c_busdev.h is also header-only with no includes). Fixing on our side introduces a minor delta vs BF 4.5; so does leaving it and working around it per-caller. Either is acceptable; the fix is more robust.

Proposed fix

Make the header self-contained:

// src/main/drivers/bus_i2c_busdev.h
#pragma once

#include <stdbool.h>
#include <stdint.h>

#include "drivers/bus.h"

bool i2cBusWriteRegister(const extDevice_t *dev, uint8_t reg, uint8_t data);
...

Sibling consideration: if BF's behavior is preferred for paste-and-tweak alignment, leave the header unchanged but establish a coding-standard convention (documented in AGENTS.md or similar) that drivers/bus.h must precede drivers/bus_i2c_busdev.h in every caller. Less robust than making the header self-contained.

History / origin

Pre-existing since the header was introduced (predates the ongoing extDevice_t refactor). Surfaced during Stage J (I2C bus-resource split) implementation, 2026-04-22. Per the scope-boundary rule established in #1111 review (pre-existing smells get separate issue tickets, not fixes in scoped refactor PRs), filed here for future cleanup.

Acceptance

  • drivers/bus_i2c_busdev.h includes drivers/bus.h (directly or via forward-declaration) and compiles cleanly regardless of caller include ordering.
  • make test passes.
  • Build passes on at least one I2C-heavy target (e.g. any target with a compass or barometer configured).
  • Optional: revert the compass.c include-block reordering introduced as the Stage J workaround (harmless to leave).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions