Tags: wdalmut/milkv-ipc
Tags
v1.2-duplex - il canale va in entrambe le direzioni read() porta i campioni dal micro, write() porta i comandi al micro, dallo stesso /dev/duos-ipc. Seconda finestra a offset 2048 nella pagina gia' riservata: il device tree non e' cambiato. Verificato sulla board: - il percorso via solo mailbox, provato accendendo e spegnendo la voce del micro da userspace con comandi che l'SDK implementa gia': zero codice RTOS nostro nel percorso, e l'osservabile e' un comportamento che cambia, non una riga in un log; - il percorso con payload: `ipc-cmd send 1 0x2a 0xde 0xad 0xbe 0xef` arriva al micro come seq=1 arg=0x2a data=de ad be ef, letto attraverso la cache del C906. inv_dcache_range() fa quello che deve - era l'unico pezzo del design che non si poteva verificare in nessun modo prima dell'hardware. Cosa NON e' solido, e va saputo prima di costruirci sopra: la finestra dei comandi e' a slot singolo e la doorbell e' fire-and-forget. Per la telemetria va bene, un campione perso e' sostituito fra 100 ms. Un comando perso e' un guasto silenzioso: chi ha bisogno di garanzie usi RTOS_CMDQU_SEND_WAIT, che in questo verso e' esattamente lo strumento giusto mentre in ingresso era inutile. In questo snapshot IPC_RTOS_LOG e IPC_LOG_EVERY sono accesi: il micro parla sulla seriale e intreccia le righe con la console di Linux. E' uno stato da banco di prova, non da produzione.
v1.1-device - i dati escono dal device, niente root read() su /dev/duos-ipc restituisce i 32 byte di sensor_msg_t gia' verificati: il seqlock sta nel kernel, la finestra la mappa il driver con ioremap, e l'indirizzo arriva dal device tree via memory-region. Verificato sulla board: - selftest.sh passa tutti e nove i punti, compresa la lettura da utente nobody; - 300 campioni consecutivi senza un seq duplicato e con ts sempre crescente: e' la prova che ioremap da' una mappatura non cacheable su questo kernel T-Head, che era l'unica incognita del design; - dmesg: finestra [mem 0x8fe00000-0x8fe00fff] risolta dal DTS, non cablata; - un consumer in Go cross-compilato con CGO_ENABLED=0 legge il canale senza cgo, senza mmap e senza privilegi. /dev/mem resta solo dietro --devmem, per distinguere un producer morto da un modulo rotto. Da qui v2-ring e' un cambio che vive solo nel driver: il formato di read() non cambia e nessun consumatore se ne accorge.
v1-irq - il reader si sveglia sull'interrupt del mailbox Catena completa e automatica: il task FreeRTOS pubblica in memoria condivisa e suona la doorbell sul mailbox, il modulo duos_ipc_irq occupa lo slot handler di IP_SYSTEM ed espone /dev/duos-ipc, il reader dorme in poll() e si sveglia solo quando c'e' un campione. Verificato su immagine pulita, senza un file piazzato a mano: - 20 campioni a 10 Hz in 1.95 s reali con user 0.00s / sys 0.00s: il processo ha dormito per tutto il tempo; - il modulo si carica da solo al boot (dopo S99user) e da quell'istante non compare piu' un solo "error ip=6" in 42 s di log; - selftest.sh passa, inclusa l'asserzione che seq AVANZI fra due letture - la lacuna che aveva lasciato passare il crash del mailbox pieno. Il payload continua a passare da /dev/mem. Toglierlo di li', facendo uscire i dati dal device, e' il prossimo passo: elimina root e CONFIG_STRICT_DEVMEM, sposta il seqlock nel kernel e apre il canale a Go e Python senza unsafe.
v0-polling - baseline: payload in memoria condivisa, polling su seq Il reader fa polling su seq e la doorbell e' spenta (IPC_DOORBELL 0). E' il punto a cui tornare quando qualcosa in v1 si rompe: qui il canale dipende solo da memoria condivisa, barriere e cache policy, senza mailbox ne' interrupt. Verificato sulla board: magic corretto, seq monotona, ts crescenti. Comprende gia' la patch 0004, senza la quale l'RTOS muore prima ancora che Linux sia in grado di ascoltare.