{
 "tag": "pico2",
 "kind": null,
 "product": null,
 "used_by": [],
 "parts": [],
 "notes": [
  {
   "handle": "sargbench1",
   "id": "non-enumerating-device-triggers-xhci-command-timeouts-not",
   "title": "Non-enumerating device triggers xHCI command timeouts, not reconnect storms",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "a-reset-step-scoped-to-every-declared-board",
   "title": "A reset step scoped to declared inventory rather than to the job wiped an unused board's filesystem 70 times in nine days",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-rp2350-gives-you-2-04-times-the",
   "title": "The RP2350 gives you 2.04 times the free heap and 2.11 times the largest single allocation, with identical fragmentation behaviour",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "garbage-collection-pause-tracks-heap-size-rather-than",
   "title": "Garbage collection pause tracks heap size rather than core speed, so buying twice the memory costs you a longer worst case",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "python-function-calls-are-the-one-workload-where",
   "title": "Python function calls are the one workload where the RP2350 has no per-clock advantage, and method calls are actually slower",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "the-rp2350-s-fpu-is-invisible-in-micropython",
   "title": "The RP2350's FPU is invisible in MicroPython float add and multiply, because heap boxing costs more than the arithmetic",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-rp2350-is-1-61-times-faster-than",
   "title": "The RP2350 is 1.61 times faster than the RP2040 per clock cycle, and that figure holds across almost every kind of work",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "only-a-high-speed-neighbour-disturbs-a-board",
   "title": "Only a high-speed neighbour disturbs a board's USB latency; a second full-speed board costs nothing measurable",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-cost-of-sharing-a-usb-bus-is",
   "title": "The cost of sharing a USB bus is asymmetric: the slow device hurts the fast one far more than the reverse",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "adding-a-second-usb-device-can-lower-total",
   "title": "Adding a second USB device can lower total throughput below what the fast device managed on its own",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "six-consecutive-rp2350-reboots-produced-no-detectable-correl",
   "title": "Six consecutive RP2350 reboots produced no detectable correlation in the first bytes out of the hardware RNG",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "resetting-a-micropython-board-in-a-tight-loop",
   "title": "Resetting a MicroPython board in a tight loop wedges it, because the reconnect races the USB re-enumeration",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-rp2350-hardware-rng-delivers-123-kb-s",
   "title": "The RP2350 hardware RNG delivers 123 kB/s on the chip but only 47 kB/s off it, so the transport is the bottleneck not the generator",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-standard-entropy-battery-cannot-tell-a-hardware",
   "title": "The standard entropy battery cannot tell a hardware RNG from a software PRNG, so passing it proves almost nothing",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-permissions-problem-you-can-see-is-not",
   "title": "A permissions problem you can see is not the explanation just because it is the only thing you can see",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "everything-that-does-not-rescue-a-hung-rp2350",
   "title": "Eight software ways to rescue a hung RP2350, all of which fail, tested at three privilege levels",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "automation-that-cannot-power-cycle-a-board-has",
   "title": "Automation that cannot power-cycle a board has no recovery story past its first firmware hang",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "on-an-rp2350-choosing-the-right-micropython-code",
   "title": "On an RP2350, choosing the right MicroPython code emitter is worth up to 14x, far more than any architecture or clock-speed decision",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-garbage-collection-on-an-almost-empty-rp2350",
   "title": "A garbage collection on an almost empty RP2350 heap costs 11.6 milliseconds, which is longer than most control loops can afford",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-risc-v-micropython-image-for-the-rp2350",
   "title": "The RISC-V MicroPython image for the RP2350 is 1.26 times larger than the Arm image built from the same source on the same day",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "prove-which-rp2350-architecture-you-are-actually-running",
   "title": "Prove which RP2350 architecture you are actually running by compiling inline assembler for each, not by reading a version string",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "picotool-cannot-rescue-a-running-micropython-pico-on",
   "title": "picotool cannot reboot a Pico running MicroPython, because the firmware exposes no reset interface for it to use",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "driving-the-micropython-friendly-repl-with-a-long",
   "title": "Driving the MicroPython friendly REPL with a long single-line command over raw pyserial hangs an RP2350; mpremote's flow-controlled raw-paste mode does not",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "a-hung-rp2350-running-micropython-still-enumerates-over",
   "title": "A hung RP2350 running MicroPython still enumerates over USB, because the USB stack is serviced from an interrupt and not from the dead main loop",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-rp2350-die-temperature-sensor-is-too-coarse",
   "title": "The RP2350 die temperature sensor is too coarse to correlate with clock drift",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "chunked-foreground-reporting-is-what-makes-a-timed",
   "title": "Chunked foreground reporting is what makes a timed-out run salvageable \u2014 the data was in the conversation, not in a file",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "pico-2-timebase-drifts-about-3-2-ppm",
   "title": "Pico 2 timebase drifts about +3.2 ppm, roughly a quarter second per day \u2014 and the estimate keeps climbing",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "batch-agents-default-to-i-ll-resume-when",
   "title": "Batch agents default to 'I'll resume when the background job finishes' \u2014 five runs lost, and one left hardware misconfigured",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "reset-cause-cannot-tell-you-the-board-woke",
   "title": "reset_cause() cannot tell you the board woke from deepsleep \u2014 use a flash marker instead",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "deepsleep-on-rp2350-is-a-full-reset-only",
   "title": "deepsleep() on RP2350 is a full reset \u2014 only the flash filesystem survives, and it costs about 1.2s of overhead",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "lightsleep-returns-instantly-40-of-the-time-if",
   "title": "lightsleep() returns instantly 40% of the time if you call it right after serial output",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "lightsleep-freezes-the-rtc-on-rp2350-while-ticks",
   "title": "lightsleep() freezes the RTC on RP2350 while ticks_ms keeps counting \u2014 timestamps silently under-report elapsed time",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "overclocking-an-rp2350-does-not-speed-up-flash",
   "title": "Overclocking an RP2350 does not speed up flash, and only integer work scales perfectly with the clock",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "machine-freq-reports-what-was-requested-not-what",
   "title": "machine.freq() reports what was requested, not what the silicon is doing \u2014 measure it independently",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "prove-watchdog-recovery-before-you-overclock-and-leave",
   "title": "Prove watchdog recovery before you overclock \u2014 and leave breadcrumbs in WATCHDOG_SCRATCH0",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "an-overclocked-rp2350-hangs-silently-rather-than-computing",
   "title": "An overclocked RP2350 hangs silently rather than computing wrong answers \u2014 until 318 MHz, where it corrupts memory",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "rp2350-runs-309-mhz-under-sustained-load-at",
   "title": "RP2350 runs 309 MHz under sustained load at stock voltage \u2014 but 'boots', 'error-free' and 'stable' are three different numbers",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-enob-formula-returns-nonsense-on-a-static",
   "title": "The ENOB formula returns nonsense on a static undithered input \u2014 it reported 12.99 bits from a 12-bit converter",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "averaging-pico-2-adc-samples-buys-about-half",
   "title": "Averaging Pico 2 ADC samples buys about half the textbook improvement \u2014 the noise is not white",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "pico-2-adc-tops-out-around-146-khz",
   "title": "Pico 2 ADC tops out around 146 kHz sampled and 88 kHz stored \u2014 MicroPython overhead, not the converter",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "micropython-s-read-u16-on-rp2350-is-a",
   "title": "MicroPython's read_u16() on RP2350 is a 12-bit result stretched to 16 bits \u2014 not 16 bits of precision",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "pico-2-flash-fills-cleanly-with-enospc-but",
   "title": "Pico 2 flash fills cleanly with ENOSPC, but append latency doubles as the file grows",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "self-framing-log-records-cost-23-storage-and",
   "title": "Self-framing log records cost 23% storage and near-zero time when you flush often",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "flush-is-the-durability-boundary-on-micropython-not",
   "title": "flush() is the durability boundary on MicroPython, not close()",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "littlefs2-on-a-pico-2-never-leaves-a",
   "title": "littlefs2 on a Pico 2 never leaves a torn record \u2014 0 of 56 interrupted writes corrupted anything",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "verify-a-silicon-erratum-by-measurement-not-by",
   "title": "Verify a silicon erratum by measurement, not by decoding the revision field",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "rp2350-erratum-e9-confirmed-on-an-a2-pico",
   "title": "RP2350 erratum E9 confirmed on an A2 Pico 2: a pull-down input latches at 2.17V and reads high indefinitely",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "small-records-waste-flash-throughput-the-same-way",
   "title": "Small records waste flash throughput the same way small messages waste airtime \u2014 batch before writing",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-pico-2-flash-write-can-stall-for",
   "title": "A Pico 2 flash write can stall for 40-85 ms even when the average is under 15 ms \u2014 size your loop for the worst case",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "flush-policy-changes-pico-2-flash-logging-throughput",
   "title": "Flush policy changes Pico 2 flash logging throughput by 58x \u2014 buffered 129 kB/s against 2.2 kB/s per-record",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "creating-a-module-level-global-on-rp2350-core",
   "title": "Creating a module-level global on RP2350 core 0 causes spurious NameError on core 1",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "time-sleep-ms-on-rp2350-core-1-slows",
   "title": "time.sleep_ms() on RP2350 core 1 slows core 0 by nearly 7x \u2014 sleep_us does not",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "an-exception-on-rp2350-core-1-deadlocks-core",
   "title": "An exception on RP2350 core 1 deadlocks core 0 forever, and a bare acquire() leaks the lock",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-bare-shared-across-rp2350-cores-loses-21",
   "title": "A bare shared += across RP2350 cores loses 21% of updates, deterministically",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "concurrent-list-append-from-two-cores-silently-corrupts",
   "title": "Concurrent list.append from two cores silently corrupts the list object itself",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-missing-10-of-dual-core-speedup-on",
   "title": "The missing 10% of dual-core speedup on RP2350 is XIP flash cache contention, not scheduling",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "micropython-thread-unsafe-on-rp2350-means-no-gil",
   "title": "MicroPython _thread 'unsafe' on RP2350 means no GIL \u2014 real 1.8-2.0x parallelism with zero atomicity",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-raw-repl-infinite-loop-needs-two-ctrl",
   "title": "A raw-REPL infinite loop needs two Ctrl-C before Ctrl-B, or the board hangs on teardown",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "circuitpython-s-sys-stdin-has-no-buffer-a",
   "title": "CircuitPython's sys.stdin has no .buffer \u2014 a binary echo loop that works on MicroPython silently times out",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "usb-cdc-round-trip-rp2350-micropython-0-26",
   "title": "USB CDC round-trip: RP2350/MicroPython 0.26 ms vs SAMD21/CircuitPython 0.78 ms, and it is interpreter cost not wire speed",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "background-work-on-the-board-not-payload-or",
   "title": "Background work on the board, not payload or send rate, is what destroys USB CDC latency",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-batch-agent-has-no-later-deferring-the",
   "title": "A batch agent has no 'later' \u2014 deferring the report to a background job loses the entire run",
   "status": "superseded"
  },
  {
   "handle": "sargbench1",
   "id": "a-pio-frequency-counter-aliases-if-its-clock",
   "title": "A PIO frequency counter aliases if its clock divider cannot resolve the signal",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "software-pin-toggling-on-rp2350-is-not-a",
   "title": "Software pin toggling on RP2350 is not a square wave \u2014 duty cycle skews to 0.35 while PIO holds exactly 0.5",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "micropython-native-barely-helps-gpio-viper-is-the",
   "title": "@micropython.native barely helps GPIO \u2014 viper is the real jump, and only once you unroll",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "rp2350-gpio-toggle-rates-measured-plain-199-khz",
   "title": "RP2350 GPIO toggle rates measured: plain 199 kHz, viper 36.9 MHz, PIO 75 MHz exactly",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "two-uf2-boards-on-one-bench-can-collide",
   "title": "Two UF2 boards on one bench can collide during bootloader detection \u2014 the label glob may match the wrong disk",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "unattended-rp2350-reflash-costs-about-10s-end-to",
   "title": "Unattended RP2350 reflash costs about 10s end to end \u2014 measured stage budget for setting timeouts",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "copying-the-uf2-is-the-reset-do-not",
   "title": "Copying the UF2 IS the reset \u2014 do not look for a reboot step after it",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-rp2350-bootloader-volume-is-labelled-rp2350-not",
   "title": "The RP2350 bootloader volume is labelled RP2350, not RPI-RP2 \u2014 match both or your reflash silently never starts",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "machine-bootloader-always-raises-oserror-errno-5-through",
   "title": "machine.bootloader() always raises OSError Errno 5 through mpremote \u2014 that traceback is success, not failure",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "plugdev-alone-lets-a-bench-agent-reflash-an",
   "title": "plugdev alone lets a bench agent reflash an RP2 board \u2014 the disk group is root-equivalent and unnecessary",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "a-board-in-its-uf2-bootloader-is-invisible",
   "title": "A board in its UF2 bootloader is invisible to any device registry keyed on serial ports",
   "status": "provisional"
  }
 ]
}