viernes, 8 de junio de 2012

I2C bitbanging con OpenWRT en Fonera 2201

Vuelvo con un tutorial, y ésta vez es sobre cómo podemos exprimir nuestro router al máximo en cuando a tema de I/O se refiere.



Este proceso fue imprescindible para poder afrontar con éxito la arquitectura del Atropos, ya que se necesitaba al menos un puerto I2C para comunicarse directamente con los sensores Wii evitando intermediarios.

Hardware


 Lo primero que tenemos que hacer es localizar 2 pines GPIO libres. Cada 2 pines, podemos crear un puerto I2C. Un pin para SCL y otro para SDA.


Una vez abierta la carcasa, procedemos a identificar los GPIO. En la Fonera 2201 podemos encontrar suficientes usando las líneas que controlan los LED de actividad de red.

Identificando líneas GPIO, el número de línea está indicado a rotulador
Aquí hemos localizado cuatro GPIO, suficientes como para montar 2 puertos I2C independientes. Se tratan de las líneas 1,3,4,7.

Lo siguiente que tenemos que hacer es acceder a ellas, sacando los respectivos cables. Es una operación delicada, ya que hay que soldar junto a las resistencias SMD que vienen con los LED. Notar que en el caso del GPIO 3 la línea viene sin utilizar y la tarea se facilita.

Para ir sobre seguro, decidí ubicar una placa de puntos sobre la placa de la fonera, para tener una buena base desde la que sacar cables.

Éste es un buen sitio donde emplazar nuestra placa perforada


Una vez localizado el sitio, adaptamos nuestra placa perforada hasta que encaje sin problemas

Salvamos las dos resistencias de arriba

Limamos la superficie del GPIO libre de LED, para evitar el barniz


Además de sacar las líneas para el I2C, preparamos la placa para contener las líneas de 3.3V y GND

Soldando pequeños trozos de cable rígido a los terminales, procuramos que coincidan con los terminales GPIO

Al colocar la placa, ajustamos los terminales cuidadosamente, para que al siguiente paso, sólo sea necesario un poco de soldador




GPIO7: amarillo, será SCL, GPIO4: verde, será SDA



En este ejemplo hemos obtenido 3 de las 4 líneas que buscábamos. En este punto, ya podríamos usar un puerto I2C, utilizando 2 de las 3.
La cuarta, basta con repetir los pasos con una placa de puntos adicional, junto a la más grande.

Para alimentar nuestros gadgets I2C, podemos aprovechar la línea 3.3V del puerto serie de la propia Fonera. Esquema:




Una vez que tenemos tanto la línea de 3.3V + GND, y dos líneas GPIO disponibles, es hora de definir SDA y SCL del I2C. Realmente podemos elegir cualquiera. Aquí mi configuración con el primer I2C:

GPIO7: amarillo=SCL
GPIO4: verde = SDA
+3,3V Serie: rojo= +3.3V
GND Serie: blanco=GND


Software

Para poder usar nuestro nuevo puerto, es necesario cargar un módulo especial en el kernel, se trata del módulo i2c-gpio-custom.ko
Necesitamos soporte para i2c para el kernel. Aquí unas pantallas orientativas para habilitarlo desde una compilación manual.




Después de hacer esto y flashear la Fonera con el nuevo kernel, el módulo no estaba disponible. Tuve que subirlo manualmente copiándolo a través de ssh, desde la carpeta de compilación de OpenWrt, buscando el propio fichero i2c-gpio-custom.ko

En mi caso, quedó aquí: /lib/modules/2.6.26.8/i2c-gpio-custom.ko

Una vez en nuestra Fonera con OpenWrt, hacemos iniciable el módulo e indicamos los pines que queremos usar:

$router# mv /etc/modules.d/59-i2c-gpio   /etc/modules.d/59-i2c-gpio-custom 
$router# echo "i2c-gpio-custom bus0=0,4,7 bus1=1,3,1" >/etc/modules.d/59-i2c-gpio-custom

$router# echo "i2c-gpio" >/etc/modules.d/60-i2c-gpio
$router# reboot


Notar el parámetro bus0=0,4,7 y bus1=1,3,1 estamos indicando que queremos 2 puertos I2C, el primero va a estar en /dev/i2c0, con pin GPIO4 como SDA y GPIO7 como SDL. El segundo va a estar en /dev/i2c1 con pin GPIO3 como SDA y GPIO1 como SDL

Ahora podemos montar cualquier gadget I2C a cualquiera de nuestros buses I2C y hacer un sondeo con el paquete i2c-utils que tendremos que tener instalado.

$router# i2c-detect /dev/i2c0



Más información:

http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/include/linux/i2c-algo-bit.h#L43
http://www.mjmwired.net/kernel/Documentation/i2c/dev-interface

jueves, 23 de febrero de 2012

Compilación cruzada con OpenWrt (cross compiling)

Voy a ir explicando en sucesivos posts, cómo he montado la plataforma para que el Átropos pudiera funcionar, desde el punto de vista del firmware.



en este primer round vamos a ver cómo compilar programas que hemos hecho nosotros mismos, para el firmware OpenWrt.
Los requisitos previos a este punto, son:
-Tener un router ya flasheado con OpenWrt, con wget instalado
-Tener un equipo con GNU/Linux, en el cual, vamos a bajar el código fuente de OpenWrt
-En el equipo Linux vamos a tener:
    -Servidor FTP ya montado
    -Fuentes de la misma versión de OpenWRT que tenemos cargado en el router (en mi caso es un kamikaze 8.09.2) Bajar estas fuentes

El escenario que vamos a ver es el más sencillo de todos. No vamos a construir una imagen nueva para incluir el SDK en el router, sino que vamos a usar el SDK en la máquina Linux. Los motivos principales son, ahorrarnos espacio en el router, y trabajar más cómodamente en la máquina linux, donde podemos tener más herramientas que un simple editor vi. Además de no tener  que reflashear el router.

nos colocamos en nuestro directorio de trabajo y lanzamos

linux$ wget http://downloads.openwrt.org/kamikaze/8.09.2/kamikaze_8.09.2_source.tar.bz2
linux$ bzip2 -dc kamikaze_8.09.2_source.tar.bz2 | tar -xv

ya tenemos bajado y descomprimido los fuentes en una carpeta.

Nota: A partir de este punto es recomendable automatizar estas tareas en un script bash.

Añadimos al PATH la ruta a los binarios de gcc de la plataforma, e indicamos que el compilador actual es el de mips (si ls arquitectura del router es MIPS) .

linux$ export PATH=$PATH:/<tu ruta de trabajo>/kamikaze_8.09.2/staging_dir/toolchain-mips_gcc4.1.2/bin/
linux$ export CC=mips-linux-uclibc-gcc



Suponiendo que tenemos un sencillo programa en c, que se llame "holamundo.c", hacemos:

linux$ mips-linux-gcc  -o holamundo holamundo.c

Si usamos librería externas como math.h, las enlazamos normalmente (-lm para math.h) como lo haríamos con un gcc corriente.

Si es necesario, copiamos el fichero generado a donde tenemos apuntando nuestro servidor de ftp

linux$ cp holamundo /<ruta de tu ftp>/<directorio de tu usuario>/holamundo


Nos vamos a nuestro flamante router, y en una sesion abierta de SSH, lanzamos

router$ wget ftp://<ip de tu maquina linux>/<ruta relativa al programa>/holamundo
router$ chmod 770 holamundo
router$ ./holamundo

Y ya tenemos corriendo nuestro programa de prueba en OpenWrt