Skip to content

Commit ec2f915

Browse files
kwagyemanclaude
andcommitted
docs: add Tools chapter, restructure Production, expand gdbrunner section
Adds a new Tools super-section between Host Protocol and Production covering the desktop GUIs, external libraries, and calculators that ship around the cam. Restructures Production -- battery moves into Tools, romfs-image lands under Shipping the application, and the TLS toctree is renamed to "Advanced material" so it can host other niche tutorials. Expands the make-debug-shortcut paragraph in firmware/debugging.rst into a proper gdbrunner section. Fixes three display bugs from nested code-inside-bold markup. Tools chapter - New tools/index.rst with three captioned groups: Desktop GUIs (IDE placeholder, Projects Tools), External libraries (openmv-py, Arduino RPC), Calculators (battery-life-estimator). - New tools/openmv-py/ covers the host-side openmv PyPI package end to end: the included CLI viewer (cli.rst), a hello-cam page for connecting and reading stdout, frame streaming (including the raw-streaming JPEG-skip path), bidirectional custom channels, and a new events page covering _handle_event subclassing, poll_events(), and the cam-side send_event surface. Reference page documents the full Camera class plus the OMVException hierarchy; private channel-internals, retry decorator, and subclassing hooks at the bottom for power users. - New tools/arduino-rpc/index.rst -- sales-summary page for the openmv-arduino-rpc library with a transports figure showing UART / SPI / I2C / CAN between an Arduino and a cam. - New tools/projects-tools/index.rst -- desktop GUI tools paired with cam-side scripts (ISP tuner, thermal-overlay calibration, Prophesee visualiser). - battery-life.rst moved out of production/ into tools/battery-life-estimator.rst. - tools/ide/ is a placeholder for the IDE overview. Production reorg - Intro paragraph trimmed -- dropped "on battery" (now Tools) and the "order is roughly the path of a product" framing paragraph. - Section order is now Custom firmware builds -> Shipping the application -> Advanced material. - romfs-image.rst added under Shipping the application alongside freezing-scripts.rst. - TLS toctree caption renamed "Working with TLS certificates" -> "Advanced material". firmware/debugging.rst - Old 11-line "make debug shortcut" paragraph replaced with a full "Command-line debugging with gdbrunner" section that introduces the gdbrunner Python package (pip install gdbrunner), shows how it collapses the manual server+gdb dance into one foreground process, and lists six features that help command-line users: clean lifecycle, STM32CubeProgrammer auto-discovery, per-project .gdbinit honoured, --dryrun, --show-output, and the QEMU backend. Library index - omv.protocol.rst moved from "Frozen Python helpers" to "Built into the firmware on every OpenMV camera board" -- it is registered via MP_REGISTER_EXTENSIBLE_MODULE in py_protocol.c, not a frozen script. Display fixes (nested code-inside-bold) - formatting.rst: four format-flag bullets used **flag \`\`-\`\`**, **flag \`\`0\`\`**, etc. -- RST can't nest code inside bold, so the asterisks and backticks were rendering literally. Reworked to one-word bold lead-ins (Left-align, Zero pad, Sign, Alternate form) with the flag character in code form in the body. - debugging.rst pitfalls: **Everything is \`\`<optimized out>\`\`** had the same problem. Reworked to **Optimized-out variables.** lead-in with <optimized out> in the description. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 7e99da1 commit ec2f915

20 files changed

Lines changed: 1691 additions & 41 deletions

File tree

docs/library/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ Built into the firmware on every OpenMV camera board.
126126
omv.crc.rst
127127
omv.ml.rst
128128
omv.ulab.rst
129+
omv.protocol.rst
129130
logging.rst
130131
senml.rst
131132

@@ -136,7 +137,6 @@ networking, and utilities):
136137
:maxdepth: 1
137138

138139
aioble.rst
139-
omv.protocol.rst
140140
omv.rpc.rst
141141
omv.rtsp.rst
142142
omv.mqtt.rst

docs/openmvcam/tutorial/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,6 @@ something covered earlier, it links back.
4444
bluetooth/index.rst
4545
protocol/index.rst
4646

47+
tools/index.rst
48+
4749
production/index.rst

docs/openmvcam/tutorial/production/firmware/debugging.rst

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -250,18 +250,74 @@ Reaching the Windows host from WSL depends on the WSL networking mode:
250250
boards (N6 / RT1062 / AE3). Use ``"request": "launch"`` to reset,
251251
flash the ELF, and start fresh at ``runToEntryPoint``.
252252

253-
The ``make debug`` shortcut
254-
---------------------------
255-
256-
If the J-Link is on the same machine as the build, the repository has
257-
a shortcut that starts a GDB server with the right device automatically::
253+
Command-line debugging with gdbrunner
254+
-------------------------------------
255+
256+
Setting up a GDB session against an embedded target by hand is a
257+
five-step dance: start the J-Link / ST-Link / OpenOCD GDB server in
258+
one window with the right device, port, and interface flags; wait
259+
for it to print *Waiting for GDB connection*; run
260+
``arm-none-eabi-gdb`` in a second window; type ``target remote
261+
localhost:<port>``; point gdb at the ELF. When the gdb session ends,
262+
remember to kill the server window. `gdbrunner
263+
<https://github.com/openmv/gdbrunner>`__ is a small CLI that collapses
264+
all of that into one foreground command::
265+
266+
pip install gdbrunner
267+
268+
gdbrunner jlink --device STM32H743VI build/OPENMV4/bin/firmware.elf
269+
gdbrunner stlink build/OPENMV4/bin/firmware.elf
270+
gdbrunner qemu --machine mps2-an500 build/OPENMV4/bin/firmware.elf
271+
272+
The first positional argument picks the server backend (``jlink``,
273+
``stlink``, ``qemu``); the rest are forwarded to that backend, with
274+
defaults that work for the OpenMV cams. ``gdbrunner --help`` lists
275+
the full per-backend flag list; each backend's argument table is
276+
JSON-driven (``src/gdbrunner/backends.json``), so adding a new server
277+
is a config edit rather than code.
278+
279+
The firmware repository's ``make debug`` target is a thin wrapper
280+
around gdbrunner that fills in the current ``TARGET``'s J-Link
281+
arguments automatically::
258282

259283
make -j$(nproc) TARGET=<TARGET> DEBUG=1 debug
260284

261-
This runs the SDK's ``gdbrunner`` with the board's J-Link arguments
262-
against ``build/<TARGET>/bin/firmware.elf``. It is convenient for
263-
command-line gdb; for source-level stepping, the VS Code Cortex-Debug
264-
setup above is what you want.
285+
This is the fastest way to drop into command-line gdb on whichever
286+
board ``TARGET`` selects.
287+
288+
What gdbrunner does for command-line work:
289+
290+
* **One process, clean lifecycle.** Server starts, gdb attaches when
291+
the port is open, server is terminated cleanly when gdb exits. No
292+
orphan ``JLinkGDBServer`` surviving the session, no two terminals
293+
to manage.
294+
* **STM32CubeProgrammer auto-discovery.** The ``stlink`` backend
295+
searches the usual install locations (``~/STM32CubeProgrammer/``,
296+
``/opt/st/``, the STM32CubeIDE plugin tree) for
297+
``ST-LINK_gdbserver``, so the long ``--cube-prog`` path doesn't
298+
have to be typed every time.
299+
* **Per-project gdbinit honoured.** A ``.gdbinit`` in the current
300+
directory is loaded with ``-ix`` -- overriding the user-wide
301+
``~/.gdbinit`` -- so per-project gdb scripting (pretty-printers,
302+
board-specific macros, breakpoint sets) drops in by being present
303+
in the working directory.
304+
* **Dry run.** ``--dryrun`` prints the server command without
305+
running it, useful for adapting the invocation to a wrapper
306+
script, copying it into an IDE launcher config, or just checking
307+
what arguments gdbrunner is composing.
308+
* **Server output visible.** ``--show-output`` keeps the server's
309+
stdout / stderr visible. The default suppresses it (so gdb's UI
310+
stays clean); flip the flag when the server itself is what's
311+
misbehaving.
312+
* **QEMU backend.** ``qemu-system-arm`` running ``mps2-an500`` /
313+
``mps3-an547`` debugs the same ELF without a board plugged in --
314+
code paths that don't touch cam-specific peripherals are
315+
steppable on a flight.
316+
317+
For source-level stepping with breakpoint gutters and a peripheral
318+
register view, the VS Code Cortex-Debug setup above is the better
319+
tool; gdbrunner is the right one for everything that lives at the
320+
command line.
265321

266322
Using the debugger
267323
------------------
@@ -336,8 +392,8 @@ RT1062, or AE3 -- use J-Link for those.
336392
Debugging pitfalls
337393
------------------
338394

339-
* **Everything is ``<optimized out>``** -- you built ``DEBUG=0``.
340-
Rebuild with ``DEBUG=1``.
395+
* **Optimized-out variables.** Everything shows ``<optimized out>``
396+
-- you built ``DEBUG=0``. Rebuild with ``DEBUG=1``.
341397
* **"GDB executable not found"** -- the SDK ``gcc/bin`` is not on
342398
``PATH``; set ``armToolchainPath`` / ``gdbPath``.
343399
* **"Cannot connect" / wrong memory map** -- wrong or missing

docs/openmvcam/tutorial/production/index.rst

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,27 @@ Production
33

44
A working script on the bench is the start, not the
55
end. A camera that ships in a product has to do its job
6-
unattended, on battery, against a network the script
7-
does not control, without the source code being
8-
readable by whoever takes the enclosure apart. The
9-
pages in this section cover the practical work between
10-
*the demo runs* and *the device is out the door*.
11-
12-
The order is roughly the path of a product: pick a
13-
battery that fits the duty cycle, freeze the
14-
application into the firmware so it ships as one
15-
binary, secure the network connections it makes, and --
16-
when the stock firmware needs to change -- build,
17-
flash, and debug the firmware itself.
6+
unattended, on a network the script does not control,
7+
without the source code being readable by whoever takes
8+
the enclosure apart. The pages in this section cover
9+
the practical work between *the demo runs* and *the
10+
device is out the door*.
1811

1912
.. toctree::
20-
:caption: Power and battery life
13+
:caption: Custom firmware builds
2114
:maxdepth: 1
2215

23-
battery-life.rst
16+
firmware/index.rst
2417

2518
.. toctree::
2619
:caption: Shipping the application
2720
:maxdepth: 1
2821

2922
freezing-scripts.rst
23+
romfs-image.rst
3024

3125
.. toctree::
32-
:caption: Working with TLS certificates
26+
:caption: Advanced material
3327
:maxdepth: 1
3428

3529
tls/index.rst
36-
37-
.. toctree::
38-
:caption: Custom firmware builds
39-
:maxdepth: 1
40-
41-
firmware/index.rst
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Building a ROMFS image
2+
======================
3+
4+
A *ROMFS image* is a flash-resident, read-only
5+
filesystem the firmware mounts at ``/rom/``. It is the
6+
right place to ship assets that are too large or too
7+
many to freeze as Python modules: machine-learning model
8+
files, label tables, JSON configuration, image
9+
templates, anything the application opens and reads but
10+
never writes.
11+
12+
This page covers building a ROMFS partition image
13+
offline and laying it down alongside the firmware so the
14+
shipped device reads from it directly at boot.
15+
16+
(Page in progress -- content to come.)

docs/openmvcam/tutorial/python/text/formatting.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,14 @@ type letter. The full shape is ``%[flags][width][.precision]type``:
192192
number of digits after the decimal point. ``%.2f`` gives two
193193
decimal places. For strings, the maximum number of characters
194194
to take (``%.5s`` truncates to five).
195-
* **flag ``-``** -- left-align inside the field. ``%-10d`` puts
196-
the digits on the left side with trailing spaces.
197-
* **flag ``0``** -- pad with leading zeros instead of spaces (for
198-
numeric types). ``%05d`` zero-pads to five digits.
199-
* **flag ``+``** -- always show the sign on numbers, including a
200-
``+`` for positives.
201-
* **flag ``#``** -- alternate form. For ``%x`` this prefixes the
202-
output with ``0x``; for ``%o`` it prefixes ``0o``.
195+
* **Left-align** -- the ``-`` flag puts the field on the left.
196+
``%-10d`` puts the digits on the left side with trailing spaces.
197+
* **Zero pad** -- the ``0`` flag pads with leading zeros instead
198+
of spaces (for numeric types). ``%05d`` zero-pads to five digits.
199+
* **Sign** -- the ``+`` flag always shows the sign on numbers,
200+
including a ``+`` for positives.
201+
* **Alternate form** -- the ``#`` flag. For ``%x`` this prefixes
202+
the output with ``0x``; for ``%o`` it prefixes ``0o``.
203203

204204
Flags, width, and precision can be combined:
205205

Lines changed: 60 additions & 0 deletions
Loading
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
OpenMV Arduino RPC Library
2+
==========================
3+
4+
The `openmv-arduino-rpc
5+
<https://github.com/openmv/openmv-arduino-rpc>`__
6+
library is the Arduino-side counterpart to the cam's
7+
:mod:`rpc` module. The cam registers Python callables;
8+
the Arduino calls them as if they were local functions,
9+
over UART, SPI, I2C, or CAN. No PC sits in the middle.
10+
11+
.. image:: figures/transports.svg
12+
:alt: An Arduino board on the left and an OpenMV cam
13+
on the right, connected by four labelled
14+
transport lines -- UART (two wires), SPI (four
15+
wires), I2C (two wires), and CAN (two wires) --
16+
showing the wire-level pairings the Arduino
17+
RPC library can drive.
18+
:align: center
19+
20+
The pattern is symmetric. The Arduino sketch picks the
21+
transport class that matches the wire, calls a function
22+
on the cam by name, and gets the return value back. The
23+
cam side mirrors it: register Python callables, run the
24+
library's polling loop. Framing, fragmentation, and
25+
retries on a noisy bus are handled by both sides
26+
underneath, so application code sees just "call a
27+
function on the other board, get a result back."
28+
29+
The repo's `examples
30+
<https://github.com/openmv/openmv-arduino-rpc/tree/master/examples>`__
31+
cover the two shapes most projects need: short
32+
remote-control calls (read a sensor, drive a pin, run a
33+
detector and read the result back) and JPEG image
34+
streaming from the cam to the Arduino for forwarding
35+
onward. Paired cam-side scripts ship in the openmv
36+
tree under
37+
`08-RPC-Library/
38+
<https://github.com/openmv/openmv/tree/master/scripts/examples/08-RPC-Library>`__.
39+
40+
The repo README covers per-transport wiring; the
41+
:doc:`/library/omv.rpc` reference covers the cam-side
42+
API in full.

docs/openmvcam/tutorial/production/battery-life.rst renamed to docs/openmvcam/tutorial/tools/battery-life-estimator.rst

File renamed without changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
OpenMV IDE
2+
==========
3+
4+
The OpenMV IDE is the desktop editor and runtime that
5+
ships with every camera. It is the fastest way to write,
6+
run, and iterate on a script: open a project, plug in a
7+
camera, hit run, and the frame buffer streams back in
8+
real time while the script executes on the device.
9+
10+
(Section in progress -- pages to come.)

0 commit comments

Comments
 (0)