Da questi tre fattori che hai elencato solo il primo è effettivamente corretto. Per il resto, non proprio. È possibile che un codice spaziale utente esegua operazioni DMA, nessun problema. Ci sono molte aziende di dispositivi hardware che impiegano questa tecnica nei loro prodotti. È anche possibile avere un'applicazione di spazio utente basata su interrupt, anche quando tutto l'I/O viene eseguito con un bypass completo del kernel. Certo, non è così facile semplicemente fare un mmap()
su /dev/mem
.
Si dovrebbe avere una minima parte del driver nel kernel - che è necessaria al fine di fornire il vostro spazio utente con un minimo di cui ha bisogno dal kernel (perché se ci pensate - /dev/mem
è anche supportato da un driver di dispositivo di carattere).
Per DMA, in realtà è troppo dannatamente facile - tutto ciò che dovete fare è quello di gestire mmap
richiesta e mappare un DMA tampone nello spazio utente. Per gli interrupt - è un po 'più complicato, l'interrupt deve essere gestito dal kernel, non importa cosa, tuttavia, il kernel potrebbe non funzionare e semplicemente riattivare il processo che chiama, per esempio, epoll_wait()
. Un altro approccio è quello di fornire un segnale al processo come fatto da DOSEMU, ma che è molto lento e non è raccomandato.
Come per la tua domanda, un fattore da tenere in considerazione è la condivisione delle risorse. Finché non è necessario condividere un dispositivo su più applicazioni e non c'è nulla che non si possa fare nello spazio utente: andare nello spazio utente. Probabilmente risparmierai un sacco di tempo durante il ciclo di sviluppo poiché scrivere codice utente dello spazio è estremamente semplice. Quando, tuttavia, due o più applicazioni devono condividere il dispositivo (o le sue risorse), è probabile che spenderai una quantità enorme di tempo per renderlo possibile - immagina più processi di forking, crash, mapping (lo stesso?) Memoria simultaneamente ecc. E dopo tutto, IPC viene generalmente eseguito attraverso il kernel, quindi se l'applicazione dovrebbe iniziare a "parlare" tra loro, le prestazioni potrebbero peggiorare notevolmente. Questo è ancora fatto nella vita reale per alcune applicazioni critiche per le prestazioni, però, ma non voglio entrare in questi dettagli.
Un altro fattore è l'infrastruttura del kernel. Diciamo che vuoi scrivere un driver di dispositivo di rete. Non è un problema farlo nello spazio utente. Tuttavia, se lo fai, dovresti scrivere anche uno stack di rete completo in quanto non sarà possibile per l'utente predefinito di Linux che risiede nel kernel.
Direi di andare per lo spazio utente se è possibile e la quantità di sforzi per far funzionare le cose è inferiore alla scrittura di un driver del kernel e tenere presente che un giorno potrebbe essere necessario spostare il codice nel kernel . In effetti, è una pratica comune avere lo stesso codice compilato sia per lo spazio utente che per lo spazio del kernel a seconda che alcune macro siano definite o meno, perché testare nello spazio utente è molto più piacevole.
Sicurezza: autorizzazioni file del controllo del nodo dispositivo che gli utenti possono aprire/leggere/scrivere sul dispositivo. Le operazioni sui file negano o consentono operazioni simultanee. – sawdust
La decisione può dipendere in gran parte da cosa si sta facendo da PWM e dall'hardware. –