8 RTLinux

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 92

Que es Tiempo Real ?

• Recordemos el concepto de Tiempo Real:

"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.“

• 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.
Diseño de un STR

• Un STR puede diseñarse directamente en Assembly sin


librerías ni nada, Ejemplo:
 Un ciclo infinito donde se consultan, una tras otra, las
entradas correspondientes a los eventos externos, y
se las atiende rápidamente
 El evento externo que no pueda esperar, que vaya
colgado de una interrupción, etc.
• Sin embargo, en sistemas medianamente complejos,
suele ser difícil asegurar los requisitos de temporización
si se emplea ese enfoque
• Recordar que valoramos las técnicas de programación
que dan cierta seguridad sobre el cumplimiento que esos
requisitos
• Por eso, a veces es conveniente utilizar un sistema
operativo de tiempo real (real-time operating system o
RTOS)
Introducción

• Antes las controladores que necesitaban procesar en tiempo real


era usadas sin S.O., pero obviamente era muy difícil programarlas
porque se tenia que encargar de la administración de recursos
(memoria, planificación, comunicación, sincronización, etc).
• Luego salieron los SOTR pero estos eran un muy pequeño
conjunto de programitas que hacían solo las tareas mas básicas de
un S.O. Esto elevo la productividad bastante, pero cada vez han
tenido que expandir estos S.O. porque las aplicaciones necesitan
poderse conectar a una red, o desplegar graficas, etc.
• Normalmente un SOTR tiene que ser desarrollado como tal desde
el principio, porque tratar de modificar un SO de tiempo compartido
como UNIX para que sea (verdadero) tiempo real, es muy
complejo.
• Ahora, desarrollar un SOTR desde el principio implica desarrollar
todos los drivers, protocolos de red, etc, lo cual también lleva
mucho tiempo.
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.).
• El S.O. es el que tiene que dar soporte y organizar la ejecución
de todas las tareas; también es 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 incertidumbre (falta de predecibilidad).
Definición de un SOTR

• Un sistema operativo en tiempo real (SOTR) es un sistema


capaz de garantizar los requisitos temporales de los
procesos o hilos que controla.
• Los sistemas operativos convencionales no son apropiados
para la ejecución de procesos en tiempo real, por :
 No tienen un comportamiento determinista
 No permite garantizar los tiempos de respuesta.
• No se quiere un S.O. que haga muchas cosas, sino uno que
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.
Definición de un SOTR

 Concurrencia, procesos ligeros (hilos) con memoria


compartida.
 Temporización, medida de tiempos y ejecución
periódica.
 Planificación, prioridades fijas con desalojo, acceso a
recursos con protocolo de herencia de prioridad.
 Manejo de dispositivos de E/S, acceso a recursos
hardware e interrupciones.
Algunos SOTR populares

VxWorks
• De Wind River, que es subsidiaria de Intel desde julio de 2009
• Con soporte para multiprocesadores, IPv6 y un sistema de archivos
• Con protección de memoria: O sea que las tareas no pueden alterar
la memoria de trabajo de otras tareas
• Funciona en las plataformas de embebidos más populares
• Se usa con un IDE para Windows/Linux, que normalmente incluye
depurador, simulador y herramientas de análisis
QNX
• De QNX, subsidiaria de Research in Motion (los del Blackberry)
desde mayo de 2010
• Símil Unix, ofrece funcionalidad parecida al VxWorks
• En 2007 fue abierto el código de su núcleo
RTLinux
• Basado en Linux
FreeRTOS
• Es gratuito
KURT
Características de los SOTR

• Poseen un cambio de contexto rápido


• Poseen un tamaño pequeño
• Responden a las interrupciones externas de una
forma rápida
• Minimizan los tiempos con interrupciones
deshabilitadas
• Proporcionan esquemas de gestión de memoria que
no afecten a la predictibilidad y proporcionan
archivos de acceso rápido
Elementos Proporcionados

• Con objeto de mantener las especificaciones de


tiempo los SOTR:
 Poseen un reloj de tiempo real
 Proporcionan planificación basada en prioridades
 Proporcionan alarmas y timeouts, y
 Las tareas pueden activarse en intervalos de tiempo
definidos
Lenguajes de Programación

• Básicamente cabe considerar tres alternativas:


• Lenguajes ensambladores
Proporcionan la máxima flexibilidad pero los
desarrollos son costosos y poco fiables
• Lenguajes secuenciales (C, Pascal, FORTRAN, etc.)
Deben tener un SOTR por debajo
• Lenguajes concurrentes (Ada, Modula, concurrent C,
etc.)
El lenguaje proporciona la concurrencia y el tiempo
real
Kernel monolítico vs. μkernel

• Existen básicamente dos maneras de organizar un


OS:
 De núcleo (kernel) monolítico: Todas las funciones
“residentes” del SO están en su núcleo
 Con microkernel: Algunas funciones del OS se
implementan como tareas similares a las de la aplicación

• VxWorks tiene kernel monolítico; QNX, RTLinux y


FreeRTOS usan microkernel
Problemas de los S.O. Convencionales

Los S.O. convencionales contienen algunas características


que no le permiten realizar procesos en tiempo real:
• Planificación en tiempo compartido
 Los planificadores tienden a asegurar un reparto equitativo
del tiempo de procesador (CPU) entre todos los procesos.
 Esta orientado a usuarios con trabajos interactivos desde
teclado y monitor.
 La ejecución de un proceso es impredecible porque
depende de la carga del sistema y el comportamiento del
resto de procesos.
Problemas de los S.O. Convencionales

• Baja resolución del temporizador


Se le proporciona acceso a unidades de tiempo del orden
de segundos, resolución que no es suficiente para
procesamiento en tiempo real.
Los SO mas recientes brindan unidades de mas precisión:
milisegundos.
• Núcleo no desalojable
Los procesos que se ejecutan en modo núcleo no pueden
ser desalojados.
Las llamadas al sistema podría tardar demasiado tiempo
para poder admitirlo en procesamiento en tiempo real.
• Memoria virtual
El manejo complejo de la memoria virtual lo hace
impredecible en tiempo
Problemas de los S.O. Convencionales

• Deshabilitación de interrupciones
El núcleo dehabilita las interrupciones para
implementar las exclusion mutua (secciones críticas).
Si Linux dehabilita las interrupciones y hay una
interrupción de reloj, esto realiza su bloqueo y
consecuentemente hay una perdida de precisión
temporal, poniendo en peligro la respuesta oportuna
frente a eventos externos (produciendo que el tiempo
de ejecución sea impredecible).
RTL implementa una solución elegante: las llamadas
a CLI, STI y IRET son reemplazadas por S_CLI,
S_STI y S_IRET que las emulan, así Linux nunca las
dehabilita.
Soluciones a los problemas de los S.O. Convencionales

• Los SO en Tiempo Real, ofrecen las siguientes


soluciones :
 Cambio de planificador por uno de prioridades.
 Implementan núcleos mas pequeños, denominados
microkernel, que tiene las funciones mínimas.
 Implementan funciones en base a estándares como
POSIX 1b orientados a la atención de procesos en tiempo
real. El estándar define la planificación con prioridades,
bloqueo de páginas de memoria, señales para tiempo
real, timers, etc.
Sistema Operativo en Tiempo Real

• Micronúcleo (Microkernel):
La parte del sistema operativo en Tiempo Real,
denominada micronúcleo, ofrece un conjunto básico de
servicios para los demás procesos:
 Creación de procesos e hilos adicionales.
 Mensajes entre hilos.
 Sincronización
 Temporizadores en tiempo real

• El micronúcleo se activa cuando:


 Un hilo llama a un servicio básico.
 Ocurre alguna excepción.
 Surge una interrupción hardware.
Sistema Operativo en Tiempo Real

• El resto de servicios del sistema operativo se implantan como


procesos independientes:
 Manejo de sistemas de ficheros.
 Interfaz con el usuario a través de un entorno orientado a
ventanas y eventos.
 Servicios de comunicación en red y a través de otros canales.
 Manejo de dispositivos y periféricos
• Las ventajas de este esquema son:
 Pequeño tiempo de latencia en atención a tareas prioritarias
(tiempo real).
 Modularidad para su implantación en plataformas embebidas:
reducción de requerimientos de memoria en sistemas sin disco,
pantalla, teclado, etc.
 Programación directa y a bajo nivel de periféricos: no son
necesarios los manejadores de dispositivo (device drivers).
 Los servicios adicionales del sistema operativo se ejecutan en
sus propios procesos: Protección de memoria y ejecución. Un
fallo en un servicio o dispositivo no afecta a la ejecución de
otros procesos
Arquitectura del software
(SO Clásico)
• Normalmente sistema
multiusuario donde prima
la seguridad, no es posible
Sistema Operativo de
el acceso directo al
hardware. Propósito General
• Uso de periféricos a través
de manejadores de Programas de usuario
dispositivos (device
drivers) integrados en el
propio sistema operativo.
Sistema Operativo
• Especificaciones de
ejecución suaves (soft
real-time systems) que Hardware
pueden incumplirse
momentáneamente sin que
suponga un problema.
Arquitectura del software
(SO de Tiempo Real)

 Las aplicaciones pueden


acceder directamente al Sistema Operativo en
hardware para mayor Tiempo Real
eficiencia.
 El sistema operativo ofrece
Programas de usuario
servicios de ejecución de
tareas, sincronización,
comunicaciones, etc.
 Restricciones temporales Sistema Operativo
que deben cumplirse en todo
momento (hard real-time
systems). Hardware
SISTEMA OPERATIVO
Real Time Linux
(RTLINUX)
Sistemas Operativo RTLINUX

• RTLinux nació del trabajo de Michael Barabanov y Victor


Yodaiken en la universidad de Nuevo Mexico.
• Las primeras versiones ofrecían un API muy reducido sin
tener en cuenta los estándares de tiempo real: POSIX Real-
Time extensions, PThreads, etc.
• A partir de la versión 2.0 Victor Yodaiken decide reconvertir
el API original a otro que fuera "compatible" con el API de
POSIX Threads.
• Extensiones de RT, POSIX.1b o IEEE 1003.1b, han sido
agregadas al standard IEEE (Institute of Electrical and
Electronic Engineering), ANSI (American National Standard
Institute) e ISO (International Standards Organization).
Normas POSIX

 POSIX (estándar 1003, Portable Operating System


Interface basado en uniX) es un conjunto de normas
IEEE/ ISO que definen interfaces de sistemas operativos
y permiten desarrollar software portátil y reutilizable
Normas POSIX

• POSIX. 1a : Unix básico.


• POSIX. 1b, 1d, 1o, 1j: Extensiones de tiempo real
• POSIX. 1c : Extensiones de tareas (threads)
• POSIX. 5 : Enlaces con el lenguaje Ada
• El objetivo de las extensiones de tiempo real es añadir a
POSIX básico los servicios que se necesitan para
conseguir un comportamiento predecible y facilitar la
programación concurrente.
• Estos servicios permiten:
Sincronización entre procesos, Compartición de
memoria, Gestión de la memoria virtual, Señales para
tiempo real, Definición de relojes y temporizadores,
Colas de mensajes, Entrada/Salida síncrona y
asíncrona.
Relación entre RTLinux y Linux

• Es importante no confundir la versión de RTLinux con la


versión del núcleo de Linux.
• RTLinux no es código independiente. Esto es, no es una
nueva versión de Linux.
• Parte de la distribución de RTLinux es un "parche" sobre
el código de Linux. Y otra parte son módulos cargables.
• Cada versión de RTLinux está diseñada para funcionar
sobre una versión de Linux. Por ejemplo la version 3 de
RTLinux necesita linux-2.3.48 o superior.
Características de RTLinux

• Sistema operativo de tiempo real estricto.


• API "próximo" al de POSIX threads.
• Planificador expulsivo por prioridades fijas, señales, sistema de
archivos POSIX (open, close, etc.) semáforos y variables condición.
• Soporte para diversas arquitecturas.
• Acceso directo al hardware (puertos e interrupciones).
• Comunicación con procesos linux por memoria compartida y
"tubos".
• Estructura modular para crear sistemas pequeños.
• Eficiente gestión de tiempos. En el peor caso se dispone de una
resolución próxima al microsegundo (para un i486).
• Facilidades para incorporar nuevos componentes: relojes,
dispositivos de E/S y planificadores.
• Existe una versión para multiprocesadores, con la posibilidad de
asignar tareas a procesadores.
• Tareas con memoria estática:
• Sin paginación.
• Sin protección de direcciones de memoria.
Arquitectura de RTLinux

• Solamente, el núcleo tiene derecho a acceder a los


recursos hardware (puertos, memoria, etc). El núcleo se
ejecuta estando el microprocesador en modo supervisor,
esto es, permite la ejecución de todas las instrucciones
máquina, es posible acceder a todas las direcciones de
memoria, programar los periféricos y capturar las
interrupciones.
• Un proceso "normal" no puede acceder a los puertos de
E/S ni capturar interrupciones. Los programas de usuario,
si necesitan interactuar con periféricos, lo hacen con
ayuda del núcleo a través de las llamadas a sistemas.
• El general, en SO clásicos el núcleo maneja los recursos y
comunica con los procesos de usuario.
• En cualquier sistema operativo (S.O.) las aplicaciones se
ejecutan bajo la supervisión del S.O. y sin la capacidad de
acceder al hardware de la máquina.
Arquitectura de Linux

netscape
bash staroffice

System Call

SO Linux

driver
Interrupción I/O

Hardware
Arquitectura de RTLinux

• A diferencia de otros diseños de S.O. de tiempo real,


RTLinux no añade nuevas llamadas al sistema ni modifica
ninguna de las ya existentes. Tampoco es una biblioteca
para el programador.
• RTLinux se sitúa entre el hardware y el propio sistema
operativo, creando una máquina virtual para que Linux
pueda seguir funcionando.
• RTLinux toma el control de todas las interrupciones, e
implementa un gestor de interrupciones por software.
• Internamente, RTLinux es como un micronúcleo que
realiza operaciones muy básicas, como es gestionar todas
las interrupciones y planificar las tareas de tiempo real. El
núcleo 'normal' de Linux se convierte en una tarea más, a
la que se le da la mínima prioridad.
• Las tareas RT-Linux se ejecutan utilizando el Run Time
Support (RTS) de RTLinux
Arquitectura de RTLinux

• Linux corre con la prioridad más baja, y puede ser


desalojado en cualquier momento por tareas de
prioridad más alta. Se dice que Linux corre como
una tarea en segundo plano (background).
• Tan pronto como las funciones de RT hayan sido
procesadas y haya recursos, se permite que el
proceso Linux ejecute.
• De esta forma, se permite que el sistema pueda
correr aplicaciones tales como adquisición de datos,
control, robótica, etc.; mientras sirve como una
estación de trabajo Linux estándar.
Arquitectura de RTLinux
El papel de las Interrupciones

• Linux como la mayoría de los SO de tipo Unix, tiene un núcleo que


deshabilita las interrupciones por largos periodos de tiempo
(característica de Linux no de un SO de RT).
• RTL implementa un esquema de interrupciones virtuales en el cual a
Linux no se le permite dehabilitar las interrupciones.
• Linux usa las macros CLI y STI para implementar la deshabilitación
y habilitación de interrupciones.
• RTL modifica las macros. CLI en lugar de dehabilitar las
interrupciones re-rutea la interrupción a un código RTL.
• Si la interrupción es una interrupción para:
 RTL: se le permite que continúe.
 Linux: se setea un flag.
• Cuando se ejecuta un STI, todas las interrupciones pendientes de
Linux son ejecutadas.
• De esta forma, RTL puede controlar las interrupciones de Linux
Aplicaciones de RT en 2 dominios

• Las aplicaciones de RT consisten en:


 Tareas de Tiempo Real (Tareas RT)
 Tareas sin Tiempo Real (Procesos Linux)
• Las Tareas de RT son incorporadas al núcleo (como módulos).
Como estan en el dominio de tiempo real pueden cumplir sus
requerimientos de tiempo real, pero deben ser simples porque
los recursos disponibles son bastante limitados.
• Los procesos Linux que manejan los displays, acceso a redes,
administración de datos, y todas las funciones que no afecten
el desempeño del sistema en los peores casos. Tienen el
rango completo de recursos Linux disponibles para su uso,
pero no pueden cumplir los requerimientos de tiempo real.
• El organizador de tareas (scheduler) que viene con RTL es un
scheduler preemptivo, de prioridad fija y considera a Linux
como la tarea de más baja prioridad.
• Se proveen también facilidades para la comunicación entre los
dos dominios.
Características de las Tareas en Tiempo Real
RT- TASK

• Comparten el mismo espacio de memoria que el núcleo,


por lo que pueden acceder a todas las variables y
funciones de éste, aunque se podrían producir
interbloqueos o condiciones de competencia.
• No pueden hacer uso de las llamadas al sistema de Linux.
• Se ejecutan en modo supervisor, esto es, pueden ejecutar
cualquier instrucción de procesador y tienen acceso a
todos los puertos de entrada/salida.
• Las páginas de memoria de datos y programa no pueden
sufrir intercambio con disco (Swap-out).
• 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.
Módulos Cargables

• Para entender y poder utilizar RT-Linux es necesario conocer


los módulos de carga dinámicos de Linux..
• Un módulo es un fichero objeto que se puede "enlazar" y
"desenlazar" en el núcleo de Linux en tiempo de ejecución.
• Con los módulos se agiliza enormemente el desarrollo de
software crítico ya que no es necesario crear un nuevo núcleo
y reiniciar la máquina cada vez que hacemos una prueba.
• Para trabajar con módulos se dispone de las siguientes
utilidades del sistema:
 insmod: Instala en el núcleo un módulo.
 rmmod: Extrae del núcleo un módulo.
 lsmod: Lista los módulos cargados.
 modinfo: Muestra información sobre el módulo.
 depmod: Determina las dependencias entre módulos.
Instalación de los Módulos
 Al compilar el mhello.c
obtendremos mhello.o
Insmod hola.c  Podemos insertar (cargar) el
módulo con la orden:
insmod mhello.o
 Desinstalar el modulo:
rmmod mhello
System Call
 Listado de módulos instalados en el
núcleo:
SO Linux
Hola.o lsmod
driver
Interrupción I/O

Hardware
Módulos en RTLinux

• La mayoría del API de RTLinux está dividido en varios módulos


opcionales con el objetivo de poder diseñar sistemas de tiempo
real lo más ajustados a las necesidades.
• Si una aplicación no necesita semáforos entonces no
cargamos el módulo que ofrece semáforos (rtl_mutex.o).
• RT LINUX esta estructurado como un componente de nucleo
pequeño y un conjunto opcional de componentes
• La componente core(principal) permite la instalacion de handler
de interrupciones de muy baja latencia que no puede ser
retardado o predesalojado por linux y algunas rutinas de
sincronizacion de bajo nivel.
Módulos en RTLinux

• La mayoría de funcionalidades de RTLinux es una


colección de módulos de kernel cargables:

Módulos cargables
rtl_sched.o planificador de prioridad
rtl_time.o controla los clocks del procesador
rtl_posixio.o soporte interface a drivers al estilo
posix: read, write, open
rtl_fifo.o conecta tareas RT y handlers de
interrupción a procesos linux
rtl_mutex.o para sincronización de recursos
El Planificador

• Hecho de poder instalar y desinstalar el planificador de


tiempo real dinámicamente, pues está compilado como un
módulo
• 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.
• Se incluyó una nueva política que sirve de base para
implementar características del POSIX: SCHED_FIFO,
SCHED_RR y otros.
• 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".
HILOS en RTLinux

• Las tareas RT en RTLinux, a partir de la v2.0, se realizan a


través de threads.
• El concepto es que cada tarea se implementa mediante un
thread.
• RTLinux adopta el estándar POSIX para los threads.
• Además añade ciertas funcionalidades NO POSIX o No
Portables (NP): Ejemplo: creación de threads periódicos
para implementación de tareas RT periódicas
• Los threads se pueden crear y destruir dinámicamente.
• El planificador (scheduler) gestiona cada thread de acuerdo
a sus propiedades o atributos.
• Existen mecanismos para sincronización y envío de señales
a los threads (tareas RT).
HILOS en RTLinux

• RTLinux implementa muchas funciones POSIX, aunque


en ocasiones no se ajustan completamente a la
semántica definida en el estándar:
 No implementan todas las opciones que define POSIX (Por ejemplo
sched_setscheduler solo ofrece la política SCHED_FIFO) o sólo se podrán
utilizar con ciertos parámetros. En estos casos, la llamada fallará con el
correspondiente código de retorno.
 Otra situación más sutil, consiste en que ciertas funciones sólo se pueden
ejecutar desde el núcleo de Linux, otras sólo por rt-tasks y otras se pueden
ejecutar indistintamente.
• Las funciones marcadas como "No RTL segura" son
aquellas que no pueden ejecutarse por tareas de tiempo
real ni por manejadores de interrupciones de tiempo real.
Funciones

Creación/destrucción Cancelación
• pthread_create • pthread_cancel
• pthread_exit • pthread_setcancelstate
Atributos • pthread_setcanceltype
• pthread_attr_init • pthread_testcancel
• pthread_attr_destroy • pthread_delete_np
• pthread_attr_setschedparam Threads periódicos (no estándar)
• pthread_attr_getschedparam • pthread_make_periodic_np
• sched_get_priority_max • pthread_setperiod_np
• sched_get_priority_min • pthread_wait_np
• pthread_attr_setstacksize Atributos (no estándar)
Control de ejecución (no estándar) • pthread_attr_setfp_np
• pthread_suspend_np • pthread_attr_setfp_np
• pthread_wakeup_np • pthread_attr_setcpu_np
• pthread_attr_getcpu_np
Creación y destrucción de Hilos

• pthread_create(*thread, *attr, *start, *arg)


Inicia la ejecución de un thread. Los atributos de creación por
defecto (attr=NULL) son: stack_size=8000, sched_priority=0,
cpu=current, use_fp=FALSE. El nuevo thread comienza su
ejecución inmediatamente.

• pthread_exit(retval)
Termina la ejecución del thread que invoca esta llamada,
retornando como valor de terminación retval.

• pthread_join(thread, retval)
Suspende la ejecución del thread que invoca esta llamada hasta
que thread termina su ejecución. En la implementación actual
todos los threads son creados PTHREAD_CREATE_JOINABLE
sin posibilidad de ser modificado.
Atributos

• pthread_attr_init(*attr), pthread_attr_init_destroy(*attr)
Los atributos de creación de tareas se pasan en una estructura
de tipo pthread_attr_t. El acceso a los campos de esta estructura
se realiza mediante funciones simulando la POO.

• pthread_attr_[get|set]schedparam(*attr, *sched_param)
Establece la prioridad de la nueva rtl-task. Por ahora (V3) sólo
está disponible la política SCHED_FIFO. El rango de prioridades
válido se obtiene de funciones sched_get_priority_min y
sched_get_priority_max. (0, 100000)

• pthread_attr_[set|get]fp_np(*attr, flag)
Para reducir el tiempo de cambio de contexto por defecto
RTLinux no salva a memoria el estado de coprocesador
matemático. Si queremos que las rtl-tasks puedan utilizar el
coprocesador entonces es necesario llamar a esta función.
Atributos

• pthread_attr_[set|get]cpu_np(*attr, cpu)
Asigna el nuevo thread que se crea con attr al procesador cpu
(sistema SMP). La numeración de los procesadores esta en el
fichero /proc/cpuinfo.

• pthread_attr_setstacksize(*attr, size)
Todos los threads comparten el mismo espacio de memoria, pero
cada uno ha de tener su propia pila.
Hilos periódicos, NO portables

•pthread_make_periodic_np(thread, start_time, period)


Permite "despertar" un thread de forma periódica. El propio
thread ha de suspenderse voluntariamente al final de cada
activación y RTLinux lo reactiva cada periodo. La unidad de
tiempo es el nanosegundo.

•pthread_setperiod_np(thread, *itime)
Equivalente a la función anterior pero utilizando una estructura
del tipo timerspec para especificar el instante de inicio y el
periodo.

•pthread_wait_np()
Suspende la ejecución del thread que la invoca. Es necesario
que el thread tenga un funcionamiento periódico.
Cancelación

•pthread_cancel(thread)
La cancelación es el mecanismo por el cual un thread invoca la terminación
de otro.El thread puede terminar o no en función de su estado de
"cancelación".

•pthread_setcanceltype(type, *oldtype)
Establece el tipo de cancelación. Estos dos tipos se denominan
respectivamente: PTHREAD_CANCEL_ASYNCHRONOUS, y
PTHREAD_CANCEL_DEFERRED. El primero se realiza inmediatamente
cuando otro thread llame a la función pthread_cancel. El otro, solo se puede
en ciertos punto de la ejecución del thread debido a que se pueda dejar el
sistema en un estado estable antes de finalizar (liberar semáforos, cerrar,
ficheros, etc.). Opción por defecto.

•pthread_testcancel()
Comprueba si hay pendiente alguna petición de cancelación y si es así
termina el thread que la invoca. Sólo tiene sentido si el thread está en estado
PTHREAD_CANCEL_ENABLE y tipo PTHREAD_CANCEL_DEFERRED.
Control de Ejecución

• pthread_suspend_np(thread)
Envía la señal RTL_SIGNAL_SUSPEND a un thread,
suspendiendo la ejecución del mismo. Para volver a activarlo
hay que enviarle la señal RTL_SIGNAL_WAKEUP o llamar a
pthread_wakeup_np.

• pthread_wakeup_np(thread)
Envía la señal RTL_SIGNAL_WAKEUP a un thread, reanudando
su ejecución.
Ejemplo 1: Tarea RT periódica

#include <rtl.h>
#include <time.h>
#include <pthread.h>
pthread_t thread;

/*tarea RT periodica */
void * thread_code(void)
{
pthread_make_periodic_np(pthread_self(), gethrtime(),
1000000000);
while (1) {
pthread_wait_np ();
rtl_printf("Hello World\n");
}
return 0;
}
int init_module(void) {
return pthread_create(&thread, NULL, thread_code, NULL);
}
void cleanup_module(void) {
pthread_delete_np(thread);
}
Ejemplo 2: Tarea RT periódica

#include <rtl.h>
#include <time.h>
#include <pthread.h>
pthread_t tareaRTperiodica;

/*tarea RT periodica */
void * rutina(void *arg)
{ struct sched_param p;
int nperiodos=0;
p.sched_priority=1;
pthread_setschedparam (pthread_self(),SCHED_FIFO, &p);
pthread_make_periodic_np(pthread_self(),gethrtime(),500000000);
/* periodo 0.5 seg */
while(1)
{ pthread_wait_np ();
rtl_printf("Periodo %d\n",nperiodos); nperiodos++;
}
return 0;
}
Ejemplo 2: Tarea RT periódica

/*incializacion del modulo */


int init_module(void)
{
rtl_printf("Cargando modulo ...\n");
return pthread_create (&tareaRTperiodica, NULL,
rutina, 0);
}

/*descarga del modulo */


void cleanup_module(void)
{
pthread_delete_np(tareaRTperiodica);
/* pthread_cancel(tareaRTperiodica); */
rtl_printf("Modulo descargado\n");
}
Ejemplo de una Tarea RT

• Para ejecutar este ejemplo deberá instalar algunos módulos de


RTLinux:
insmod rtl.o

• Luego para poder utilizar las funciones de creación y gestión de


threads (tareas RT), cargar el módulo del planificador:
insmod rtl_sched.o

• gethrtime() y las funciones de gestión del tiempo están en el


módulo
insmod rtl_time.o

Nota:
• Si la tarea rutina() tarda mucho, LINUX “se colgará”.
• Comprobar como afectan las tareas RT a procesos Linux: Variar periodo
o tiempo de computo y ejecutar algún proceso Linux al mismo tiempo.
¿Está más pesado el sistema?. Si el procesador está un poco más
pesado, recuerde que Linux corre más lento que lo usual.
NOTAS

• Como observamos, antes de poder poner en marcha


una aplicación de tiempo real necesitaremos cargar
los módulos del API que nuestra aplicación vaya a
necesitar.
• En el proceso de instalación de RTLinux se crea el
fichero rtl.mk, fichero que contiene todas las
declaraciones necesarias para poder compilar los
programas para RTLinux (módulos). Este fichero se
tiene que incluir en el Makefile para poder compilar
sin problemas nuestros programas.
Señales
e
Interrupciones
Señales e Interrupciones

• En la programación clásica de UNIX, las señales se utilizan


como un mecanismo de "comunicación" asíncrono.
• Si consideramos que un proceso es la abstracción de
procesador, entonces las señales hacen el papel de las
interrupciones.
• RTLinux hace un uso extensivo del concepto de
señal/interrupción. Se utilizarán para comunicarse rt-tasks entre
sí, modificar el estado de ejecución de rt-tasks , atender
interrupciones hardware y disparar eventos en el núcleo de
Linux.
• Actualmente toda la gestión de las interrupciones se realiza
mediante funciones no estándar. El objetivo de los
desarrolladores de RTLinux consisten en gestionar la
interrupciones como señales.
Señales e Interrupciones

• Al igual que sucede con las interrupciones, un proceso puede


establecer a priori la forma en la que se atienden las señales. Cada
señal puede estar en uno de los siguientes estados:
• Ignorada: El proceso no recibe estas señales
• Capturada: Cada vez que llega una señal se ejecuta una
función manejadora asociada.
• Opción por defecto: Dependiendo de la señal puede suspender
o terminar la ejecución del proceso, ignorarla o causar un
volcado de memoria (core).
• Bloqueada: Las señales no se "entregan" al proceso hasta que
se desbloqueen.
• Aunque una señal es un evento asíncrono a la ejecución de un
thread, la recepción de la señal no se produce de forma inmediata a
su envío. Si un thread de alta prioridad envía una señal a otro de
menor prioridad, entonces el thread de menor prioridad sólo podrá
atender (recibir) la señal cuando se ponga en ejecución.
Señales e Interrupciones

• Las señales que representan interrupciones físicas, sí que son


atendidas inmediatamente, siempre y cuando la interrupción
concreta no esté bloqueada ni inhabilitadas a nivel de
procesador.
• En los sistemas operativos clásicos, el número de posibles
señales es limitado, suele estar entre 16 y 64.
• RTLinux dispone de 1024 (RTL_SIGIRQMAX) distribuidas en
varias categorías (interrupciones, predefinidas de sistema,
entre pthreads y para Linux).
• Las señales serán el interfaz de RTLinux para el manejo y
captura de interrupciones.
Señales e Interrupciones

• 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 (instrucciones
ensamblador que modifican el estado de las interrupciones) por
S_CLI, S_STI que las emulan, de forma que Linux no puede
nunca deshabilitar las interrupciones.
• El núcleo de RTLinux captura todas las interrupciones
hardware y se las reenvía al núcleo de Linux.
Envió de Señales

• Listado de señales
• RTL_SIGNAL_NULL, no causa ninguna acción sobre el thread
destino.
• RTL_SIGNAL_SUSPEND, suspende la ejecución del hilo que recibe
esta señal.
• RTL_SIGNAL_WAKEUP, despierta el thread.
• RTL_SIGNAL_CANCEL, es equivalente a usar la función
pthread_cancel(hilo)
• RTL_LINUX_MIN_SIGNAL, equivale a enviar una interrupción
software al núcleo de Linux.Esta señal representa la interrupción 0.
• RTL_SIGNAL_KILL, termina la ejecución.
Esquema global de la gestión de
interrupciones

Habilitar/inhabilitar
interrupciones

Interrupciones
Interrupciones hardware
software

Enmascarar
interrupciones
Gestión de
Tiempo
Gestión de Tiempo

• POSIX define operaciones para trabajar con relojes y


temporizadores. RTLinux sólo implementa los relojes
POSIX, pero es posible realizar temporizaciones, pero
con funciones no estándar.
• Reloj (clock)
Dispositivo que registra el paso del tiempo. Las
operaciones que acepta son: leer/escribir la hora y
obtener sus características (resolución, precisión, etc.).
• Temporizador (timer)
Dispositivo que produce eventos relacionados con el
paso del tiempo a los que se les puede asociar
acciones. Las operaciones que acepta son: Programar
periodo, asociar función, consultar estado del
contador, etc.
Visión global de la Gestión de Tiempo
Visión global de la Gestión de Tiempo

• Los servicios de tiempo provistos por POSIX básico son


insufientes o inadecuados para las aplicaciones de
tiempo real.
• Estas requieren:
 Soporte para relojes adicional
 Mayor resolución
 Posibilidad de enterarse del desbordamiento de los
temporizadores.
 Posibilidad de utilizar otras señales distintas de SIGALRM
para indica la expiración de los temporizadores
Visión global de la Gestión de Tiempo

• Puede haber varios relojes, tienen nombres. Al menos


uno : CLOCK_REALTIME
opcional : CLOCK_MONOTONIC
• La resolución de la representación del tiempo es de 1
nanosegundo. Especificación del tiempo:
Struct timespec {
time_t tv_sec; //Nro segundos
long tv_nsec; //Nro nanosegundos
};

t = (tv_sec*109 + tv_nsec) nanoseg

• La resolución de CLOCK_REALTIME es de máximo 20


mseg (20,000,000 nseg)
• Los temporizadores se crean en forma dinámica
Visión global de la Gestión de Tiempo

• Operaciones
 Gestión de los relojes
 Gestión de temporizadores:
Relativos o absolutos
Un solo disparo o periódicos
 Retardo de alta resolución
Listado de Funciones

Leer el tiempo
• clock_gettime () Control
• clock_gethrtime () • rtl_getschedclock ()
• gethrtime () • rtl_setclockmode ()
• rtl_getbestclock ()
Temporización: Retardos
• rtl_delay ()

• nanosleep ()

• clock_nanosleep ()
Tipo de Datos que emplean las funciones

• Tipos de datos y constantes de tiempos (time.h):

struct timespec {
time_t tv_sec;
Long tv_nsec;
};

typedef struct rtl_clock *clockid_t;


typedef long hrtime_t;
typedef unsigned useconds_t;
Funciones de consulta de reloj

• hrtime_t gethrtime()
Devuelve el tiempo actual en nanosegundos del reloj más
eficiente.
• hrttime_t gethrtimeres()
Devuelve la resolución del tiempo que devuelve gethrtime().
• hrttime_t clock_gethrtime( clockid_t clock)
Devuelve el tiempo actual del reloj indicado. El reloj puede ser
alguno de los tres relojes lógicos o dos físicos disponibles en
RTLinux:

CLOCK_REALTIME
CLOCK_MONOTONIC
CLOCK_RTL_SCHED
CLOCK_8254
CLOCK_APIC
Funciones de Temporización, esperas

• rtl_delay(long duracion)
Realiza una espera activa de duración en nanosegundos.
Se puede utilizar desde una tarea RT o un manejador de
interrupción.
• usleep(unsigned duracion)
Realiza una espera NO activa de duración en microsegundos.
La espera se realiza suspendiendo el thread, por lo que no se
puede llamar desde un manejador de interrupción.
• nanosleep(struct timespec *espera,struct timespec *restante);
Realiza un espera NO activa de duración en nanosegundos. En
restante se devuelve el tiempo que queda de la espera en caso
de que se abortará por recibir alguna señal.
Funciones de Control

• rtl_getschedclock()
Retorna el identificador usado por el planificador
• rtl_getbestclock()
Retorna el identificador del reloj mas eficiente disponible
• rtl_setclockmode()
Establece el modo de operación del reloj especificado ( un
disparo periódico)
Sincronización
Sincronización

• Las funciones relacionadas con la gestión de recursos


están contenidas en el mismo módulo que el planificador.
• Por tanto para hacer uso de ellas es necesario tener
cargado el módulo rtl_sched.o.
• POSIX utiliza un mecanismo similar a los semáforos
binarios clásicos para controlar el acceso a las secciones
críticas.
• Los semáforos reciben el nombre de "mutex" y las
operaciones pasan a denominarse pthread_muttex_lock
y pthread_mutex_unlock.
Listado de funciones de sincronización

Semáforos
pthread_mutex_init Variables condición
pthread_mutex_destroy pthread_cond_init
pthread_mutex_lock pthread_cond_destroy
pthread_mutex_trylock pthread_cond_wait
pthread_mutex_unlock pthread_cond_broadcast
Atributos de semáforos pthread_cond_signal
pthread_mutexattr_init pthread_cond_timedwait
pthread_mutexattr_settype Atributos variable condicion
pthread_mutexattr_destroy pthread_condattr_init
pthread_mutexattr_setpshared
pthread_condattr_destroy
pthread_mutexattr_getpshared
pthread_condattr_getpshared
pthread_mutexattr_settype
pthread_condattr_setpshared
pthread_mutexattr_gettype
pthread_mutexattr_setprotocol Herencia dinámica
pthread_mutexattr_getprotocol pthread_mutex_setprioceiling
pthread_mutexattr_setprioceiling pthread_mutex_getprioceiling
pthread_mutexattr_getprioceiling
Paralelismo
y
Concurrencia
Paralelismo y concurrencia

• RTLinux implementa tareas RT a través de threads.


• Se ejecutan de forma concurrente, normalmente en un mismo
procesador.
• RTLinux ofrece funciones no POSIX para poder asignar
threads a procesadores en sistemas SMP con varios
procesadores:
Se pueden implementar procesos (tareas RT) que se ejecuten
en paralelo.
• API:
int pthread_attr_getcpu_np (phtread_attr_t *attr, int *cpu);
int pthread_attr_setcpu_np (phtread_attr_t *attr, int cpu);

Si no se especifica en los atributos del thread, se asigna por


defecto el procesador actual.
Ejemplo: Asignación de hilos a CPUs

#include <rtl.h>
#include <time.h>
#include <pthread.h>
#include <rtl_core.h>
#include <rtl_sched.h>
#include <errno.h>
pthread_t thread1,thread2;

void * start_routine(void *arg)


{ int cpu;
cpu=rtl_getcpuid();
rtl_printf("Thread \"%s\" en la CPU %d\n",(char*)arg,cpu);
return NULL;
}
void cleanup_module(void)
{
pthread_delete_np (thread1); pthread_delete_np (thread2);
}
Ejemplo: Asignación de hilos a CPUs

int init_module(void)
{
pthread_attr_t attr;
struct sched_param sched_param;
int thread_status;
rtl_printf("El modulo de arranque esta en la CPU %d\n",rtl_getcpuid());
pthread_attr_init(&attr);
pthread_attr_setcpu_np(&attr, 0);
sched_param.sched_priority = 1;
pthread_attr_setschedparam(&attr,&sched_param);
pthread_create(&thread1,&attr,start_routine,"Hello ");

pthread_attr_setcpu_np(&attr, 1);
pthread_create(&thread2,&attr,start_routine,"World!");
return 0;
}
Mecanismo de comunicación
entre tareas : FIFO
FIFO

• En RT-Linux sólo hay una forma de comunicación: Real-


Time FIFO. Las FIFO son un mecanismo de comunicación
basado en las "fifo" de UNIX, pero adaptado a tiempo real.
• El funcionamiento es muy similar a las tuberías (PIPE's) de
Unix, la comunicación es por flujo de datos sin estructura.
Una FIFO es un buffer de bytes de tamaño fijo sobre el que
se pueden hacer operaciones de lectura y escritura.
• Con las FIFOS podemos comunicar tanto tareas de tiempo
real entre sí, como tareas de tiempo real con procesos Linux
normales
• La comunicación es unidireccional, esto es, se comporta
como un buffer circular de forma que cada operación de
lectura elimina del buffer los datos leídos.
FIFO

 Una FIFO es un fichero especial de caracteres. Normalmente estará


en /dev/rtf0, /dev/rtf1, etc. Estos fichero no existen en Linux por lo
que hay que crearlos.
 Las FIFO se "ven" desde los procesos Linux como dispositivos
especiales de carácteres (con mayor number 150)en el directorio
/dev/...
 Las FIFOs son usadas como cualquier archivo normal (open, write,
read, close).
/dev/rtf1
cat cat
/dev/rtf0
/dev/fd0

SO Linux

Floppy FIFO
FIFO

• Si bien estos dispositivos especiales no suelen estar en las


distribuciones normales de Linux, son creados por los scripts
de instalación de RTLinux. De todas formas es posible
crearlos utilizando la orden: mknod /dev/rtf0 c 150 0.
• Se pueden utilizar hasta 64 fifos distintas, si bien se puede
incrementar este número hasta 248 modificando la macro
RTF_NO en el fichero include/rtl_fifo.h. No es posible
disponer de 256 fifos ya que las últimas 8 están reservadas.
FIFO

• Existen dos implementaciones distintas: rtl_fifo y rtl_nfifo.


rtl_fifo
Para trabajar con estas FIFO se pueden utilizar funciones
propias de RTLinux, como por ejemplo rtf_put, rtf_get, etc. Y
por otra parte utilizando el interfaz de dispositivos de POSIX:
open("/dev/rtf0",..), read, write, etc
rtl_nfifo
La nueva implementación ofrece además de los dos
interfaces anteriores un interfaz similar al de las colas de
mensajes de POSIX: mq_fast_send, mq_fast_receive, etc.
Este API permite pasar de una comunicación por stream
(flujo de datos) a otra por mensajes, en la que se puede
definir claramente la unidad de información.
Desde el punto de vista de un
Proceso Linux normal

• Las FIFOS se utilizan como si fueran ficheros normales (open,


read, write, close). Para poder utilizarlas han de existir, esto es,
una tarea de tiempo real ha de haber creado la FIFO (haya
creado mediante la llamada rtf_create) antes de que un proceso
normal de Linux pueda hacer un open sobre ella.
• Los ficheros especiales son el interfaz de acceso a un
manejador del sistema operativo, pero si el manejador no existe
entonces no sirve de nada el fichero especial, de hecho, intentar
abrir un fichero especial del cual el sistema operativo no tiene el
manejador asociado fallará.

/dev/rtf1
cat cat
/dev/rtf0
/dev/fd0

SO Linux

Floppy FIFO
Desde el punto de vista de un
Proceso Linux normal

Las funciones para manejar un FIFO desde una


aplicación Linux:
• fd=open("/dev/rtfx", flags)
Antes de realizar esta operación es necesario haber creado la
fifo llamando a rtf_create(). A efectos prácticos la función open
no hace nada útil excepto devolver el descriptor de fichero y
comprobar que hemos abierto el fichero en modo
O_NONBLOCK, esto es, sólo podemos realizar operaciones no
bloqueantes.
• close(fd)
Existe por compatibilidad. Realmente no hace nada, sólo liberar
las estructuras de datos relacionadas con el descriptor de
fichero.
• read(fd, *buf, size)
Esta función es un front end para a la función rtf_get. Retorna el
número de bytes efectivamente leídos.
• write(fd, *buf, size)
Front end a rtf_put.
Lectura de FIFO desde una tarea LINUX

#include <fcntl.h>
main () {
int fd, count;
int valor;;
fd=open("/dev/rtf0", O_RDONLY);
while (1) {
read(fd, sizeof(valor));
printf("valor: %8d\n", valor);
}
}
Desde el punto de vista de una
Tarea de tiempo real

 Las FIFOS se utilizan mediante funciones


específicas.
 El fichero de cabecera que hay que incluir para usar
estas llamadas es include/rtl_fifo.h

Creación / Destrucción Manejadores de eventos


rtf_create_handler()
rtf_create()
rtf_create_rt_handler()
rtf_destroy ()

Trabajar con fifos


rtf_put ()
rtf_get ()
rtf_flush ()
rtf_isempty ()
Desde el punto de vista de una
Tarea de tiempo real

• rt_create(unsigned int fifo, int size):


crea una FIFO con un buffer de tamaño size. A partir de
este momento, y hasta que se destruya, el dispositivo
accedido desde /dev/rtf_xx existe y se puede utilizar.
• rt_destroy(unsigned int fifo):
se destruye la FIFO y se libera la memoria.
• rt_fifo_put(fifo, char *buf, int count):
intenta escribir count bytes del buffer buf. Si no hay
bastante espació en el buffer de la FIFO, retorna -1.
• rt_fifo_get(fifo, char *buf, count):
intenta leer count bytes desde la FIFO, si no hay
bastantes datos disponibles retorna -1
Desde el punto de vista de una
Tarea de tiempo real

• rtf_create_handler(fifo_nr, function)
Instala una función manejadora que se invoca cada vez
que un proceso normal de Linux lee o escribe sobre la fifo
indicada. Sólo se llama la función cuando se ha llevado a
cabo la operación con éxito, p.e. una operación de lectura
sobre una fifo vacía no causa la llamada del manejador
hasta que se escribe y luego se completa la llamada de
lectura. Para desinstalar un manejador nuestro tenemos
que instalar la función manejadora por defecto
(default_handler):
rtf_create_handler(n_fifo,default_handler).
•rtf_create_rt_handler(fifo_nr, function)
Instala una función manejadora que se invoca cada vez
que alguna tarea de tiempo real lee o escribe sobre la fifo
indicada. El manejador se desinstala de igual forma que el
manejador anterior.
Uso de FIFOS desde RTLINUX

// Programa: rt_fifo.c void tarea(char *arg){


#include <linux/module.h> rtf_put(0, frase, strlen(frase));
#include <linux/kernel.h> pthread_exit(0);
#include <rtl_fifo.h> }
#include <rtl_core.h> int init_module(void){
char *frase="Hola desde una if (rtf_create(0, 4096)) return -1;
rt-task\n"; if (rtf_create_handler(0,
int manejador(unsigned int &manejador))
fifo){ return -1;
printk("Puedo llamar a return 0;
printk!!\n"); }
return 0; void cleanup_module(void){
} rtf_destroy(0);
}
Ejemplo de Uso de FIFOS desde RTLINUX

• Para ejecutar ejemplo de la FIFO:


• Compilar módulo con opciones definidas por
/usr/src/rtlinux- 3.1/rtl.mk
• Cargar módulos:
 basicos (rtl, rtl_time)
 del planificador (rtl_sched)
 servicios FIFO (rtl_posixio, rtl_fifo).
 finalmente cargar el módulo ejemplo.o

También podría gustarte

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy