sábado, 21 de marzo de 2009

El targetfs de un sistema embedded

Un sistema embedded es un sistema informático de bajo coste, y de propósito general, que corre sobre una plataforma hardware con recursos generalmente escasos. El hecho de que los recursos hardware escaseen en el sistema embedded, plantea problemas nuevos al ingeniero de software generalmente acostumbrado a trabajar con un ordenador de sobremesa. Imagina por un momento que tuvieras que instalar una distribución de Linux de las tipicas (Ubuntu, Fedora, Suse, etc.) en un disco duro de solo 4MB. Una distribucion Debian tipica minima (excluyendo el kernel) ocupa unos 40MB, demasiado para nuestro sistema embedded. Necesitas una alternativa bastante mas ligera.

El objetivo de este post es generar un targetfs para el sistema embedded que tenga disponibles todas las aplicaciones del user-space necesarias para manejar tu dispositivo embedded (target). Para ello usaremos la herramienta busybox.



Su manual (man) lo define como "The Swiss Army Knife of Embedded Linux", algo asi como "la navaja suiza de los Linux embedded". Busybox es un único binario que combina pequeñas versiones de los distintos comandos basicos de un sistema Linux. En terminologia busybox, cada comando basico es un "applet". La lista de los 107 applets incluidos no tiene desperdicio:

addgroup, adduser, adjtimex, ar, arping, ash, awk, basename, bunzip2,
busybox, bzcat, cal, cat, chgrp, chmod, chown, chroot, chvt, clear, cmp,
cp, cpio, crond, crontab, cut, date, dc, dd, deallocvt, delgroup, deluser,
devfsd, df, dirname, dmesg, dos2unix, dpkg, dpkg-deb, du, dumpkmap,
dumpleases, echo, egrep, env, expr, false, fbset, fdflush, fdformat, fdisk,
fgrep, find, fold, free, freeramdisk, fsck.minix, ftpget, ftpput, getopt,
getty, grep, gunzip, gzip, halt, hdparm, head, hexdump, hostid, hostname,
httpd, hush, hwclock, id, ifconfig, ifdown, ifup, inetd, init, insmod,
install, ip, ipaddr, ipcalc, iplink, iproute, iptunnel, kill, killall,
klogd, lash, last, length, linuxrc, ln, loadfont, loadkmap, logger, login,
logname, logread, losetup, ls, lsmod, makedevs, md5sum, mesg, mkdir,
mkfifo, mkfs.minix, mknod, mkswap, mktemp, modprobe, more, mount, msh, mt,
mv, nameif, nc, netstat, nslookup, od, openvt, passwd, patch, pidof, ping,
ping6, pipe_progress, pivot_root, poweroff, printf, ps, pwd, rdate,
readlink, realpath, reboot, renice, reset, rm, rmdir, rmmod, route, rpm,
rpm2cpio, run-parts, rx, sed, seq, setkeycodes, sha1sum, sleep, sort,
start-stop-daemon, strings, stty, su, sulogin, swapoff, swapon, sync,
sysctl, syslogd, tail, tar, tee, telnet, telnetd, test, tftp, time, top,
touch, tr, traceroute, true, tty, udhcpc, udhcpd, umount, uname,
uncompress, uniq, unix2dos, unzip, uptime, usleep, uudecode, uuencode,
vconfig, vi, vlock, watch, watchdog, wc, wget, which, who, whoami, xargs,
yes, zcat

Busybox funciona usando argv[0] para determinar el applet que debe invocar. Al renombrar el binario de busybox con el nombre de un applet determinado, se ejecuta dicho applet. Sin embargo esto no es practico. El truco que usa busybox es tener un único binario llamado "busybox" y tener un enlace (link) simbólico distinto por cada applet apuntando al binario de busybox. Asi por ejemplo:
$ ls -l /bin
-rwxr-xr-x 1 0 0 272800 busybox
lrwxrwxrwx 1 0 0 12 sh -> busybox
lrwxrwxrwx 1 0 0 12 cp -> busybox
lrwxrwxrwx 1 0 0 12 ls -> busybox

Para crear los enlaces simbólicos, se usa el comando ln:
$ ln -fs busybox sh
$ ln -fs busybox cp
$ ln -fs busybox ls

Así por ejemplo, para ejecutar un listado largo usando el applet ls, hacemos:
$ /bin/ls -l

donde /bin/ls es en realidad un link apuntando al binario busybox.

Para compilar busybox, hay que descargar los fuentes, preferiblemente del sitio oficial http://www.busybox.net/downloads/. Para obtener los fuentes de la versión 1.9.0 y extraer su contenido, hacemos esto:
$ cd /usr/src
$ wget http://www.busybox.net/downloads/busybox-1.9.0.tar.gz
$ tar xvfz busybox-1.9.0.tar.gz

Durante el proceso de configuración de la compilación de busybox, el usuario decide los applets que integra el binario resultante una vez compilado. Para ello, busybox emplea un método similar al de la compilación del kernel de Linux (.config), pudiendo usar varias opciones:
$ make allnoconfig
$ make oldconfig
$ make menuconfig

Para realizar la compilación, basta con ejecutar el comando make, igual que se hace con el kernel de Linux, y el binario resultante aparece en la raiz de los fuentes:
$ make

Despues de un buen rato esperando, tendras compilado tu busybox.

Retomando el objetivo inicial de este post, nos interesa generar un targetfs para el dispositivo embedded. Para ello crea una partición de 4MB en un fichero de tu disco duro (por ejemplo targetfs4M.img) y crear un sistema de ficheros en su interior (por ejemplo, formatealo con EXT2).
$ dd if=/dev/zero of=targetfs4M.img bs=1M count=8
$ mkfs.ext2 -F targetfs4M.img

Despues monta la partición de 4MB recien creada (targetfs4M.img) en el sistema de ficheros de tu ordenador de sobremesa, por ejemplo en el directorio /media/removable.
$ mount -o loop targetfs4M.img /media/removable

Por ultimo instala el binario de busybox en el targetfs de tu sistema embedded:
$ make install CONFIG_PREFIX=/media/removable

La instalación copia el binario del busybox en /media/removable (en la partición de 4MB montada en ese directorio) y crea en su interior todos los enlaces simbólicos a los applets configurados y compilados dentro del directorio de compilación.

Con esto ya tienes un targetfs básico para tu sistema embedded. No estará completo porque deberás añadir la aplicación que deba correr tu sistema embedded, pero ya dispones de un buen punto de partida para empezar a jugar con tu sistema. Ah! Y no olvides hacer un sync y desmontar /media/removable antes de hacer nada mas con esa partición!

viernes, 27 de febrero de 2009

Ya no me gustas GNOME: bienvenido XFCE

He sido usuario de GNOME durante los últimos 5 años. No tenía nada en contra de KDE (de hecho desarrollo habitualmente con la libreria Qt), pero una vez me acostumbré a sus atajos de teclado, llegó el momento que sin ellos mi vida ya no tenia sentido. ¡Que sería de mi si no pudiera abrir un nuevo tag del terminal con Mays+Ctrl+t [...]!

GNOME y KDE son dos de los escritorios de Linux mas extendidos en la actualidad. Los dos cumplen su función de manera extraordinaria, facilitando las tareas a los usuarios, sobre todo a aquellos usuarios que yo llamo "de la generación ventana", poco o nada acostumbrados al uso del terminal. (A todos vosotros, no sabeis lo que os perdeis. Bueno, este será tema de otro debate).

Sin embargo, ambos escritorios comparten un serio problema que me disgusta bastante, acentuado sobre todo en sus últimas versiones: un consumo de recursos exagerado, que causa una caida notable del rendimiento del PC. Esta perdida de rendimiento se nota mucho mas en los PCs con menos cantidad de memoria RAM. ¿No era ese uno de los motivos por los que yo no gustaba de usar Windows [...]?

En el caso de GNOME corriendo en mi PC con 1GB de memoria RAM, mas de 500MB los consumía GNOME, el solito. Y claro, cuando los recursos de tu PC escasean y la economía no está para muchos extras tecnológicos (esperaremos tiempos mejores), uno tiene que mirar alternativas que satisfagan sus necesidades de la mejor manera posible.

Y buscando por google encontré una alternativa que me gustó, y me gustó mucho. Tanto que desde entonces ha pasado a ser el nuevo escritorio de mi PC. Se trata del escritorio XFCE (version 4) que viene de serie en la distribución XUbuntu.

Como podeis ver en este pantallazo, a primera vista se trata de un escritorio similar a cualquier otro que ya esteis acostumbrados a usar:



Si seguis mirando capturas de pantalla vereis que pese a su sencillez, es bastante completo: un panel con multitud de opciones para su configuración, escritorios virtuales, transparencias en las ventanas, en los marcos, applets para la barra de tareas. Y por lo que he podido probar hasta ahora, muy estable.







Estamos de acuerdo en que no es un GNOME+compiz con escritorios virtuales rotando en 3D con efectos de aguas al mover la ventanas, iconos animados y tal. Pero, ¿y que me aporta a mi toda esa parafernalia? Pues en realidad muy poco. Esas características las usamos mas para presumir de escritorio bonito que para aumentar nuestra productividad.

En cambio, ¿que gano yo usando XFCE? Un escritorio que consume 14MBytes en memoria RAM, y deja libre casi 1GByte de memoria RAM para que se ejecuten las aplicaciones de mi PC. Desde que lo he instalado, mis aplicaciones estan radiantes de felicidad, dando saltos de alegría por los bits de mi memoria RAM. Todas han abandonado el cuarto oscuro llamado "la partición de swap" por completo. Y me lo agradecen todos los días dandome unos tiempos de respuesta inauditos desde hacía mucho tiempo. Y ese placer espiritual que produce poder abrir un nuevo tag del xfce4-terminal con Mays+Ctrl+t [...]

¿Que mas se le puede pedir a un escritorio? Sin duda alguna... ¡Me gustas XFCE, bienvenido a mi PC!

sábado, 31 de enero de 2009

Usando valgrind + memcheck como debugger

Linus Torvalds declaró en este post su postura contraria al uso de debuggers en el kernel, argumentando que son herramientas usadas por los malos desarrolladores que, lejos de aprender de sus errores, se concentran en resolver el problema sin profundizar en la causa real del error. Y por tanto, prefiere mantenerlos lejos del desarrollo del kernel. Desde luego que tiene mucha razón (palabra de Linus).

Mi postura, no tan radical, aunque totalmente de acuerdo con sus argumentos. Es deseable desarrollar con sumo cuidado e intentar evitar todos los fallos durante la codificación, pues detectarlos a posteriori en ocasiones puede ser complicado. Sin embargo, puede que tengamos que analizar algun core de código que no hemos escrito nosotros. Y en una línea que nunca en la vida debería fallar. ¿Que esta ocurriendo?. ¿Que hacemos ahora? Es en estos casos cuando necesitamos ayuda de lo que yo llamo "las fuerzas especiales".


En este post os voy a explicar como usar el debugger valgrind con la herramienta memcheck para detectar 5 errores comunes en la programación de C/C++. Lo vemos en estos 5 test:

Test 1: Detección de una perdida de memoria:

03 int main()
04 {
05 char *x = malloc(100); /* memory leak */
06 return 0;
07 }
$ gcc -g test1.c -o test1
$ valgrind --tool=memcheck --leak-check=yes ./test1
==8458== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==8458== at 0x4C265AE: malloc (vg_replace_malloc.c:207)
==8458== by 0x40051D: main (test1.c:5)


Test 2: Detectar escrituras fuera de los limites de la memoria reservada:

03 int main()
04 {
05 char *x = malloc(10);
06 x[10] = 'a'; /* write out of bounds */
07 return 0;
08 }
$ gcc -g test2.c -o test2
$ valgrind --tool=memcheck --leak-check=yes ./test2
==17039== Invalid write of size 1
==17039== at 0x40052A: main (test2.c:6)
==17039== Address 0x519d03a is 0 bytes after a block of size 10 alloc'd
==17039== at 0x4C265AE: malloc (vg_replace_malloc.c:207)
==17039== by 0x40051D: main (test2.c:5)


Test 3: Detectar el uso de variables sin inicializar:

03 int main()
04 {
05 int x;
06 if (x == 0) /* uninitialised variable */
07 printf("x is zero");
08 return 0;
09 }
$ gcc -g test3.c -o test3
$ valgrind --tool=memcheck --leak-check=yes ./test3
==17070== Conditional jump or move depends on uninitialised value(s)
==17070== at 0x400518: main (test3.c:6)


Test 4: Intentar liberar una zona de memoria que no ha sido reservada:

03 int main(void)
04 {
05 char * str;
06 free(str); /* free not allocated */
07 return 0;
08 }
$ gcc -g test4.c -o test4
$ valgrind --tool=memcheck --leak-check=yes ./test4
==17092== Conditional jump or move depends on uninitialised value(s)
==17092== at 0x4C25265: free (vg_replace_malloc.c:323)
==17092== by 0x40051C: main (test4.c:6)


Test 5: delete en C++ mal hecho:

01 int main(void)
02 {
03 char * str = new char[10];
04 delete str; // instead of: delete [] v;
05 return 0;
06 }
$ g++ -g test5.c -o test5
$ valgrind --tool=memcheck --leak-check=yes ./test5
==17116== Mismatched free() / delete / delete []
==17116== at 0x4C24DAD: operator delete(void*) (vg_replace_malloc.c:342)
==17116== by 0x40067A: main (test5.cpp:4)


Hemos visto que valgrind es una herramienta de mucha ayuda para un desarrollador de C/C++ que sin duda nos ayudará a resolver muchos bugs. No obstante, tambien tiene sus limitaciones, por ejemplo que memcheck no comprueba los limites en los arrays estaticos, y por tanto no detecta este error:

01 int main()
02 {
03 char x[10];
04 x[11] = 'a'; /* not detected! */
05 return 0;
06 }


No obstante, debemos recordar las palabras de Linus. Los debugger son para los malos programadores. Y nosotros queremos ser buenos programadores. Asi que debemos aprender de nuestros errores e intentar que no vuelvan a repetirse en el futuro. Si seguis estos consejos, los debuggers tienen los días contados :-) En todo caso, para mi, el mejor debugger que ha existido y que siempre existirá es el printf (en C) o el cout (en C++).

viernes, 23 de enero de 2009

Controla tu tarifa plana de Orange

Todos debemos (deberíamos) llevar un control exhaustivo del gasto mensual que hacemos en la factura de nuestro teléfono movil, y mas en plena época de crisis en la que siempre viene tan bien ahorrarse unas pelillas. Lo primero sin duda es elegir una tarifa que se adapte a vuestras necesidades.

En mi caso, tengo la tarifa plana de Orange: pago 22 euros al mes y hablo 1000 minutos gratis. Eso siempre que las llamadas sean dentro de la franja horaria de 18-08h. Los SMS y las llamadas fuera de la franja horaria se pagan aparte. El problema de la tarifa plana es que Orange no proporciona ningún servicio para controlar los minutos consumidos (ya me informé en su momento, muy mal hecho señores de Orange) y cuando (como en mi caso) apuras el consumo mensual hasta el último suspiro, a veces puedes llevarte sorpresas desagradables si no controlas el tiempo.

Este post explica como controlar los minutos que todavía os quedan disponibles para seguir llamando, y así poder apurar al máximo los minutos gratuitos. Para ello necesitas dos cosas: el listado de llamadas del periodo de facturación actual (en formato .txt) y un bash shell script en Linux que desarrollé hace algun tiempo y que extrae la información de esa factura.

El bash shell script lo teneis disponible aqui.

http://socios.aditel.org/~icastell/develex/bash/orangeTarifaPlanaActual.sh

Esta licenciado bajo GPL, asi que podeis usarlo y modificarlo a vuestro antojo, siempre que respeteis la licencia.

Para conseguir el listado de llamadas del periodo de facturación actual, hay que darse de alta en la página de Orange, enviando un SMS (gratuito) desde vuestro movil Orange al 222, con el texto CLAVE seguido de un espacio y la clave entre 6 y 8 dígitos, por ejemplo: CLAVE 12345678. Después os autentificais en el área de clientes de su página web http://www.orange.es, introduciendo vuestro número de teléfono y el password que hayais elegido en el SMS:
En el menú que aparece a la izquierda, hay que seleccionar dentro del apartado "mi factura y consumo", la opción "listado de llamadas" e insertar en el calendario el periodo de facturación en el que estais interesados:
En pantalla aparece un listado de todas las llamadas realizadas en el periodo de facturación indicado en el paso anterior. Lo siguiente es pulsar el boton que aparece al pie de la pagina "Imprimir todas las paginas", tal y como muestra la siguiente imagen:
Al pulsar ese boton aparece una ventana emergente para iniciar la impresión. Esa ventana no será necesaria, debes cerrarla. En pantalla tendrás el listado de todas las llamadas realizadas. Debes seleccionarlo al completo desde la primera llamada hasta la última, y usar la función de copiar/pegar para guardarlo en un fichero de texto llamado factura.txt (en realidad el nombre es irrelevante).

Ya tienes el listado de llamadas. Ese listado lo vas a usar como input del script que ya debes haber descargado. Para probarlo, basta con que ejecutes esto en linea de comandos del bash:

$ orangeTarifaPlanaActual.sh factura.txt

Los resultados del script son concluyentes:

Gasto en llamadas sin descuentos = 234.1776 (euros)
Gasto en llamadas con descuentos = 6.5448 (euros)
Minutos gratis consumidos = 994.26666666666666666666
Minutos gratis restantes = 5.73333333333333333334
Total factura a pagar este mes = 33.111968 (euros)

Este mes nos han sobrado poco mas de 5 minutos. Podríamos haber hecho una llamadita mas. Pero mas de 200 euros de ahorro en llamadas, ¡no estan nada mal!

domingo, 4 de enero de 2009

El cubo de Rubik

Papa Noel me trajo estas Navidades un juguete nuevo muy chulo: un cubo de Rubik de 3x3. De pequeño ya tuve uno, pero me causó una gran frustración no poder resolverlo nunca y finalmente opté por despegar todas las pegatinas y pegarlas en su posición correcta. ¿Lo resolví o no? jeje. Pues si, pero a partir de entonces el cubo quedo algo dañádo, por decirlo de alguna manera, y algunas pegatinas se caian de cuando en cuando... Aquella azaña no me dejó un buen sabor de boca. Asi que estas vacaciones me puse manos a la obra, leyendo algunos manuales de Internet, para sacarme la espinita.

El cubo viene resuelto de fábrica, asi que lo primero que hay que hacer es enredarlo todo lo que podais. De eso se encargó mi hermano antes de regalarmelo... ¡ya te apañaras! me dijo. ¡Que cabron! jeje Pense yo. Pero no os preocupeis porque puede resolverse desde cualquier posición. Nuestra posicion de partida del cubo es la siguiente:


Para empezar hay que tomar una cara de referencia como cara superior del cubo. Sirve cualquiera, asi que vamos a tomar la blanca que me gusta mas. Debes hacer una cruz en la cara blanca. Ademas, todas sus caras laterales deben tener el color de su celda central del mismo color que la celda que hay por encima:


Una vez has conseguido esto, debes completar toda la primera fila de cada lateral de su color, lo que a su vez completará la cara superior de color blanco:


Ahora debes completar la segunda fila de cada lado:


En este punto, debes girar el cubo, tomando como base la cara blanca y como cara superior la cara amarilla (todavia sin completar):


Igual que hiciste con la cara blanca, debes hacer una cruz en la cara amarilla, por supuesto sin estropear la cara blanca ni las dos filas inferiores que ya tenemos en su posición correcta:


Ahora todas las caras laterales deben tener el color de su celda central del mismo color que la celda que hay por encima, por supuesto respetando la cruz de color amarillo:


En el siguiente paso debes situar las fichas de las 4 esquinas que todavía faltan por completar en su posicion, aunque sus colores no esten bien encarados:


Por útimo solo queda encarar con sus colores las fichas que todavia no lo esten. Y por fin, el cubo queda resuelto:


¡Objetivo cumplido!

Los algoritmos necesarios para conseguir la secuencia descrita no los he incluido aqui porque es bastante mas complicado de explicar que de entender. Hay multitud de manuales en Internet y por supuesto, podeis preguntarme aqui si teneis cualquier duda.

Ha sido muy divertido aprender a resolverlo y me lo he pasado muy bien. Pero en realidad no es trivial, y desde luego no es un juguete pensado para un niño de 8 años que no reciba ninguna ayuda para resolverlo. El cubo 3x3 tiene 43 trillones de posiciones y sin una guia que te explique los pasos es prácticamente impensable que alguien pueda resolverlo por su cuenta.

No obstante, en este mundo hay gente para todo, y el estadounidense Shotaro Makisumi ostenta el record mundial de velocidad en 12,11 segundos, y a ciegas en 3 minutos y 37 segundos. Desde luego que no voy a ser yo quien se lo quite...

domingo, 14 de diciembre de 2008

Barcelona - Valencia

La semana pasada tuve una agradable visita en Barcelona. Aprovechando el puente de la Inmaculada, vinieron a visitarme desde Castellón mi hermano David y mi mejor amigo Xavi. Para aprovechar el viaje al máximo, decidimos comprar entradas para ver el partido de la jornada "Barcelona - Valencia".

Para Xavi era el primer partido en un campo de primera división al que asistía en directo, ni mas ni menos que su querido Barcelona en el Camp Nou y contra todo un Valencia con Villa maravilla y compañía... Sin duda, ¡un partidazo! Mi hermano David y yo, merengues confesos, nunca habíamos estado en el Camp Nou, asi que era el dia perfecto para conocer al campo de nuestro eterno ribal.Dos horas antes del partido decidimos infiltramos en la plaza en frente del bar "La Jarra" con los seguidores cules para disfrutar del ambiente y vivir mas de cerca el partido. Entre canticos a favor del Barcelona, y algunos gritos poniendo en duda la sexualidad de Gutti (poco importaba que el ribal fuera el Valencia), tuvimos que pasar desapercibidos mientras Xavi se dejaba sus cuerdas vocales gritando en favor de los suyos.

Sabedores de lo arriesgado de la situación, no era ni el momento ni el lugar apropiado para posicionarnos en favor del Real Madrid, asi que decidimos unimos a la fiesta cantando el himno del Barça como dos seguidores mas ¡Tooot el camp...! Si, soy un vendido, pero amigos seguidores del Real Madrid, era cuestion de supervivencia, ¡que Dios me perdone! :-)
Media hora antes del partido entramos en el estadio. Aunque sea el eterno ribal, reconozco que el estadio me impresionó y durante unos minutos me quedé hipnotizado admirando todos sus detalles. Un cesped verde en perfectas condiciones, el video marcador gigante, los paneles publicitarios perfectamente sincronizados, la prensa haciendo su trabajo, el palco, los aficionados que poco a poco iban tomando sus asientos y como no, los jugadores de ambos equipos que ya habían iniciado el calentamiento en el terreno de juego.
El arbitro dió comienzo al partido y una enorme cantidad de flashes de fotos iluminaron las gradas por unos instantes formando un campo lleno de estrellas de luz donde en el terreno de juego empezaban a brillar con luz propia las verdaderas estrellas del partido (Xavi, Messi, Henri y compañia...)

El partido fué azulgrana de principio a fin. La gente se lo pasó en grande, celebrando cada gol con toda su energía. Los culé obtuvieron la recompensa que se merecían por la entrega de sus aficionados que no pararon de animarles en todo el partido. Al final, Barcelona 4 - 0 Valencia.
Una gran victoria del equipo catalán que mi amigo Xavi disfrutó mas que nunca, y que mi hermano David y yo, sin llegar a su eufória pero con aplausos de dos madrilistas en el Camp Nou reconociendo al Barça como justo vencedor.

sábado, 13 de diciembre de 2008

The IT Crowd. Tercera parte

Los que ya conocíais la serie, estais de enhorabuena, pues ya estan disponibles los capitulos de la tercera temporada de la serie de televisión "The IT Crowd".

Los que no la conocíais, os la recomiendo personalmente. Es una serie muy divertida que narra las aventuras y desventuras de dos informáticos de un servicio técnico y su convivencia con el resto de los compañeros de su trabajo.

A mi me hicieron reir mucho en las dos primeras temporadas y despues de tanto tiempo sin saber nada de ellos ya les echaba de menos. Y es que terminas por cogerles cariño. Esperemos que la tercera temporada esté a la altura.

Visitas:

Seguidores