Para leer el dispositivo mediante la función de usuario fread o similar se utiliza el miembro read: de la estructura file operations en la llamada a register_chrdev. En este caso es la función memoria_read. Tiene como argumentos una estructura tipo file, un buffer, buf, del cual leerá la función del espacio de usuario (fread), un contador del número de bytes a transferir, count, que tiene el mismo valor que el contador habitual de la función de lectura del espacio de usuario (fread) y finalmente la posición del fichero donde empezar a leer, f_pos.
En este caso simple, la función memoria_read procede a transferir el byte del buffer del driver, memoria_buffer, al espacio de usuario, mediante la función copy_to_user:
<<memoria read>>= ssize_t memoria_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) { /* Transferimos datos al espacio de usuario */ copy_to_user(buf,memoria_buffer,1); /* Cambiamos posición de lectura segun convenga */ if (*f_pos == 0) { *f_pos+=1; return 1; } else { return 0; } } |
Además cambiamos la posición de lectura en el fichero, f_pos. Si dicha posición está en el inicio del fichero, la aumentamos en una unidad y damos como valor de retorno el número de bytes leídos correctamente, 1. Si no estamos en el inicio del fichero devolvemos un fin de fichero, 0, ya que el fichero o dispositivo únicamente almacena un byte.
En la Tabla 7 se puede ver esta nueva función.
Eventos | Funciones de usuarios | Funciones del kernel |
Carga de módulo | insmod | init_module |
Abrir dispositivo | fopen | file operations: open |
Leer dispositivo | fread | file operations: read |
Escribir dispositivo | ||
Cerrar dispositivo | fclose | file operations: release |
Quitar módulo | rmmod | cleanup_module |
Tabla 7. Eventos de los drivers y sus funciones asociadas de intercambio entre el espacio de kernel y el espacio de usuario.