Intel Galileo. Device Drivers

Device Driver y Modulo tienen el mismo significado en este contexto, ambos se refieren a un Controlador de Dispositivo. Dispositivo y Periférico se refieren al mismo componente de hardware que puede integrarse / removerse de un sistema de computo.

Introducción 

El concepto de Device Driver (Controlador/Manejador de Dispositivo) consiste en ofrecer una interfaz de usuario consistente hacia una gran variedad de dispositivos/periféricos. Tienen la función de ocultar la complejidad del dispositivo de hardware al usuario, Linux (a diferencia de otros sistemas operativos) tiene la capacidad de agregar y remover componentes del kernel en tiempo de ejecución, el sistema Linux se estructura como un núcleo monolítico con una interfaz bien definida para agregar y remover módulos de forma dinámica después del tiempo de arranque/inicio (boot time). Los Device Drivers se dividen en dos categorías: 1) Character Devices- se pueden imaginar como un flujo secuencial de datos de forma serial (Teclado, puertos seriales) 2) Block Devices- tienen la capacidad de leer/escribir bloques de datos  de forma aleatoria en un medio direccionable (Disco duro, memoria SD).

Los módulos tienen una aplicación importante en los sistemas embebidos, ofrecen un campo para la actualización de un sistema sin la necesidad de hacer un reboot. En este apartado me enfoque en la implementación de un device driver mínimo,  lo que es relativamente fácil en un sistema Linux. lsmod (list módulos) nos permite ver los device driver que actualmente están integrados en nuestra tarjeta Galileo.

Selección_068Algunos de ellos son intuitivos como usbcore o gpio_sch (General Purpose Input and Output / Entrada y Salida de Propósito General), y algunos no tanto como ehci_pci (Enhanced Host Controller Interface / Interfaz de Controlador Host Mejorado) encargado  del manejo de una comunicación de alta velocidad desde la tarjeta al exterior.  Que utilidad hay en crear nuestro propio driver?

Ejemplo

embedded

 

Tal como se muestra en la imagen, nuestro desarrollo es así: En nuestro sistema Host creamos y compilamos el driver, en nuestro sistema Target es donde lo vamos a instalar; en mi caso el Host consiste en una Laptop VAIO con Ubuntu Gnome de 64 bits, el Target es un Galileo Intel i386 usando Debian Whezzy.

Actualizamos e instalando gcc en nuestro sistema Target:

apt-get update

apt-get install gcc

Creamos el archivo Hola.c con el siguiente código en el Host :

/*Example Minimal Character Device Driver*/

#include <linux/module.h> //Necesario para todos los modulos

static int __init hello_init(void)

{ printk(“\tHello Example Init\n”); retun 0;

}

static void __exit hello_exit(void)

{ printk(“\tHello Example Exit”);

}

module_init(hello_init);

module_exit(hello_exit);

MODULE_DESCRIPTION(“Hello World Example”);

MODULE_LICENSE(“GPL”);

No lo compiles! antes hay que tomar en cuenta algunas cosas, los módulos/drivers  a diferencia de los programas program.c no inician en una función main(), los drivers requieren de al menos dos funciones: una de inicio hello_init() y otra de salida o limpieza hello_exit(), puedes usar cualquier nombre para estas funciones pero por convención se emplea init_module() y cleanup_module(). Las funciones module_init y module_exit son las encargadas de indicarle al sistema cual es la operación de inicio, y cual la de salida.  

printk no tiene la función de comunicar información al usuario, por lo regular se utiliza para enviar mensajes o warnings  usando las macros contenidas en linux/kernel.h de esta forma:

#include <linux/hernel.h>

printk(KERN_INFO “Kernel info\n”);

Los drivers se compilan de forma distinta a las aplicaciones o programas que se ejecutan en el espacio de usuario, los drivers se ejecutan en espacio kernel y por ello requieren de características especificas en su implementación, ademas de que presentan un riesgo debido a que tienen acceso a los recursos del kernel. Para compilarlo creamos un Makefile en el mismo directorio donde se encuentra nuestro Hola.c

obj-m := Hola.o

all:

       make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean: 

       make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

 

Usamos make para crear el archivo Hola.ko (Kernel Object) y usamos scp (secure copy) para pasar esos archivos al Target. scp nos va a solicitar la contraseña del usuario root para poder hacer esa trasferencia de archivos via ssh (ponemos la contraseña root). En mi caso copie toda la carpeta.

Selección_072

 

 

insmod Hola.ko nos permite insertar el modulo (driver) en el kernel actual, pero no da un error debido a que este modulo fue creado en una arquitectura de 64 bits. En esta pagina  (link) hay un componente llamado Cross Compiler Toolchain, el toolchain es una herramienta que nos permite generar binarios desde una arquitectura de Host diferente a la arquitectura del Target.

 

Selección_073

 

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s