Quattrocento app, una alla volta
NucleoOS-P4 ha uno Store con oltre 400 app e un assistente, su un microcontrollore. Le funzioni le ho scelte io. La forma l'ha decisa la memoria.
di Nicola Sabaini 4 min di lettura Progetto: NucleoOS-P4
A luglio la scheda ha smesso di accendersi. Schermo nero, riavvio, schermo nero. Avevo appena cambiato la tabella delle partizioni, cioè il modo in cui è divisa la memoria flash, e ho dato la colpa a quella.
Non era quella. Il cavo seriale diceva un’altra cosa: all’avvio il sistema prova a mettere da parte 32 kilobyte di RAM interna, e non li trovava più.
Erano finiti in tre elenchi di nomi di file. Musica, video e registratore tenevano ciascuno una lista da 256 nomi, 32 kilobyte a testa, in memoria dall’accensione anche con l’app chiusa. Novantasei kilobyte per tre elenchi che nessuno stava guardando. Il registratore era il terzo, ed è bastato lui.
Due memorie, una piccola
NucleoOS-P4 gira su un ESP32-P4. Accanto al chip ci sono 32 MB di RAM esterna, la PSRAM: tanta per un microcontrollore, ma più lenta. Copiarci dentro dei dati va a circa 32 MB al secondo, cioè un fotogramma intero dello schermo costa più di trenta millesimi di secondo.
Dentro il chip c’è la RAM interna, quella veloce, l’unica che certe periferiche sanno usare. Con Wi-Fi e interfaccia accesi ne restano liberi fra 80 e 100 kilobyte, e il pezzo continuo più grande è di circa 31.
Sopra ci sono Doom, uno Store con oltre quattrocento app, un foglio di calcolo che apre i file Excel e un assistente. Quelle sono funzioni, e le ho scelte io. La forma del sistema invece l’ha decisa la memoria.
Un’app alla volta
Sul telefono le app restano aperte in sottofondo. Qui no. Gira un’app sola, quella davanti, e prende la memoria che le serve. Quando si chiude la restituisce tutta.
La regola è nata da quello schermo nero: niente buffer che vivono dall’avvio. Un’app chiede la memoria quando si apre, nella PSRAM, e la libera quando si chiude. I tre elenchi adesso esistono solo mentre la loro app è aperta.
Su uno schermo da sette pollici si guarda comunque una cosa alla volta.
Chiedere il numero vero
La fotocamera vuole quattro buffer da poco più di 4 MB l’uno, e ognuno deve essere un blocco continuo. All’inizio dichiarava di averne bisogno di 8 in tutto. Il controllo all’apertura passava, poi l’allocazione falliva a metà e l’app si apriva rotta.
Adesso dichiara 18 MB, il numero vero. Prima di dire di no, un gestore della memoria svuota le cache degli altri: quella di ANIMA, l’assistente, e quelle dei giochi. Se non basta ancora, la fotocamera non si apre, e lo dice subito.
Nel codice c’è una nota accanto a quel numero: non abbassarlo per farla aprire. Un rifiuto pulito si capisce. Un’app aperta a metà no.
Lo stesso file, ogni volta un errore diverso
Biblioteca, il lettore di Wikipedia offline, falliva a caso. A volte mancava memoria, a volte l’archivio risultava danneggiato. Ogni volta qualcosa di diverso, e il file era sempre lo stesso.
Colpa del modo in cui cresce la memoria di un’app WebAssembly: quando serve più spazio, il runtime alloca un blocco più grande e ci copia dentro tutto. Dopo un po’ la PSRAM è piena di buchi, e un blocco grande e continuo non c’è più, anche se la memoria libera in totale basterebbe.
Ho provato a chiedere 16 MB fin dall’inizio. A volte l’app non partiva nemmeno. Con 12 MB, presi e restituiti subito all’avvio quando il blocco grande è ancora libero, regge.
Centoquarantacinque secondi
Copiare un file da 21 MB sulla scheda SD ci metteva 145 secondi.
Il controller della SD sa spostare i dati da solo, senza passare dal processore: si chiama DMA. Ma lo fa solo se il buffer comincia a un indirizzo allineato. Altrimenti va un settore da 512 byte alla volta, ognuno con il suo comando.
Stesso file, buffer allineato a 64 byte: 11 secondi. Nessun algoritmo nuovo. Un indirizzo che comincia nel posto giusto.
Lo schermo azzurro
Durante gli aggiornamenti, e ogni tanto a caso, lo schermo diventava azzurro per un attimo.
Mentre il chip scrive sulla flash non può leggere codice dalla flash. La routine che a ogni fotogramma rilancia il pannello stava proprio lì, quindi durante ogni scrittura aspettava, e il pannello restava senza dati.
Spostarla nella RAM interna è costato 92 byte. Su 300 scritture di prova, prima i fotogrammi in ritardo erano quattro o cinque per giro. Dopo, zero.
L’undici per cento gratis
Sulla carta il P4 va a 400 MHz. Su questa scheda a 400 non parte: si riavvia all’infinito, perché il clock della PSRAM non si riesce a ricavare da quella frequenza.
L’ho scoperto con un aggiornamento via Wi-Fi. Il sistema non è arrivato a confermarlo, e si è rimesso da solo sulla versione precedente: la rete di sicurezza ha fatto il suo lavoro. Poi è servito un riflash col cavo. Adesso gira a 360, e accanto all’impostazione c’è scritto di non riprovarci.
Le regole scritte
Ognuna di queste storie è diventata una riga in un file di regole del progetto, con il guasto che l’ha generata. Niente stack in PSRAM per chi scrive sulla flash. Niente buffer statici per le app. Buffer allineati per la SD. Il motivo sta scritto accanto, perché una regola senza motivo prima o poi qualcuno la toglie.
È lo stesso discorso di Il vincolo è una specifica, visto da dentro un sistema che gira davvero.
Lo Store ha più di quattrocento app. In memoria, ne sta una.