Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,32 @@ deste manual antes do primeiro estilo ou da primeira frase.** Parte das regras

## 1. A bancada

Um Pico W (o **alvo**, que roda o SIMUT) e um Pico comum (a **PicoHand**, ou
"mão") que aciona as linhas RESET (GP0) e BOOTSEL (GP1) do alvo por comando
serial, mede a sonda e finge o carregador. O rig está em `192.168.3.24`.
Desde 12/10/2026, um Pico 2 W (o **alvo**, que roda o SIMUT, com os cinco
sensores e o painel TFT) e um Pico W (a **PicoHand**, ou "mão") que aciona as
linhas RESET (GP0) e BOOTSEL (GP1) do alvo por comando serial, mede a sonda e
finge o carregador. A mão roda na placa que foi o alvo até 05/10; o Pico comum
que era a mão foi para outro projeto e pode continuar ligada a este PC: não
mande nada a ela. O alvo está em `192.168.3.33`, com a web na porta 8080.

**Identifique as portas pelo serial, nunca pela ordem de enumeração:**

| Placa | USB | Serial (udev) |
|---|---|---|
| PicoHand (mão) | `2e8a:000a` | `ID_SERIAL_SHORT=E660C062131E3E27` |
| Alvo SIMUT (Pico W) | `2e8a:f00a` | `ID_SERIAL_SHORT=E6642815E34C1824` |
| PicoHand (mão), num Pico W | `2e8a:f00a` | `ID_SERIAL_SHORT=E6642815E34C1824` |
| Alvo SIMUT (Pico 2 W) | `2e8a:f00f` | `ID_SERIAL_SHORT=6A73539D612923CA` |
| A mão antiga, fora da bancada | `2e8a:000a` | `ID_SERIAL_SHORT=E660C062131E3E27` |

**Os roteiros de `tools/` ainda conhecem a bancada de antes.** Dez deles
procuram o alvo como Pico W, pelo serial `E6642815E34C1824` ou pelo glob
`usb-Raspberry_Pi_Pico_W_*`, e os dois agora dão na mão: um toque de 1200 bps
ali põe a mão em BOOTSEL. Três (`air_test_suite.py`, `bt_auth_test.py` e
`rig_validate_history_clock.py`) procuram a mão pelo serial da mão antiga. Até
eles aprenderem a bancada nova, não os rode. Definir `SIMUT_TARGET_SERIAL` e
`PICO_HAND_SERIAL` não basta: eles montam o caminho `by-id` com o modelo de
antes (`Pico_W_` no alvo, `Pico_` na mão), e o da bancada nova não existe. O
`pico_hand.sh` acha a mão por `PING` em toda porta, e a mão antiga responde se
ainda tiver o firmware da mão: fixe `PICO_HAND_PORT` no caminho `by-id` da mão
nova.

**Fiação real** (confirmada em 06/09/2026): DS18B20 no GP0, sem chaveamento de
energia — a linha GP16 do alvo vai ao GP2 da mão como **sonda** de
Expand All @@ -44,6 +60,16 @@ com o fio solto foram 60 minutos sem reinício. Religue o fio depois: gravar e o
RESET dos roteiros precisam dele. O `hand VERIFY` não acusa um pulso que já
passou, porque só imprime a contagem enquanto a falha está ativa.

**Não é só no soak.** Em 05/10/2026, no portão da v2.11.1, com o fio ligado, o
Pico W reiniciou sozinho quatro vezes em seis horas, de 7 minutos a 2,5 horas
depois de um boot. Uma delas cortou uma atualização pelo ar aos 33,8 s do
envio: a placa voltou na versão de antes, com a configuração idêntica byte a
byte, como o passo do corte espera, e o mesmo envio passou na tentativa
seguinte. Um passo que falha sem a linha `WATCHDOG_REBOOT detected` na serial e
sem `SYS_BOOT` no log foi reiniciado por fora: repita-o antes de culpar o
firmware. Com o fio solto, o BOOTSEL vem pelo toque de 1200 bps na serial do
alvo, e o `picotool reboot` o tira de lá.

**O alvo tem um painel TFT ligado** (ILI9341 + XPT2046, pinagem do
`simut_config.h`), o que esta lista não dizia até 22/09/2026 — `/api/screenshot`
devolve o dashboard renderizado e `POST /api/touch` dirige o painel. Vale para
Expand Down
77 changes: 75 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

All notable changes to SIMUT firmware.

## v2.11.1 (2026-10-05)
## v2.11.1 (2026-10-12)

**Four high-severity defects of the manual's review are fixed: the panel's
forced PIN change could be skipped, its account editor granted bits the
Expand Down Expand Up @@ -81,13 +81,76 @@ Slack under the 1,040,384 B over-the-air ceiling: release 7,027, alpha 49,763,
Air 8,899. The Pico 2 W's slot is 1,568,768 B. Neither the alpha nor the Air has
a panel, and neither grew past its 4 KiB page.

### The bench

The release gate (`AGENTS.md` §2) ran on the candidate the CI signed on `main`
(run 37259233322). The published images carry the same image bytes; their
signature is their own, because every signing run makes a new one.

**On the Pico 2 W,** the bench board (an RP2350 A2), from the published v2.11.0
in slot B, which trusts the release root alone:
- **The update, over the air:** stage 200 in 16.7 s, the board back 39.3 s
later from slot A on trial, and kept 50.4 s after that. All 555 configuration
values the web API reports unchanged.
- **Refused,** the board left running on its slot: the candidate with one byte
changed (9), and an image signed by the bench key (12).
- **The candidate over itself,** from slot A to slot B: stage 16.7 s, back
24.9 s later, kept 60.4 s after that, the configuration unchanged.
- **The factory `.uf2`,** dragged by the maintainer onto the BOOTSEL drive of
the board: up on 2.11.1 from slot A, not on trial, with its configuration.
At the buy of the update over itself the ROM erases slot A's first sector,
so the board could come up from A only if the drag had written it.
- **A week later, back on the bench** (2026-10-12), still on 2.11.1 from slot A:
30 minutes without a restart, the five sensors valid in every sample. Four of
the 119 reads lost their chunked framing (#189, under *Known*). The probe on
GP0 had been swapped while the board was away, so its slot sat in quarantine
until *Adopt the probe wired here* bound it to the new one, which read 0.1 s
later. The PicoHand's RESET wire stayed on the RUN pin this time, against
`AGENTS.md` §1, and no restart came. The web suite on the candidate, as its
admin: 67 passed, 0 failed.

**On the Pico W,** the bench board with the touch display and five sensors, from
the published v2.11.0 with the bench's configuration, a throwaway admin account
and the web on port 8080. That start is the v2.11.0 gate's own, written by USB
and read back, then updated over the air to v2.11.0 with its `.bkp` put back.
The board's flash was dumped first, two equal reads, and written back at the
end.
- **The update from v2.11.0,** complete, over the air: stage 200 (`v` 0) in
35.6 s, the board back 50.0 s after the apply, `2.11.1`, the five sensors
reading, all 567 configuration values the web API reports unchanged, the
configuration file identical byte for byte, and the `.bkp` back with 71 of 75
files identical. The other four are the log, its previous file and two of the
history's, which move while the device runs. The same on the alpha and the
Air (558 values, and 71 of 75 files on each), where the Air's own options,
which an update erases, came back with the `.bkp`.
- **The candidate over itself,** on all three, the candidate checking the
signature (`v` 0): the same.
- **Back to v2.11.0 and up again,** over the air, both at security version 1:
accepted (`v` 0) both ways, the configuration unchanged, and the telemetry
queue rebuilt at each boot from the cursor the other version wrote.
- **Refused** with 422, the configuration intact before and after a reset: an
unsigned image (8), the Air's signed image (7), the Pico 2 W's signed update
(6, which the Files page now explains) and the candidate with one byte changed
(9).
- **An upload cut at 400 kB, then a reset,** and the same with the filesystem
filled to its last 8 KB and emptied between the cut and the reset: the
configuration intact.
- **30 minutes** without a restart, the five sensors valid in every sample, with
the PicoHand's RESET wire off the RUN pin, as `AGENTS.md` §1 says. With the
wire on, the board restarted itself four times in six hours, with no watchdog
behind any of them. One of those restarts came 33.8 s into an update from the
board's arrival state, on v2.10.0. The board came back on v2.10.0 with its
configuration identical byte for byte, and the same update passed on the next
try.
- **The web suite on the candidate,** as an admin account: 67 passed, 0 failed.

### Upgrading

- **From v2.11.0, on either board:** over the air, from the Files page, with
this release's `.bin`. The configuration carries over. On the Pico 2 W the
update goes to the other slot and boots on trial, as since v2.11.0.
- **Back to v2.11.0:** over the air with its signed `.bin` (both carry security
version 1), or over USB.
version 1; checked on the bench, on the Pico W), or over USB.
- **From an older version, or a Pico 2 W's first install:** as for v2.11.0,
below.
- **Language packs:** upload the two attached to this release on the Files page,
Expand Down Expand Up @@ -128,6 +191,16 @@ a panel, and neither grew past its 4 KiB page.
first one's key and with the last one's value**, by the code.
- **The Telemetry page's token list for the alarm line stops at v22.** Chapter 22
of the manual lists them all.
- **Adopting a probe, or `sensor_wipe`, does not start the slot's history
anew.** Both stamp the slot's provisioning epoch, and nothing reads it: the
history serves every record of a slot under the slot's current id. On the
bench, after slot 0 adopted another probe, its readings of 4 October came back
under the new probe's id.
- **After a boot, a probe that is not the slot's can have its first reading
recorded.** The read path checks the ROM on every fifth read, from the fifth
on. On the bench, with another probe on the slot's GPIO, the reading of 20 s
after the boot went into the history as the slot's, and the quarantine began
within the next minute.

## v2.11.0 (2026-10-04)

Expand Down
79 changes: 77 additions & 2 deletions CHANGELOG.pt-BR.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Todas as mudanças notáveis do firmware SIMUT.

## v2.11.1 (2026-10-05)
## v2.11.1 (2026-10-12)

**Quatro defeitos de severidade alta da revisão do manual estão consertados: a
troca obrigatória de PIN do painel podia ser pulada, o editor de contas do
Expand Down Expand Up @@ -84,13 +84,78 @@ Folga sob o teto de 1.040.384 B da atualização pelo ar: release 7.027, alpha
49.763, Air 8.899. O slot do Pico 2 W tem 1.568.768 B. Nem a alpha nem o Air têm
painel, e nenhum dos dois passou da sua página de 4 KiB.

### A bancada

O portão de release (`AGENTS.md` §2) rodou na candidata que o CI assinou no
`main` (execução 37259233322). As imagens publicadas trazem os mesmos bytes de
imagem; a assinatura é delas, porque cada execução de assinatura faz uma nova.

**No Pico 2 W,** a placa da bancada (um RP2350 A2), a partir da v2.11.0
publicada no slot B, que confia só na raiz de release:
- **A atualização, pelo ar:** envio 200 em 16,7 s, a placa de volta 39,3 s
depois, do slot A e em teste, e confirmada 50,4 s depois disso. Os 555 valores
de configuração que a API web informa, iguais.
- **Recusadas,** com a placa rodando no slot dela: a candidata com um byte
trocado (9) e uma imagem assinada pela chave de bancada (12).
- **A candidata sobre ela mesma,** do slot A para o B: envio em 16,7 s, de volta
24,9 s depois, confirmada 60,4 s depois disso, a configuração igual.
- **O `.uf2` de fábrica,** arrastado pelo mantenedor para a unidade do BOOTSEL
da placa: ela subiu na 2.11.1 do slot A, fora de teste, com a configuração
dela. Na confirmação da atualização sobre ela mesma a ROM apaga o primeiro
setor do slot A, então a placa só subiria do A se o arrasto o tivesse gravado.
- **Uma semana depois, de volta à bancada** (12/10/2026), ainda na 2.11.1 do
slot A: 30 minutos sem reinício, os cinco sensores válidos em todas as
amostras. Quatro das 119 leituras perderam o enquadramento chunked (#189, em
*Conhecido*). A sonda do GP0 tinha sido trocada enquanto a placa estava fora,
e o slot dela ficou em quarentena até o *Adotar a sonda ligada aqui* ligá-lo à
nova, que leu 0,1 s depois. Desta vez o fio do RESET da PicoHand ficou no pino
RUN, contra o `AGENTS.md` §1, e nenhum reinício veio. A suíte web na
candidata, como o admin dela: 67 aprovados, 0 falhas.

**No Pico W,** a placa da bancada com o painel de toque e cinco sensores, a
partir da v2.11.0 publicada com a configuração da bancada, uma conta de
administrador descartável e a web na porta 8080. Esse começo é o do próprio
portão da v2.11.0, gravado pelo USB e relido, depois atualizado pelo ar para a
v2.11.0 com o `.bkp` de volta. A flash da placa foi copiada antes, em duas
leituras iguais, e regravada no fim.
- **A atualização a partir da v2.11.0,** completa, pelo ar: envio 200 (`v` 0)
em 35,6 s, a placa de volta 50,0 s depois da aplicação, `2.11.1`, os cinco
sensores lendo, os 567 valores de configuração que a API web informa iguais, o
arquivo de configuração idêntico byte a byte, e o `.bkp` de volta com 71 de 75
arquivos idênticos. Os outros quatro são o log, o arquivo anterior dele e dois
do histórico, que mudam enquanto o aparelho roda. O mesmo no alpha e no Air
(558 valores, e 71 de 75 arquivos em cada), onde as opções próprias do Air,
que uma atualização apaga, voltaram com o `.bkp`.
- **A candidata sobre ela mesma,** nas três, com a candidata conferindo a
assinatura (`v` 0): o mesmo.
- **De volta à v2.11.0 e de novo para cima,** pelo ar, as duas no nível de
segurança 1: aceitas (`v` 0) nos dois sentidos, a configuração igual, e a fila
da telemetria refeita em cada boot a partir do cursor que a outra versão
gravou.
- **Recusadas** com 422, com a configuração intacta antes e depois de um
reinício: uma imagem sem assinatura (8), a imagem do Air assinada (7), a
atualização assinada do Pico 2 W (6, que a página Arquivos agora explica) e a
candidata com um byte trocado (9).
- **Um envio cortado aos 400 kB, seguido de um reinício,** e o mesmo com o
sistema de arquivos cheio até os últimos 8 KB e esvaziado entre o corte e o
reinício: a configuração intacta.
- **30 minutos** sem reinício, os cinco sensores válidos em todas as amostras,
com o fio do RESET da PicoHand fora do pino RUN, como diz o `AGENTS.md` §1.
Com o fio ligado, a placa reiniciou sozinha quatro vezes em seis horas, sem
watchdog por trás de nenhuma. Uma delas veio aos 33,8 s de uma atualização a
partir do estado em que a placa chegou, na v2.10.0. A placa voltou na v2.10.0
com a configuração idêntica byte a byte, e a mesma atualização passou na
tentativa seguinte.
- **A suíte web na candidata,** com uma conta de administrador: 67 aprovados, 0
falhas.

### Atualizando

- **A partir da v2.11.0, nas duas placas:** pelo ar, na página Arquivos, com o
`.bin` desta release. A configuração vem junto. No Pico 2 W a atualização vai
para o outro slot e sobe em teste, como desde a v2.11.0.
- **De volta à v2.11.0:** pelo ar, com o `.bin` assinado dela (as duas têm o
nível de segurança 1), ou pelo USB.
nível de segurança 1; conferido na bancada, no Pico W), ou pelo USB.
- **A partir de uma versão mais antiga, ou a primeira instalação de um Pico 2
W:** como na v2.11.0, abaixo.
- **Pacotes de idioma:** envie os dois anexados a esta release pela página
Expand Down Expand Up @@ -132,6 +197,16 @@ painel, e nenhum dos dois passou da sua página de 4 KiB.
primeiro e com o valor do último**, pelo código.
- **A lista de marcadores da linha de alarmes na página Telemetria para na
v22.** O capítulo 22 do manual lista todos.
- **Adotar uma sonda, ou o `sensor_wipe`, não recomeça o histórico do slot.** Os
dois carimbam a época de provisionamento do slot, e nada a lê: o histórico
entrega todo registro de um slot sob o id atual dele. Na bancada, depois que o
slot 0 adotou outra sonda, as leituras dele de 4 de outubro voltaram sob o id
da sonda nova.
- **Depois de um boot, uma sonda que não é a do slot pode ter a primeira leitura
gravada.** O caminho de leitura confere a ROM a cada cinco leituras, a partir
da quinta. Na bancada, com outra sonda no GPIO do slot, a leitura de 20 s
depois do boot entrou no histórico como a do slot, e a quarentena começou no
minuto seguinte.

## v2.11.0 (2026-10-04)

Expand Down
2 changes: 1 addition & 1 deletion README.es-ES.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Los tres comparten el mismo núcleo:

| | |
|---|---|
| **Release actual** | **v2.11.1** (05/10/2026); el [changelog](CHANGELOG.md) dice qué cambió cada versión. SIMUT salió de beta con la v2.7.0, sobre mediciones: un soak de 8,18 h sin ningún reinicio y 6 de 6 actualizaciones por el aire sin perder nada. |
| **Release actual** | **v2.11.1** (12/10/2026); el [changelog](CHANGELOG.md) dice qué cambió cada versión. SIMUT salió de beta con la v2.7.0, sobre mediciones: un soak de 8,18 h sin ningún reinicio y 6 de 6 actualizaciones por el aire sin perder nada. |
| **Imágenes publicadas** | Cuatro imágenes, cada una en `.uf2` y `.bin`. Para la Pico W: `release` (panel táctil TFT), `alpha` (LCD 16×2 con consola Bluetooth) y `air` (registrador a batería sin pantalla). Para la Pico 2 W (RP2350): `releasetwo`, la release, cuyo `.uf2` lleva su tabla de particiones y cuyo `.bin` arranca a prueba. Junto a ellas van los packs de idioma pt-BR y es-ES y un manifiesto de OTA. Una imagen con otro conjunto de funciones sale del [configurador de build](https://angelointj.github.io/simut/configurador/), y el CI la compila desde `main`; el configurador todavía no compila para la Pico 2 W. |
| **Madurez** | <ul><li>`release`: **estable**.</li><li>`alpha`: publicado y probado en el banco, con su LCD 16×2 incluido desde el 26/09/2026.</li><li>`air`: **experimental**. Su único soak largo falló: un sueño en el ciclo 119 nunca despertó (F28). Hoy lo mitiga un watchdog a lo largo del despertar; la causa raíz no está confirmada.</li><li>`releasetwo`: **nueva** en la v2.11.0, probada en el banco en una Pico 2 W (RP2350 A2). Se actualiza por el aire en el otro slot, a prueba, y vuelve sola cuando la actualización no se confirma.</li></ul> |
| **Pruebas** | Cada pull request ejecuta 639 casos de test en el host en 9 suites, 60 s de fuzzing y análisis estático, y compila las siete imágenes de firmware con la caché fría. El comportamiento en hardware real se verifica en un banco — ver [Verificación en hardware](docs/VERIFICATION.es-ES.md). |
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ They share one core:

| | |
|---|---|
| **Current release** | **v2.11.1** (2026-10-05); the [changelog](CHANGELOG.md) says what each version changed. SIMUT left beta with v2.7.0, on measurements: an 8.18 h soak with 0 reboots, and 6 of 6 over-the-air updates with nothing lost. |
| **Current release** | **v2.11.1** (2026-10-12); the [changelog](CHANGELOG.md) says what each version changed. SIMUT left beta with v2.7.0, on measurements: an 8.18 h soak with 0 reboots, and 6 of 6 over-the-air updates with nothing lost. |
| **Published images** | Four images, each as `.uf2` and `.bin`. For the Pico W: `release` (TFT touch panel), `alpha` (16×2 LCD with a Bluetooth console) and `air` (headless battery logger). For the Pico 2 W (RP2350): `releasetwo`, the release, whose `.uf2` carries its partition table and whose `.bin` boots on trial. The pt-BR and es-ES language packs and an OTA manifest ship alongside. An image with a different set of features comes from the [build configurator](https://angelointj.github.io/simut/configurador/), and CI builds it from `main`; the configurator does not build for the Pico 2 W yet. |
| **Maturity** | <ul><li>`release`: **stable**.</li><li>`alpha`: published and bench-tested, its 16×2 LCD included since 2026-09-26.</li><li>`air`: **experimental**. Its one long soak failed: a sleep in cycle 119 never woke (F28). A watchdog across the wake now mitigates it; the root cause is not confirmed.</li><li>`releasetwo`: **new** in v2.11.0, bench-tested on one Pico 2 W (RP2350 A2). It updates over the air into its other slot, on trial, and goes back by itself when the update does not keep itself.</li></ul> |
| **Tests** | Every pull request runs 639 host test cases in 9 suites, 60 s of fuzzing and static analysis, and builds all seven firmware images from a cold cache. Behaviour on real hardware is verified on a bench — see [Verification on hardware](docs/VERIFICATION.md). |
Expand Down
Loading
Loading