Introducción a los conceptos básicos de Tiempo-Real (TR). Tiempo real estricto con RT-Linux.
¿Qué es Tiempo-Real?Antes de presentar RT-Linux es necesario aclarar algunas ideas sobre qué es Tiempo Real. Diremos que:
"Un sistema de tiempo real es aquel sistema informático en el que la corrección del sistema no sólo depende de los resultados lógicos de los algoritmos, sino que también depende del momento en el que estos se producen."
No es suficiente que los resultado obtenidos sean correctos, sino que tienen que tienen que obtenerse dentro de un intervalo de tiempo especificado. Observa que de esta definición no se deduce que un sistema de tiempo real tenga se ser necesariamente rápido, como quizás se pudiera pensar. Por ejemplo: el sistema de guiado de un barco pude parecer en principio que no es de tiempo real, pues la velocidad del barco es relativamente baja y normalmente se dispone de "bastante" tiempo (del orden de algunos minutos) para tomar las decisiones de control. Pero sí que es un sistema de TR según la definición anterior.
Observa que lo que he definido es un sistema "de tiempo-real" y no un sistema "en tiempo-real". Un sistema "en tiempo-real" es lo que normalmente se entiende por un sistema rápido, capaz de dar la impresión de "realidad". Típicamente todas las simulaciones y juegos interactivos quieren dan la impresión de continuidad en el tiempo y cuantas más imágenes generen mejor.
Vamos a ver con un poco más de detalle qué se entiende por "restricción temporal". Supon que queremos controlar la velocidad de un motor que está sometido a una carga variable, supongamos también que ese control lo queremos realizar utilizando un control PID (Proporcional, Integral, Derivativo). El control PID desde nuestro punto de vista es una función a la que se le pasan unos parámetros --en este ejemplo, la velocidad actual del motor-- y retorna el valor de la señal de control que hay que aplicar al motor --la tensión con la que hay que alimentar el motor. La teoría, que por cierto es mucha, que hay detrás del diseño de los algoritmos PID supone que el tiempo de cómputo es despreciable, esto es, desde que se lee la velocidad del motor hasta que se actúa pasa muy poco tiempo. Normalmente se puede tolerar un cierto retraso. Otra característica de este tipo de control es que se debe realizar de forma periódica, esto es, el algoritmo PID se tiene que ejecutar regularmente. Si entre dos invocaciones consecutivas a la función PID pasa demasiado tiempo, entonces el motor puede alcanzar una velocidad no deseada. En resumen: podemos considerar la función PID como un programa que se ha de ejecutar de forma periódica (Pi); desde que la ponemos en ejecución hasta que acaba ha de estar acotado por lo máximo que viene impuesto por la teoría de diseño del PID (Di) y que en función de la velocidad del procesador que tengamos el tiempo de ejecución del propio código PID emplea una cantidad de tiempo (Ci).
Pi: Periodo de la tarea i.
Di: Plazo de ejecución (deadline) de la tarea i.
Ci: Tiempo de computo en el peor de los casos de la tarea i. Si el sistema está compuesto por una sola tarea, entonces no hay problema de tiempo real: o el procesador puede hacer el trabajo en el tiempo requerido, o no. En caso de ser lo suficientemente rápido el procesador, entonces simplemente se cambia de procesador.
Los problemas de TR aparecen cuando el sistema está compuesto por varias tareas, y hay que repartir el procesador (o procesadores) entre todas ellas. Para ello no podemos utilizar un sistema clásico de tiempo compartido como puede ser el utilizado por Linux con los procesos normales. No en necesario decir que ni se te ocurra hacer programas que requieran tiempo real en Windows... Un consejo aún mejor: no hagas ningún programa bajo ese producto.
No todos los sistema de tiempo real son iguales, no es lo mismo controlar el sistema de frenado ABS de un coche o la inyección de combustible en el motor de un avión, que la descompresión y visualización de un fichero mpeg. En el primer caso, la perdida de algún plazo de ejecución puede producir perdidas humanas o graves perdidas materiales; en el segundo caso, sencillamente se tiene una degradación de la calidad del sistema (la imagen se queda congelada o se pierde algún fotograma). A los primeros se les llama sistemas de tiempo real estricto (hard real-time) y a los segundo sistemas de tiempo real blando (soft real-time). Nos centraremos en el estudio de los sistemas de tiempo real estricto.
El diseño de un sistema de tiempo real pasa por varias fases. Primero se identifican las tareas a realizar y las restricciones temporales que deben cumplir; luego se escriben los programas que ejecutarán las tareas; después se mide el tiempo de cómputo de cada tarea y se realiza un análisis de planificabilidad. El análisis de planificabilidad consiste en aplicar unas pruebas al conjunto de tareas de tal forma que si éstas pasan el test entonces se puede garantizar que ninguna tarea perderá su plazo de ejecución. Si no pasan el test entonces se tiene que volver al principio y empezar de nuevo, utilizando otro procesador más potente o utilizando otros algoritmos para implementar las tareas.
Resumiendo: Las tareas se modelan con tres números: P, D y C. El objetivo del sistema es garantizar que todas las tareas (en todas sus activaciones) cumplan sus plazos de ejecución. La forma de conseguirlo es teniendo un sistema predecible. Decir que un sistema es de tiempo real o que es un sistema es predecible es decir casi lo mismo.
¿Qué tiene que ver el Sistema Operativo con el Tiempo-Real?La corrección semántica de la respuesta es responsabilidad del programador, y la corrección temporal depende del sistema operativo (S.O.).
Es el S.O. el que tiene que dar soporte y organizar la ejecución de todas las tareas, es también labor del S.O. el gestionar las interrupciones. El S.O. ha de ofrecer:
- El algoritmo de planificación.
- Los mecanismos de comunicación entre tareas (semáforos, mensajes,etc).
- Gestionar las interrupciones.
- Activar las tareas en cada uno de sus periodos.
Al contrario que sucede en los S.O. "normales", el objetivo en los S.O. de tiempo real es minimizar la complejidad para minimizar la inceridumbre (falta de predecibilidad). No se quiere un S.O. que haga muchas cosas, sino uno lo haga de forma predecible y rápida. Es preferible un S.O. que normalmente tarde 10 unidades de tiempo (u.t.) en realizar un cambio de contexto y que en el peor de los casos tarde 12, que otro S.O. que por término medito tarde 3 u.t. pero que de cuando en cuando necesite 20 u.t.
No hay que sorprenderse si descubrimos que los sistemas operativos de tiempo real son más "lentos" que los S.O. normales. En ocasiones, para obtener un comportamiento predecible, se puede llegar incluso a deshabilitar la memoria cache, con la consiguiente perdida de velocidad. La memoria cache, los procesadores con unidades pipeline y los algoritmos de predicción de saltos son claros enemigos de la predecibilidad y por tanto de los sistemas de tiempo real.
Extensiones POSIX de TR.
POSIX son la iniciales de Portable Operating System Interface (Y ¿qué es un S.O. sin la X al final?). Es un estándar que pretende conseguir la portabilidad del software al nivel del código fuente. En otras palabras: un programa escrito para un S.O. que sea compatible con POSIX ha de poderse compilar y ejecutar sobre cualquier otro "POSIX" aunque sea de otro fabricante distinto. El estándar POSIX define la interfaz que el S.O. debe ofrecer a las aplicaciones: el juego de llamadas al sistema. POSIX está siendo desarrollado por IEEE (Institute of Electrical and Electronic Engineering) y estandarizado por ANSI (American National Standards Institute) e ISO (International Standards Organization). Evidentemente POSIX está basado en UNIX. La mayor parte de los S.O. (incluido el Windows NT) tienden en sucesivas versiones hacia la compatibilidad POSIX.
El trabajo en la definición del estándar POSIX está dividida en varios grupos de trabajo en los que participan fabricantes de ordenadores, empresas de software, representantes de distintos gobiernos y gurús de la informática. Cada grupo se encarga de diseñar un aspecto del S.O.. Por ejemplo: el grupo llamado POSIX.4 se encarga de las cuestiones relativas a tiempo real.
Las extensiones POSIX.4 --renombradas como 1003.1b desde 1993-- permiten que un S.O. se pueda utilizar en situaciones que requieran tiempo real. Evidentemente, la mayor parte de estas extensiones están relacionadas con la gestión del tiempo y las prioridades de los procesos, también hay llamadas al sistema para facilitar la comunicación entre procesos.
Las extensiones POSIX están pensadas para tener un mayor control sobre la administración de los recursos del S.O..
Linux 2.0 tienen implementadas bastantes llamadas al sistema de las extensiones POSIX de tiempo real... pero este aspecto de Linux lo contaré en otro artículo. En la versión 2.2, casi con toda seguridad, Linux será 100% compatible POSIX 1003.1b.
Real Time Linux
Ha sido desarrollado en el departamento de informática en el Instituto de Minería y Tecnología de Nuevo México, por Victor Yodaiken y Michael Barabanov. RT-Linux fue el trabajo de Michael para completar su Master of Computer Science in Computer Science (algo así como el proyecto fin de carrera). La última versión disponible es la 0.6. Por ahora sólo está disponible para la arquitectura Intel.
RT-Linux resuelve el problema de una forma radicalmente distinta. En lugar de modificar el núcleo de Linux para ofrecer nuevas llamadas al sistema y que sea predecible, lo que hace es construir directamente sobre el procesador (i386) un pequeño núcleo --que no tiene nada que ver con el núcleo de Linux-- con un planificador. Sobre este núcleo el S.O. Linux se ejecuta como una tarea más. Linux se ejecuta compartiendo el procesador con otras tareas. Más concretamente: Linux se ejecuta en background, cuando no hay otras tareas que ejecutar.
Me imagino que se te han roto todos los esquemas... quizás pensabas que el S.O. era todo poderoso y que no se podía jugar con él.
Aún te parecerá más sorprendente el hecho de poder instalar y desinstalar el planificador de tiempo real dinámicamente, pues está compilado como un módulo.
El código del kernel de Linux (como cualquier S.O.) suele deshabilitar las interrupciones como medio de sincronización o para implementar secciones críticas. Si mientras Linux tiene deshabilitadas las interrupciones se produce una interrupción de reloj, ésta quedará bloqueada; con la consiguiente perdida de precisión temporal. En RT-Linux se ha implementado una solución muy elegante: se ha sustituido todas las llamadas a cli, sti e iret (instrucciones ensamblador que modifican el estado de las interrupciones) por S_CLI, S_STI y S_IRET que las emulan, de forma que Linux no puede nunca deshabilitar las interrupciones.
El planificador por defecto que viene con RT-Linux es un planificador basado en prioridades estáticas y trata a la tarea Linux como la tarea de menor prioridad. Si las tareas de tiempo real consumen todo el tiempo del procesador, entonces la tarea Linux no recibe tiempo de procesador y da la impresión de que el sistema se ha"colgado".
Con RT-Linux tenemos a la vez un sistema de tiempo real y un S.O. clásico. Podemos navegar por la red a la vez que estamos muestreando y controlando un proceso físico.
Instalación de RT-Linux
Los ficheros de la distribución los podemos encontrar en: http://luz.cs.nt.edu/~rtlinux.
Para "transformar" a Linux en RT-Linux hay que aplicar al código del kernel un parche que viene con la distribución de RT-Linux y luego recompilar el kernel. Aquí está la receta para hacerlo. Supongo que has bajado el fichero rtlinux-0.6-2.0.33.tgz al directorio /usr/src y lo has extraído en ese mismo directorio, con lo que ahora los fuentes están en /usr/src/rtlinux-0.6. También supongo que ya has configurado todas las opciones del kernel (make config).
# cd /usr/src/linux
# patch -p1 <../rtlinux-0.6-2.0.33/kernel_path
# make dep; make clean; make zlilo; make modules; make modules_install
# reboot
El nuevo núcleo es, en apariencia, igual que uno normal, pero está preparado para convertirse en un sistema de tiempo real. Dentro del directorio /usr/src/rtlinux-0.6-2.0.33/testing hay varios programas de demostración.
Aparte del ejemplo de sonido que viene con la distribución (dentro del directorio testing), se puede bajar otro ejemplo preparado por Oleg Subbotin que permite crear un cronograma de la ejecución de las tareas. Uno de los ficheros que viene en esta demo es un planificador con las modificaciones necesarias para que a la vez que realiza la planificación, envíe información sobre las decisiones que va tomando. Esta información es recogida y almacenada en un fichero que posteriormente puede ser visualizada gráficamente. Como resultado podemos ver en qué orden se han ejecutado las distintas tareas, y como la tarea más prioritaria expulsa a la menos prioritaria. La tarea Linux no parece representada.
Cada tarea está representada sobre un eje horizontal. Los rectángulos representan tiempos en los que cada tarea está utilizando el procesador (en un instante dado, sólo una tarea puede estar en ejecución, pues estamos en un sistema monoprocesador). En este ejemplo, el deadline de cada tarea es igual a su periodo; el periodo de cada tarea está enmarcado por un intervalo temporal representado por: ,dentro del cual debe ejecutarse. Las tareas de arriba tienen mayor prioridad y son capaces de expulsar del procesador a otras de menos prioridad, como ocurre en el instante 600.
El Futuro de RT-Linux
Ya está disponible una versión de RT-Linux para multiprocesador. Los servicios que ofrece RT-Linux son intencionadamente mínimos, no se quiere incluir ninguna funcionalidad que no sea estrictamente necesaria con el fin de mantener al sistema lo más predecible posible. De todas formas, hay disponibles varias ampliaciones para trabajar con semáforos y para poder acceder a las tareas de tiempo real desde los procesos Linux mediante /proc/sys.
Hace pocas semanas, se ha comenzado ha escribir un completo manual-tutorial de RT-Linux.
Conclusiones
Antes de aparecer el RT-Linux la mayor parte de los ingenieros que necesitaban trabajar con sistemas de tiempo real tenían que o bien utilizar el MS-DOS y tener que construirse todos los drivers que necesitaban, o bien comprar un S.O. de tiempo real (a unos precios poco atractivos). Ahora se dispone de todo un completo S.O. para desarrollar las aplicaciones de tiempo real y sobre el mismo sistema que se van a ejecutar. De hecho, podemos tener simultáneamente varias tareas de tiempo real en ejecución y estar navegando por la Internet sin problemas.
En el siguiente artículo veremos varios ejemplos de aplicaciones de tiempo real y cómo escribir nuestras propias aplicaciones de tiempo real.
Artículo original en Castellano
|