diff --git a/images/node-radio-chip-counters.png b/images/node-radio-chip-counters.png new file mode 100644 index 0000000..40fc5ab Binary files /dev/null and b/images/node-radio-chip-counters.png differ diff --git a/images/sweep-chip-counters.png b/images/sweep-chip-counters.png new file mode 100644 index 0000000..b372fca Binary files /dev/null and b/images/sweep-chip-counters.png differ diff --git a/pages/debugging.md b/pages/debugging.md index 5cd200f..4da6cfb 100644 --- a/pages/debugging.md +++ b/pages/debugging.md @@ -121,6 +121,26 @@ uses. between runs and the capture survives that, but a restarted workbench has no capture until one is started again. +## Read the node's radio + +A node's window has a **Radio** tab: what the firmware left in the chip's +registers, and what the chip counted. Two rows answer whether the firmware could +have seen a packet at all. + +- **IRQ suppressed** sits under the IRQ and DIO1 masks. It counts events the + chip raised that the firmware's mask kept out of the register. A firmware + waiting on an interrupt it never enabled looks exactly like a quiet mesh, and + this row is what tells the two apart. Above zero it is drawn in amber. A chip + model older than virtual-sx1262 v1.3.2 does not keep the count, and the row + reads **not counted** rather than 0. +- **Spurious detections** sits under busy time. It counts the false detections + the faulty chip variants inject, and is 0 on a chip that behaves. + +![The Radio tab of a MeshCore 1.16 repeater: IRQ mask 0x0272, 14 events suppressed, spurious detections 0](images/node-radio-chip-counters.png) + +From a script, `nodes.stats` answers the same count as `irq_suppressed`, absent +for a chip that does not keep it. + ## Common causes that produce no error - **Regions inferred but never applied.** Everything transmits, nothing relays. diff --git a/pages/experiments.md b/pages/experiments.md index bf32aeb..a99433d 100644 --- a/pages/experiments.md +++ b/pages/experiments.md @@ -85,12 +85,28 @@ _, err := wb.Call(ctx, "experiment.start", nil) | `airtime_ms` | total time the network spent transmitting | | `rx_spread` | how much `rx` varied across the arm's seeds - the arm's own noise floor | | `at_risk_2db` | deliveries within 2 dB of the demodulator floor, absent when no run measured it | +| `irq_suppressed` | interrupt events the chips raised and the firmware's IRQ mask kept out, summed over every node | +| `busy_ms` | how long the chips' detection flags were up, summed over every node | Airtime, collisions and redundancy are the metrics that answer "is this change good for the network" rather than "did this message arrive". They are reported for every arm without being asked for, and `rx_spread` is the number every delta must beat before it means anything. +The last two come from the chips rather than the channel, and they are where two +firmwares that flood identically differ. The **Results** table shows them +straight after **delivered**, as **IRQ suppressed**, a cost where fewer is +better, and **busy time**, in seconds and without a colour, because more busy time is a firmware seeing more of the +traffic that is really there. Each is averaged over the seeds whose chips +counted it. An arm whose chips sent no counters, such as one running emulated +boards, shows a dash in both columns rather than a zero. + +![The Results table for MeshCore 1.16.0, 1.17.0 and 1.17.1 over five seeds: delivery identical in every arm, IRQ suppressed down 84.9% in 1.17, busy time up from 236 s to 284 s](images/sweep-chip-counters.png) + +Every cell of `experiment.export` also carries `chip`: the same counters for +every node, measured from the point the cell starts counting, after the adverts +have settled. + Every run and every arm summary also carries `builds`: the firmware each role actually ran, as `{role, version, file, bytes}`. A sweep exists to compare builds, and a delta means nothing unless the arms ran what they claimed, so the diff --git a/pages/reference-control.md b/pages/reference-control.md index ea1f9c1..57bdb62 100644 --- a/pages/reference-control.md +++ b/pages/reference-control.md @@ -3685,7 +3685,7 @@ Read the sweep back as one row per finished cell and one summary per arm, and pu **Takes** nothing. -**Answers** `runs`, `arms`, `warning`. `runs` and `arms` are both lists, and an empty `runs` is the normal answer before anything has started. `warning` is present only where the numbers do not mean what they look like: nothing run, one seed, one arm, a cell that failed, or seeds that agree so exactly that a difference between arms has nothing to be called larger than. Each run and each arm summary carries `builds`: the firmware every role actually ran, as `{role, version, file, bytes}`, so two arms that came back identical can be told from two arms that never switched build. +**Answers** `runs`, `arms`, `warning`. `runs` and `arms` are both lists, and an empty `runs` is the normal answer before anything has started. `warning` is present only where the numbers do not mean what they look like: nothing run, one seed, one arm, a cell that failed, or seeds that agree so exactly that a difference between arms has nothing to be called larger than. Each run and each arm summary carries `builds`: the firmware every role actually ran, as `{role, version, file, bytes}`, so two arms that came back identical can be told from two arms that never switched build. Each arm summary also carries `irq_suppressed` and `busy_ms`, its chips' counts per cell averaged over the seeds that counted them, and absent where none did. **Example** - read the table so far