|
Appunti sullo sviluppo di un driver per Linux per il controllo di una automobilina radiocomandatadi Marco Faella e Marco Trucillo |
3.1 Write |
|
Veniamo finalmente al cuore del driver: la funzione di scrittura.
Essa consiste essenzialmente in un ciclo while che invia ogni carattere fornito dall'utente alla porta parallela appropriata, dopo aver filtrato i comandi non validi. In più, la funzione deve far si che il comando rimanga attivo per il numero di secondi specificato. Per far questo la funzione deve "dormire" e lo fa modificando direttamente il record di attivazione (process control block) del processo che ha invocato car_write, record puntato dalla variabile globale current. Poi invoca lo scheduler perché dia il controllo ad un altro processo finché il numero di secondi richiesto non è trascorso. Ultimo accorgimento, un ciclo while più interno che, ritentando più volte la scrittura di ogni carattere, cerca di aggirare eventuali difetti occasionali della porta. La funzione restituisce il numero di caratteri correttamente inviati alla porta. static int car_write(struct inode * inode, struct file * file, const
char * buf, int count)
temp = buf;
|
|
3.2 Inizializzazione |
|
L'inizializzazione del driver è compito della procedura
car_init, che per prima cosa invoca register_chrdev(), la
funzione che, come abbiamo già visto, tutti i driver a caratteri
devono chiamare per esportare le proprie funzionalità verso il sistema
operativo e più precisamente presso il Virtual File System.
Fatto questo, car_init si servirà di car_probe sia per verificare, con una chiamata a check_region(), la presenza della porta parallela necessaria sia per controllarne il corretto funzionamento. Quest'ultimo controllo viene fatto scrivendo un carattere sulla porta e rileggendolo dalla stessa. Se la porta supera i due test appena descritti, viene acquisita dal driver con la chiamata a request_region(). La funzione printk(), più volte usata in questa porzione del driver, è la versione kernel della printf ed ha, tranne poche eccezioni, il suo stesso formato. A differenza di quest'ultima, la printk scrive generalmente su file di sistema invece che sullo schermo, tranne che durante la fase di boot del sistema. static struct file_operations car_fops = {
static int car_probe(int offset)
base = CAR_B(offset);
if (check_region(base, ((base == 0x3bc)? 3 : 8)) <
0)
if (testvalue == 0x055) { /* inizializzazione riuscita */
int car_init(void)
if (register_chrdev(CAR_MAJOR,"car",&car_fops)) {
for (offset = 0; offset < CAR_NO; offset++) count+= car_probe(offset);
return 0;
|
|
3.3 Conclusioni |
|
Finisce qui l'esposizione del nostro lavoro. Anche se abbiamo
descritto soltanto uno scheletro di driver, ci auguriamo possa comunque
risultare utile a quanti, per studio o lavoro, debbano inoltrarsi nella
programmazione di sistema in ambiente Linux.
|
|
3.4 Bibliografia e webliografia |
|
Bibliografia
"Segreti di Linux", Apogeo
"Linux Device Drivers", O'Reilly & Associates
"Linux Kernel Internals", Addison Wesley Webliografia |