Introducción
Los sistemas en tiempo real son aquellos que deben cumplir con restricciones temporales estrictas. En estos sistemas, la corrección del sistema no solo depende de los resultados lógicos de las operaciones, sino también del tiempo en que estos resultados son producidos. Ada es un lenguaje de programación que ofrece características robustas para el desarrollo de sistemas en tiempo real, gracias a su soporte para concurrencia, sincronización y manejo de tiempo.
Objetivos
- Comprender los conceptos básicos de los sistemas en tiempo real.
- Aprender a utilizar las características de Ada para desarrollar aplicaciones en tiempo real.
- Implementar tareas y mecanismos de sincronización en Ada.
- Manejar temporizadores y eventos temporales.
Conceptos Clave
- Sistemas en Tiempo Real: Sistemas que deben responder a eventos dentro de un tiempo predefinido.
- Tareas: Unidades de ejecución concurrente en Ada.
- Objetos Protegidos: Mecanismos para la sincronización y comunicación entre tareas.
- Temporizadores: Herramientas para medir y controlar el tiempo en aplicaciones en tiempo real.
Tareas en Tiempo Real
En Ada, las tareas son la base de la programación concurrente y en tiempo real. Una tarea en Ada se define de la siguiente manera:
task type Real_Time_Task is entry Start; end Real_Time_Task; task body Real_Time_Task is begin accept Start; -- Código de la tarea end Real_Time_Task;
Ejemplo Práctico
Vamos a crear una tarea que se ejecuta periódicamente cada segundo.
with Ada.Real_Time; use Ada.Real_Time; with Ada.Text_IO; use Ada.Text_IO; procedure Periodic_Task is task type Task_Type is entry Start; end Task_Type; task body Task_Type is Next_Time : Time := Clock; begin accept Start; loop Put_Line("Task executed at " & Time'Image(Clock)); Next_Time := Next_Time + Milliseconds(1000); delay until Next_Time; end loop; end Task_Type; T : Task_Type; begin T.Start; end Periodic_Task;
Explicación del Código
- Importación de Paquetes:
Ada.Real_Time
para manejar el tiempo yAda.Text_IO
para la salida de texto. - Definición de la Tarea:
Task_Type
con una entradaStart
. - Cuerpo de la Tarea:
Next_Time
se inicializa con el tiempo actual.- La tarea acepta la entrada
Start
y entra en un bucle infinito. - En cada iteración, imprime la hora actual y espera hasta el próximo segundo usando
delay until
.
Sincronización y Comunicación
Para sincronizar tareas y permitir la comunicación entre ellas, Ada proporciona objetos protegidos.
Ejemplo de Objeto Protegido
protected type Shared_Data is procedure Write(Value : Integer); function Read return Integer; private Data : Integer := 0; end Shared_Data; protected body Shared_Data is procedure Write(Value : Integer) is begin Data := Value; end Write; function Read return Integer is begin return Data; end Read; end Shared_Data;
Explicación del Código
- Definición del Objeto Protegido:
Shared_Data
con un procedimientoWrite
y una funciónRead
. - Cuerpo del Objeto Protegido:
Write
actualiza el valor deData
.Read
devuelve el valor deData
.
Temporizadores y Eventos Temporales
Ada proporciona mecanismos para manejar temporizadores y eventos temporales, esenciales en sistemas en tiempo real.
Ejemplo de Temporizador
with Ada.Real_Time; use Ada.Real_Time; with Ada.Text_IO; use Ada.Text_IO; procedure Timer_Example is Next_Time : Time := Clock; begin loop Next_Time := Next_Time + Milliseconds(500); delay until Next_Time; Put_Line("Half a second passed at " & Time'Image(Clock)); end loop; end Timer_Example;
Explicación del Código
- Inicialización del Temporizador:
Next_Time
se establece con el tiempo actual. - Bucle Infinito:
Next_Time
se incrementa en 500 milisegundos.- La ejecución se retrasa hasta
Next_Time
. - Se imprime un mensaje indicando que ha pasado medio segundo.
Ejercicio Práctico
Ejercicio
Crea un programa en Ada que tenga dos tareas. La primera tarea debe imprimir un mensaje cada segundo, y la segunda tarea debe imprimir un mensaje cada dos segundos. Usa objetos protegidos para sincronizar el acceso a una variable compartida que cuenta el número de mensajes impresos.
Solución
with Ada.Real_Time; use Ada.Real_Time; with Ada.Text_IO; use Ada.Text_IO; procedure Dual_Task is protected type Counter is procedure Increment; function Get_Value return Integer; private Count : Integer := 0; end Counter; protected body Counter is procedure Increment is begin Count := Count + 1; end Increment; function Get_Value return Integer is begin return Count; end Get_Value; end Counter; Shared_Counter : Counter; task type Task_One is entry Start; end Task_One; task body Task_One is Next_Time : Time := Clock; begin accept Start; loop Next_Time := Next_Time + Milliseconds(1000); delay until Next_Time; Shared_Counter.Increment; Put_Line("Task One executed at " & Time'Image(Clock) & " Count: " & Integer'Image(Shared_Counter.Get_Value)); end loop; end Task_One; task type Task_Two is entry Start; end Task_Two; task body Task_Two is Next_Time : Time := Clock; begin accept Start; loop Next_Time := Next_Time + Milliseconds(2000); delay until Next_Time; Shared_Counter.Increment; Put_Line("Task Two executed at " & Time'Image(Clock) & " Count: " & Integer'Image(Shared_Counter.Get_Value)); end loop; end Task_Two; T1 : Task_One; T2 : Task_Two; begin T1.Start; T2.Start; end Dual_Task;
Explicación del Código
- Definición del Objeto Protegido:
Counter
con un procedimientoIncrement
y una funciónGet_Value
. - Cuerpo del Objeto Protegido:
Increment
incrementa el contador.Get_Value
devuelve el valor del contador.
- Definición de las Tareas:
Task_One
yTask_Two
con una entradaStart
. - Cuerpo de las Tareas:
- Ambas tareas aceptan la entrada
Start
y entran en un bucle infinito. Task_One
se ejecuta cada segundo yTask_Two
cada dos segundos.- Ambas tareas incrementan el contador compartido y imprimen el valor actual del contador.
- Ambas tareas aceptan la entrada
Conclusión
En esta sección, hemos explorado cómo Ada puede ser utilizada para desarrollar sistemas en tiempo real. Hemos aprendido a definir y manejar tareas, utilizar objetos protegidos para la sincronización y manejar temporizadores. Estos conceptos son fundamentales para construir aplicaciones robustas y eficientes en tiempo real. En la siguiente sección, profundizaremos en la sincronización y comunicación entre tareas en Ada.
Curso de Programación en Ada
Módulo 1: Introducción a Ada
Módulo 2: Conceptos Básicos
- Variables y Tipos de Datos
- Operadores y Expresiones
- Estructuras de Control
- Bucles en Ada
- Subprogramas: Procedimientos y Funciones
Módulo 3: Tipos de Datos Avanzados
Módulo 4: Programación Modular
Módulo 5: Concurrencia y Programación en Tiempo Real
Módulo 6: Temas Avanzados
Módulo 7: Mejores Prácticas y Optimización
- Estilo de Código y Mejores Prácticas
- Depuración y Pruebas
- Optimización del Rendimiento
- Consideraciones de Seguridad