Skip to content

Tags: wdalmut/milkv-ipc

Tags

v1.2-duplex

Toggle v1.2-duplex's commit message
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

Toggle v1.1-device's commit message
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

Toggle v1-irq's commit message
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

Toggle v0-polling's commit message
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.