Architecture¶
How the driver is put together: the layers, the CEVA SH-2 library underneath, and how one call reaches the hub.
Figure description and sources
From top to bottom. Your application talks to one BNO085
Drawn from: inc/bno08x.hpp BNO085 public members; inc/bno08x_comm_interface.hpp CommInterface; figure module docs/diagrams/figures/driver-layers.py.
The layers¶
| Layer | Where | Depends on | You change it when |
|---|---|---|---|
Hardware-agnostic core: BNO085<Comm> |
inc/bno08x.hpp |
Interface, SH-2 library | Never |
| CEVA SH-2 and SHTP library | src/sh2/ |
sh2_Hal_t from the core |
For CEVA fixes |
Communication interface: bno08x::CommInterface<Derived> |
inc/bno08x_comm_interface.hpp |
Your port | Never |
| Platform port: your class | Your project | Your SDK | Per MCU (Porting) |
Everything above the port is the same on ESP32, STM32, a Linux host or the unit-test mock. That is how the host tests run the real driver code without hardware.
How one call reaches the hub¶
sequenceDiagram
participant A as Application
participant D as BNO085 core
participant S as SH-2 library
participant P as Your port
A->>D: EnableSensor(RotationVector, 10)
D->>D: cache 10 000 µs for re-enable after a reset
D->>S: sh2_setSensorConfig(id, interval_us)
S->>P: Write(Set Feature transfer)
A->>D: Update()
D->>S: sh2_service()
S->>P: Read(buffer, 1024)
P-->>S: one SHTP transfer (or 0)
S-->>D: sensorCallback(event)
D->>D: decode into SensorEvent, set the new-data flag
D-->>A: your callback(SensorEvent)
The SH-2 library calls the port through a C function table (sh2_Hal_t: open, close, read, write,
getTimeUs). The core fills it with static trampolines that forward to your port's Open(), Close(), Read(),
Write() and GetTimeUs().
Three modes, one object¶
The port's GetInterfaceType() decides what the object may do, and a small state machine
(BNO085DriverState) keeps the modes apart:
stateDiagram-v2
[*] --> Closed
Closed --> Sh2Active: Begin() (I2C, SPI, UART)
Sh2Active --> Closed: Close()
Closed --> RvcActive: BeginRvc() (UARTRVC)
RvcActive --> Closed: Close() / CloseRvc()
Closed --> DfuInProgress: Dfu...() (I2C, SPI, UART)
Sh2Active --> DfuInProgress: Dfu...() closes SH-2 first
DfuInProgress --> Closed: transfer done or failed
A call for the wrong interface fails with SH2_ERR_BAD_PARAM; a call in the wrong state fails with
SH2_ERR_OP_IN_PROGRESS. GetLastError() returns the code.
Design choices¶
- CRTP, not virtual functions. The interface is a template parameter. The compiler sees your port's methods
directly and inlines them: no vtable, no RTTI. The cost is that the driver type names the port:
BNO085<MyI2c>. - CEVA's library, unmodified. The SH-2 protocol (sensor configuration, FRS records, report decoding) is CEVA's own code, kept as a submodule. The core adds the C++ types, the report cache and the reset handling.
- A latest-value cache. Each of the 47 possible sensor IDs keeps its last decoded value and a new-data flag, so callbacks and polling work together.
- One SH-2 session per program. The CEVA library keeps its state in a single global instance (
_sh2insh2.c, one SHTP instance inshtp.c) and its API takes no handle, so oneBNO085object can run SH-2 at a time. The driver enforces it: while one object's session is open,Begin()on any other object returnsfalsewithBNO08X_ERR_SH2_SESSION_IN_USEbefore it touches the library, so the open session is never reset behind its owner's back.Close()(or the owner's destructor) frees it;Sh2SessionInUse()tells whether it is taken. Making the driver multi-instance would mean changing CEVA's library, which this repository keeps unmodified. UART-RVC and firmware updates do not use the library and have no such limit. - Not thread-safe. Call one driver object from one task, or guard it with a mutex.
Source map¶
| Path | Contents |
|---|---|
inc/bno08x.hpp |
BNO085<Comm>, BNO085Sensor, SensorEvent, RVC and DFU types |
src/bno08x.ipp |
Template implementation, included by the header (installed next to it) |
inc/bno08x_comm_interface.hpp |
CommInterface, BNO085Interface, CtrlPin, GpioSignal |
inc/bno08x_shtp_uart.hpp |
UART-SHTP framing for UART ports: EncodeFrame(), FrameDecoder |
src/sh2/ |
CEVA SH-2 and SHTP library (submodule, Apache-2.0) |
src/dfu/ |
HcBin_t firmware-image interface, MemoryFirmware, the stub image |
tests/ |
Host unit tests and the compiled documentation snippets |
examples/esp32/ |
ESP-IDF applications |