30 mar 2009

Analizando y aplicando diferencias con vimdiff

Pues resulta que se puede usar una extensión de Vim para analizar diferencias y aplicarlas entre varios archivos, usando una el comando:

vimdiff archivo1 archivo2

Para movernos por las diferencias, usaremos ]c y [c para ir a la siguiente y anterior diferencia.
Para aplicar las diferencias en uno u otro sentido usaremos

do obtiene la diferencia desde el otro archivo
dp aplica la diferencia sobre el otro archivo

También es posible realizar operaciones sobre un rango de líneas. Para mayor detalle, consultar
http://www.vim.org/htmldoc/diff.html

3 mar 2009

Instalación de Xenomai

Los ingredientes para este maravilloso cocktail de frutas son:

  • Fuentes del kernel a utilizar (Linux kernel)
  • Parche ADEOS para la arquitectura y versión del kernel que vamos a usar (adeos patches).
  • Fuentes de xenomai (xenomai sources).
  • Herramientas de desarrollo habituales para la compilación del kernel (gcc, make, etc...) o toolchain para la arquitectura a utilizar, en caso de que vayamos a hacer una compilación cruzada.
Con las manos en la masa
En primer lugar hay que aplicar el parche ADEOS sobre el kernel a utilizar (si es necesario aplicar otros parches al kernel, el de ADEOS es preferible que sea el último), para lo cual haremos

patch -p1 < ruta_al_parche/parche_adeos.patch

Desde el directorio principal del kernel.

Una vez hecho esto, entramos en la configuración del kernel (según prefiramos con menuconfig, xconfig, ...) y configuramos el mismo a nuestro gusto. Podemos ver como aparecen nuevas opciones en Real-Time sub-system así como en otros lugares y que son los puntos de configuración de ADEOS/Xenomai. Para una descripción detallada de la instalación y configuración visitar www.xenomai.org.

Hay que decir que en los fuentes de Xenomai existe un directorio ksrc donde podemos encontrar los parches mas comunes de ADEOS.

En segundo lugar descomprimimos los fuentes de Xenomai, y ejecutamos

scripts/prepare-kernel.sh --linux=path_to_linux_kernel_directory --adeos=parche_a_usar --arch=arquitectura

Si ya hemos aplicado el parche a mano, no es necesario poner la opción --adeos, y si lo hacemos tampoco pasa nada porque el script se dará cuenta de que ya está parcheado.

Una vez hecho esto, pasamos a configurar las fuentes de Xenomai para su compilación. Existen diversas opciones para ello, en función de la arquitectura que usemos, y de donde queramos instalar el resultado. Consultar el README que acompaña a las fuentes para determinar las opciones necesarias. Como ejemplo la compilación para un sistema integratorCP ARM.

./configure --host=arm-926ejs-linux --enable-arm-mach=integrator --enable-arm-arch=4
make DESTDIR=directorio_destino_instalacion install


Con esto y la imagen del kernel, ya tendríamos Xenomai listo para instalarlo, en función de si se trata de un PC o de un sistema empotrado, los siguientes pasos variaran para hacer que el sistema arranque nuestro nuevo kernel.

Tiempo Real Estricto con GNU/Linux y Xenomai

Xenomai es una solución utilizada para dotar al kernel de Linux de soporte para tiempo real estricto (hard real time), ya que éste no es capaz de proporcionar, por si solo, las capacidades necesarias para garantizar restricciones temporales estrictas (lo que no implica alta velocidad).
Según la definición que se hace en su propia pagina web, Xenomai es "un entorno de desarrollo en tiempo real que coopera con el núcleo Linux para proporcionar un respaldo omnipresente, independiente de la interfaz y muy cercano al tiempo real a aplicaciones de espacio de usuario, integrado completamente en el entorno GNU/Linux. Xenomai proporciona su propia API y capas de emulación («pieles» o «skins») para poder migrar desde otros RTOS más fácilmente. Ejemplos de estos son: pSOS+, VxWorks, VRTX, uiTRON, RTAI, POSIX."
Personalmente, lo de "omnipresente" me parece una mala traducción del termino anglosajón "pervasive" cuya traducción es también dominante o penetrante, aunque ninguna de ellas expresa correctamente el concepto.

De una forma mas llana, podemos decir que Xenomai proporciona estructuras de datos, funciones y tipos de datos que nos permiten desarrollar aplicaciones con restricciones de tiempo real estricto, que se integran perfectamente con un entorno GNU/Linux, y que además proporciona varias interfaces que hace más sencilla la adaptación de aplicaciones ya desarrolladas en otros sistemas operativos de tiempo real.

La instalación de Xenomai consta de dos partes:
  1. Parche para el kernel de Linux.
  2. Soporte y aplicaciones de espacio de usuario.
El parche para el kernel se trata de ADEOS (Adaptative Domain Enviroment for Operating Systems) que comparte las interrupciones y eventos generados por el sistema, de forma que colabora con el kernel para ofrecer las capacidades de tiempo real. De ésta forma, los servicios normales de Linux son considerados tareas de baja prioridad respecto a las tareas con restricciones de tiempo real, y éstas últimas no adolecen de latencias no deseadas.

En próximas entradas nos adentraremos en la instalación y uso de Xenomai.

2 mar 2009

Depuración con Core dumps

Un core dump es un archivo que contiene una imagen de la memoria de un proceso en el momento en el que sufrió un fallo (Segmentation fault) o se le envió una señal que produce su generación (señales cuyo Action es igual a Core).
Estos archivos son realmente útiles a la hora de depurar un programa, ya que nos ofrecen información de como se encontraba el mismo en el momento del fallo. Para utilizarlos, en primer lugar es necesario que el sistema tenga habilitada su generación, para lo cual usaremos el comando:

ulimit -c tamaño_maximo_en_bytes

Realmente con esto lo que hacemos es no poner límite al tamaño de los cores que se generen.
El comando ulimit permite variar otras cosas, como el número máximo de archivos abiertos por usuario/grupo.

Por defecto, el kernel nos generará el core dump con el nombre core, pero esto se puede modificar de forma permanente o solo mientras este el sistema arrancado.

No permanente
Modificamos el valor del archivo /proc/sys/kernel/core_pattern, donde podemos utilizar expresiones especiales que se expanden en ciertos valores útiles:

  • %% a single % character
  • %p PID of dumped process
  • %u (numeric) real UID of dumped process
  • %g (numeric) real GID of dumped process
  • %s number of signal causing dump
  • %t time of dump, expressed as seconds since the Epoch (00:00h, 1 Jan 1970, UTC)
  • %h hostname (same as nodename returned by uname(2))
  • %e executable filename (without path prefix)
  • %c core file size soft resource limit of crashing process (since Linux 2.6.24)
Así podemos poner por ejemplo que los cores se ubiquen en un directorio, y se generen con el PID del proceso correspondiente, la hora en que se ha producido, la señal que provoco el dump, el nombre del programa, etc...

Ejemplo:

echo "core.%p-%t" > /proc/sys/kernel/core_pattern


Además, es posible enviar el dump a la entrada de otro programa a través de una tubería (pipe) utilizando argumentos para el programa, entre los que pueden estar variables como las que hemos visto antes.

Ejemplo:

echo "|nombre_programa argumento1 argumento2 %p %e"

(Los argumentos 3 y 4 serán el PID y el nombre del ejecutable causante del dump)

Permanente
Para hacer los cambios de manera permanente, deberemos editar el archivo /etc/syslog.conf, y añadir en él una línea como:

kernel.core_pattern = patron_para_los cores

Donde el patrón se escribe de la misma forma que hemos visto anteriormente.

Este archivo permite configurar los valores de todos los archivos en /proc/sys, lo cual puede ser útil para otras muchas cosas además de los cores.

Para una información mas detallada y precisa consultar man core y man 5 sysctl.conf.

Por último, es posible generar core dumps de programas en ejecución con la orden gcore (ver man gcore).