¿Qué es un RTOS?

Un RTOS es un sistema operativo en tiempo real para sistemas embebidos.

Pero, ¿ésto qué quiere decir?

Empecemos por partes:

  • Sistema operativo: es un programa que gestiona el hardware de un dispositivo y permite que subprogramas se ejecuten mediante los servicios que provee. Vamos, que lo que hace es simplificar el desarrollo de aplicaciones específicas, ya que gestiona toda la parte de control del hardware y no hay necesidad de programar en bajo nivel.
  • Tiempo real: los sistemas en tiempo real son capaces de gobernar varios periféricos en un determinado tiempo. Por ejemplo, en una fábrica un objeto pasa cada X segundos por un punto, ahí se pone una etiqueta. El sistema debe ser capaz de terminar su programa y volver a ejecutarlo en X segundos, sino la etiqueta estaría mal puesta.
  • Sistemas embebidos: realmente es un anglicismo de embedded systems, también se llaman sistemas empotrados. Son sistemas diseñados para realizar unas tareas concretas, en el ejemplo de antes el robot que pone la etiqueta.

¿Porqué usar un RTOS?

La ventaja de los RTOS frente a los métodos de programación tradicionales, reside en la simplificación de la gestión de las tareas.

Una tarea o proceso es un subprograma, que se ejecuta en paralelo con el programa principal, que se encarga de controlar algún periférico del sistema o realizar operaciones secundarias, se ejecutan en el background. Por ejemplo, un sistema que necesita un conversor analógico digital, la tarea sería la lectura del ADC cuando éste haya terminado.

El tiempo que tarda en ejecutarse una tarea se llama trabajo.

En un programa hay que distinguir el bucle principal o scan de las tareas, es el programa que se ejecuta en el foreground. En el scan se ejecuta el programa por estados, por ejemplo en el robot: el robot coge etiqueta, se posiciona y cuando pasa el objeto pone la etiqueta.

Las tareas de este ejemplo serían comprobar los sensores para saber que el robot se ha posicionado correctamente, que tiene etiqueta...

En los sistemas tradicionales, esto se controlaba gracias a las interrupciones. La desventaja que tiene es que una interrupción podía tardar mucho tiempo en realizarse demorando el resto del programa y produciendo un error.

Ésta desventaja se solucionaba dividiendo las tareas largas en dos o cambiando el hardware y usando uno más rápido.

Gracias a los RTOS, introducimos el planificador, que es un componente que se encarga de gestionar las prioridades de las interrupciones, los tiempos que tardan...

Hay dos tipos de planificadores:

  • Cooperativo: se encarga de llamar a las tareas con más prioridad y, cuando ésta termina o tarda mucho, llama a la siguiente. El problema que tiene es que el programador tiene que llamar al planificador cuando él crea oportuno.
  • Expropiativo: cada cierto tiempo se llama automáticamente al planificador, ejecutando la tarea que éste crea más oportuna. El problema que tiene es que si dos tareas acceden al mismo dispositivo se van a producir errores ya que no se sabe cuál es la que se va a ejecutar.

Para evitar estos errores, se introducen los semáforos. Con ellos se comprueban las prioridades y el uso de los periféricos, evitando que varias tareas controlen un dispositivo "a la vez".

Semáforos

El funcionamiento de los semáforos es similar al de los que controlan los trenes, si un tren está en un tramo de vía el semáforo está en rojo para el siguiente tren. En cuanto el primero deja el tramo libre el semáforo se pone en verde, permitiendo el paso al segundo tren.

En los RTOS lo que hace es gestionar los recursos compartidos, así si dos interrupciones quieren acceder a una misma variable o bus, hasta que no acaba la primera no puede ejecutarse la segunda. Independientemente de la prioridad de la interrupción.

Se pueden usar múltiples semáforos ya que cada uno se encarga de un recurso compartido. Pero hay que recordar que el RTOS no comprueba que estás accediendo al semáforo correcto.

Otro uso de los semáforos, es la sincronización de tareas; mediante un semáforo podemos permitir ejecutar una tarea si otra anterior (o una interrupción) ha terminado.

Así, por ejemplo podemos leer un RTC (real time clock) e imprimirlo en pantalla, pero sólo se imprimirá si ha terminado de leer el RTC.

Problemas con los semáforos

Como es el programador el encargado de la gestión y control de los semáforos, se pueden producir ciertos problemas, los más comunes:

  • Olvidar activar el semáforo
  • Activar un semáforo equivocado
  • Desactivar el semáforo
  • Activar un semáforo durante mucho tiempo (aumenta la latencia)
  • Inversión de prioridad. Si una interrupción menos prioritaria accede a un semáforo, por mucho que intente acceder a ese recurso otra interrupción más prioritaria, no podrá.

Al ocurrir esto, el sistema se bloquea, ya que hasta que no termine la interrupción más prioritaria no se ejecutará la menos prioritaria, pero ésta tiene bloqueado el recurso necesario para ejecutarse la más prioritaria.

Algunos RTOS solucionan este problema haciendo que la menos prioritaria herede la prioridad de la otra (momentáneamente). A los semáforos que tienen esta opción se les llama mutexes.

  • Abrazo mortal. Ocurre cuando una tarea activa varios semáforos (por ejemplo el A y el B) y, cuando se está ejecutando, se activa otra tarea (justo en el momento que se ha activado A y no B) que activa los mismo semáforos pero en distinto orden (B y A), como el semáforo A no se puede utilizar vuelve a la primera tarea, pero ésta no se puede ejecutar por que el semáforo B está ocupado.

Para evitar esto o bien se activan todos los semáforos en el mismo orden o se utilizan los semáforos con Timeout así, transcurrido un tiempo, el semáforo se libera se haya o no ejecutado la tarea.

Colas

 Sirven para comunicar tareas entre ellas. Se suelen usar para:

  • Cuando se necesita un almacenamiento temporal para datos
  • Cuando hay varios elementos que devuelven datos y sólo un receptor

Las colas, en los sistemas de programación clásicos, son buffer circulares en los que se van colocando las tareas en orden de ejecución.

El los RTOS, el funcionamiento es similar, la diferencia reside en que el sistema operativo es el que gestiona el orden en lugar del programador.

La creación y manejo de las colas se realiza mediante llamadas al sistema.

Dependiendo del RTOS, los elementos de las colas dependen del tipo. Por ejemplo, algunos admiten cualquier tipo, otros sólo punteros...

Si la cola se llena o se vacía, se puede bloquear las funciones que escriben o reciben datos.

Interrupciones

Las interrupciones en un RTOS son las mismas que siempre pero, a la hora de programar, hay que tener ciertas cosas en cuenta:

  • No llamar funciones del sistema que puedan bloquearse.
  • no llamar funciones del sistema que puedan conmutar tareas.

Para el último caso, existen 3 métodos para solucionarlo:

  • avisar al S.O. de la entrada y salida de las interrupciones.
  • el S.O. intercepta las interrupciones y luego llama a la rutina de atención a interrupción. Hay que avisar al S.O. en la inicialización que rutinas tratan que interrupciones.
  • Funciones especiales desde las ISR.

 Gestión del tiempo

La gestión de tiempo en la mayoría de los sistemas operativos se basa en usar una interrupción periódica para incrementar un contador en el que se lleva la cuenta del tiempo transcurrido desde que se arrancó el sistema. Cada incremento del contador se denomina tick de reloj. Normalmente este periodo de tiempo (tick) es configurable al compilar el núcleo.

Bibliografía

  • "Sistemas Empotrados en Tiempo Real" José Daniel Muñoz Frías
  • "Material monográfico sobre los sistemas operativos empotrados"  Reinier Torres Labrada