Você está na página 1de 152

Introduccin a los Sistemas

operativos de tiempo Real

Alejandro Celery
acelery.utn@gmail.com
Introduccin a los sistemas embebidos - FI-UBA - 2011

Parte 1
Un poco de contexto

Sistemas embebidos
Los sistemas embebidos son plataformas con
recursos muy limitados en comparacin con una PC.
Es por esto que generalmente no tienen un sistema
operativo completo, sino slo el subconjunto de
estos que pueden manejar ventajosamente.
En algunos casos el OS no es un programa en s
mismo sino que es un conjunto de funciones que se
ejecutan solo en momentos determinados del
programa.

Introduccin a los RTOS - 2011 - FI-UBA

Qu es un OS?
Es un conjunto de programas que ayuda al programador de
aplicaciones a gestionar los recursos de hardware disponibles, entre
ellos el tiempo del procesador y la memoria.
La gestin del tiempo del procesador permite al programador de
aplicaciones escribir mltiples subprogramas como si cada uno fuera
el nico que utiliza la CPU.
Una parte del OS se encarga de asignar tiempo de ejecucin a
todos los programas que tiene cargados en base a un juego de
reglas conocido de antemano. A estos subprogramas se los llama
tareas.
Con esto se logra la ilusin de que mltiples programas se ejecutan
simultneamente, aunque en realidad slo pueden hacerlo de a uno
a la vez (en sistemas con un slo ncleo, como es el caso general
de los sistemas embebidos).

Introduccin a los RTOS - 2011 - FI-UBA

Cmo se administra el tiempo del CPU?


El encargado de esta gestin es un componente del
OS llamado scheduler o programador de tareas. Su
funcin es determinar qu tarea debe estar en
ejecucin a cada momento.
Ante la ocurrencia de ciertos eventos revisa si la
tarea en ejecucin debe reemplazarse por alguna
otra tarea. A este reemplazo se le llama cambio de
contexto de ejecucin.

Introduccin a los RTOS - 2011 - FI-UBA

Ms contexto
Se llama contexto de ejecucin al conjunto de
recursos que identifican el estado de ejecucin de
una tarea:

IP (instruction pointer)
SP (stack pointer)
Registros del CPU
Contenido de la pila en uso

Introduccin a los RTOS - 2011 - FI-UBA

Cambiemos de contexto
Cuando el scheduler determina que debe cambiarse
el contexto de ejecucin, invoca a otro componente
del OS llamado dispatcher para que guarde el
contexto completo de la tarea actual y lo reemplace
por el de la tarea entrante.
Por esta razn debe reservarse un bloque de
memoria de datos para cada tarea. Esto limita la
cantidad de tareas simultneas del sistema (pueden
sin embargo eliminarse y crearse nuevas tareas en
tiempo de ejecucin).

Introduccin a los RTOS - 2011 - FI-UBA

Cambiemos de contexto
Estos cambios de contexto se realizan de forma
transparente para la tarea, no agregan trabajo al
programador. Cuando la tarea retoma su ejecucin
no muestra ningn sntoma de haberla pausado
alguna vez.
Los OS trabajan en dos modos:

En modo cooperativo, estos cambios solo ocurren


cuando la tarea en ejecucin relega voluntariamente el
uso del CPU.
En cambio en modo preemptive el scheduler tiene la
facultad de remover una tarea sin el consentimiento de la
misma.

En este caso debe preveerse que algunas operaciones no


deben ser interrumpidas, a estos pasajes del programa se los
llama secciones crticas. Los OS permiten inhibir de este modo
los
cambios ade
cuando
es necesario.
Introduccin
loscontexto
RTOS - 2011
- FI-UBA

Qu es un RTOS?
Un RTOS es un sistema operativo de tiempo real.
Esto significa que hace lo mismo que un OS comn
pero adems me da herramientas para que los
programas de aplicacin puedan cumplir
compromisos temporales definidos por el
programador. El objetivo del mismo es diferente de
un OS convencional.
Un RTOS se emplea cuando hay que administrar
varias tareas simultneas con plazos de tiempo
estrictos.

Introduccin a los RTOS - 2011 - FI-UBA

Cmo se define un sistema de tiempo real?

Un STR est definido por:

Los eventos externos que debe atender.


La respuesta que debe producir ante estos eventos.
Los requerimientos de temporizacin de esas respuestas.

Los STR suaves se suelen disear como si fueran


STR duros. Luego se da mayor prioridad a la
atencin de los eventos con compromisos
temporales estrictos.

10

Introduccin a los RTOS - 2011 - FI-UBA

Por qu usar un RTOS?

Para cumplir con compromisos temporales estrictos

El RTOS ofrece funcionalidad para asegurar que una vez ocurrido


un evento, la respuesta ocurra dentro de un tiempo acotado. Es
importante aclarar que esto no lo hace por s solo sino que brinda
al programador herramientas para hacerlo de manera ms
sencilla que si no hubiera un RTOS.

Para no tener que manejar el tiempo a mano

Esto implica que una aplicacin mal diseada puede fallar en la atencin
de eventos an cuando se use un RTOS.

El RTOS absorbe el manejo de temporizadores y esperas, de


modo que hace ms facil al programador el manejo del tiempo.

Tarea Idle

11

Cuando ninguna de las tareas requiere del procesador, el sistema


ejecuta una tarea llamada idle u ociosa. Esto me permite
fcilmente contabilizar el nivel de ocupacin del CPU, poner al
mismo en modo de bajo consumo o correr cualquier tarea que
pudiera ser de utilidad para el sistema cuando no debe atender
ninguno de sus eventos.
Introduccin a los RTOS - 2011 - FI-UBA

Por que usar un RTOS?

Multitarea

Escalabalidad

Simplifica sobremanera la programacin de sistemas con


varias tareas.
Al tener ejecucin concurrente de tareas se pueden
agregar las que haga falta, teniendo el nico cuidado de
insertarlas correctamente en el esquema de ejecucin del
sistema.

Mayor reutilizabilidad del cdigo

12

Si las tareas se disean bien (con pocas o ninguna


dependencia) es ms fcil incorporarlas a otras
aplicaciones.
Introduccin a los RTOS - 2011 - FI-UBA

La letra chica 1

Se gasta tiempo del CPU en determinar en todo


momento qu tarea debe estar corriendo. Si el
sistema debe manejar eventos que ocurren
demasiado rpido tal vez no haya tiempo para esto.
Se gasta tiempo del CPU cada vez que debe
cambiarse la tarea en ejecucin.
Se gasta memoria de cdigo para implementar la
funcionalidad del RTOS.
Se gasta memoria de datos en mantener una pila y
un TCB (bloque de control de tarea) por cada tarea

13

El tamao de estas pilas suele ser configurable POR


TAREA, lo cual mitiga este impacto.
Introduccin a los RTOS - 2011 - FI-UBA

La letra chica 2

Finalmente, debe hacerse un anlisis de tiempos,


eventos y respuestas ms cuidadoso. Al usar un
RTOS ya no es el programador quin decide cundo
ejecutar cada tarea, sino el scheduler. Cometer un
error en el uso de las reglas de ejecucin de tareas
puede llevar a que los eventos se procesen fuera del
tiempo especificado o que no se procesen en lo
absoluto.
A la luz de los beneficios mencionados, en el caso
de que la plataforma de hardware lo permita y el
programador est capacitado no hay razones para
no usar un RTOS.
14

Introduccin a los RTOS - 2011 - FI-UBA

Tipo de tareas que vamos a implementar en


una aplicacin de tiempo real

Tareas peridicas

Tareas aperidicas

Atienden eventos que ocurren constantemente y a una


frecuencia determinada. P. ej, destellar un led.
Atienden eventos que no se sabe cundo van a darse.
Estas tareas estn inactivas (bloqueadas) hasta que no
ocurre el evento de inters. P. ej, una parada de
emergencia.

Tareas de procesamiento contnuo

15

Son tareas que trabajan en rgimen permanente. P. ej,


muestrear un buffer de recepcin en espera de datos
para procesar.
Estas tareas deben tener prioridad menor que las otras,
ya que en caso contrario podran impedir su ejecucin.
Introduccin a los RTOS - 2011 - FI-UBA

Caso de estudio

Tarea de la primera prctica

16

Destellar un led a una frecuencia determinada.


Muestrear un pulsador y reflejar su estado en un led
(tarea peridica).
Contar pulsaciones y destellar un led esa misma cantidad
de veces (tarea aperidica).

Introduccin a los RTOS - 2011 - FI-UBA

Parte 2
Por qu FreeRTOS

Es de cdigo abierto

18

No hay costo de implementacin.


El cdigo est ampliamente comentado, es muy
sencillo verificar cmo hace su trabajo.
Es relativemente sencillo de portar a plataformas
nuevas.

Introduccin a los RTOS - 2011 - FI-UBA

Es fcil de implementar

Hay mucha documentacin disponible.

19

Libro de texto escrito por uno de los diseadores del


sistema.
Incluye una demostracin de sus funciones para cada
plataforma en la que est soportado.

Nutrida comunidad de usuarios (ver


http://sistemasembebidos.com.ar/foro)
Hay una opcin con soporte comercial.
Hay una opcin con certificacin SIL-3 para
sistemas de misin critica.

Introduccin a los RTOS - 2011 - FI-UBA

Est pensado para microcontroladores

20

Est escrito mayormente en C, salvo las partes


especficas de cada plataforma.
Es liviano en tamao de cdigo y en uso de
memoria RAM.

Introduccin a los RTOS - 2011 - FI-UBA

Primera mirada a FreeRTOS

21

Es un mini kernel de tiempo real que puede trabajar en modos


cooperativo, preemptive o mixto.
Mini kernel significa que provee los servicios mnimos e
indispensables
Permite compilar solo las funciones que se vayan a usar,
acotando as su impacto en la memoria de cdigo.
Se puede definir y acotar en tiempo de compilacin el uso de
memoria de datos por parte del sistema.
Ofrece funciones de temporizacin, de comunicacin entre
tareas, de sincronizacin entre tareas e interrupciones, y de
definicin de secciones crticas

Introduccin a los RTOS - 2011 - FI-UBA

Algunas opciones de configuracin

FreeRTOSConfig.h

22

configUSE_PREEMPTION
configCPU_CLOCK_HZ
configTICK_RATE_HZ
configMAX_PRIORITIES
configMINIMAL_STACK_SIZE
configTOTAL_HEAP_SIZE
configUSE_USE_MUTEXES
configUSE_CO_ROUTINES
#define INCLUDE_vTaskDelete 1

Introduccin a los RTOS - 2011 - FI-UBA

Parte 3
Tareas en FreeRTOS

Cmo es una tarea en FreeRTOS?

Citando a Richard Barry: Las tareas se


implementan con funciones de C. Lo nico especial
que tienen es su prototipo, que debe devolver void y
recibir un puntero a void como parmetro.

void vTareaEjemplo (void *parametros);

Cada tarea tiene su propio punto de entrada,


seccin de inicializacin y lazo de control.
Las funciones de tarea (en adelante, tareas) en
FreeRTOS NO DEBEN RETORNAR BAJO NINGN
CONCEPTO. No deben incluir un return ni
ejecutarse hasta la llave de cierre

24

Si una tarea deja de ser necesaria, puede eliminrsela


explcitamente.
Introduccin a los RTOS - 2011 - FI-UBA

Cmo es una tarea en FreeRTOS?

Las tareas tienen una prioridad de ejecucin. 0 es la


menor prioridad.

Se pueden crear mltiples instancias de una misma


funcin de tarea

Se recomienda usar referencias a tskIDLE_PRIORITY (+1, +2,


etc)
No hay lmites a la cantidad de prioridades del sistema, pero se
gasta RAM por cada una. Usar con cuidado.

Estas instancias pueden recibir un parmetro que las


caracterice

IMPORTANTE: Cuando una tarea deja de estar en


ejecucin, las referencias a variables alojadas en su pila
dejan de ser vlidas.
Al ser funciones de C, se aplican las mismas reglas de
visibilidad de variables => se puede compartir memoria
entre las tareas usando variables globales.

25

En este caso se debe cuidar el acceso a este recurso


Introduccin a los RTOS - 2011 - FI-UBA
compartido.

Ejemplo 1: Dos tareas de igual prioridad se apropian


del CPU, pero son administradas por el scheduler.
void vTask1( void *pvParameters )
{
// Punto de entrada - Seccion de inicializacion
const char *pcTaskName = "Task 1 is running\n";
volatile unsigned long ul;

// Cuerpo de la tarea
for( ;; )
{
vPrintString( pcTaskName ); // enva el string a la consola del IDE
for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ ) { }
}
// La tarea NUNCA debe pasar de este punto, si lo hiciera debe ser
eliminada
vTaskDelete(NULL);
}

26

Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 1: Dos tareas de igual prioridad se apropian


del CPU, pero son administradas por el scheduler.
void vTask2( void *pvParameters )
{
// Punto de entrada - Seccion de inicializacion
const char *pcTaskName = "Task 2 is running\n";
volatile unsigned long ul;

// Cuerpo de la tarea
for( ;; )
{
vPrintString( pcTaskName ); // enva el string a la consola del IDE
for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ ) { }
}
// La tarea NUNCA debe pasar de este punto, si lo hiciera debe ser
eliminada
vTaskDelete(NULL);
}

27

Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 1: Dos tareas de igual prioridad se apropian


del CPU, pero son administradas por el scheduler.
// Punto de entrada de la aplicacin con FreeRTOS
int main( void )
{
// Creo las dos tareas
xTaskCreate( vTask1, "Task 1", 240, NULL, 1, NULL );
xTaskCreate( vTask2, "Task 2", 240, NULL, 1, NULL );
// Inicio el scheduler
vTaskStartScheduler();
// No se llega a este punto si no hubo problemas al iniciar el
scheduler
for( ;; );
return 0;
}
28

Introduccin a los RTOS - 2011 - FI-UBA

Estados de las tareas en FreeRTOS


Transiciones de estados de las
tareas del ejemplo 1.
Ntese que ninguna de las tareas
cede el control del CPU, sin
embargo el scheduler las conmuta
al cabo de un tiempo.

29

Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 1: Demostracin

Vemoslo funcionando

30

Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 1: Diagrama de ejecucin

31

Introduccin a los RTOS - 2011 - FI-UBA

Algoritmo de scheduling

Como elige el scheduler la tarea a ejecutar? Usa un algoritmo


llamado Fixed priority preemptive scheduling

SIEMPRE ejecuta la tarea de mayor prioridad que esta en


condiciones de ejecutarse.

Fixed priority significa que el kernel NO MODIFICA las prioridades


de las tareas (salvo en un caso particular que se ver ms
adelante).
Esto simplifica el anlisis de ejecucin del sistema, a la vez que
transfiere al programador la total responsabilidad del cumplimiento
de los plazos.

Esto puede hacer que tareas de menor prioridad no reciban


ningn tiempo de ejecucin. A esto se le denomina starvation
(hambreado) de la tarea.
Ya veremos cmo una aplicacin deja de estar en condiciones de
ejecutarse

Si la aplicacin est en modo preemptive, al cabo de un


tiempo el scheduler va a retirar la tarea en ejecucin solo si
hubiera una de igual prioridad en condiciones de
ejecutarse.
32
Introduccin a los RTOS - 2011 - FI-UBA

Ms sobre el algoritmo de scheduling

Recordar: la tarea de mayor prioridad en


condiciones de ejecutarse (en estado Ready)

Si hubiere varias tareas de la misma prioridad en este


estado, el kernel las ejecuta secuencialmente a todas.

33

Si hubiere alguna(s) de menor prioridad, no va(n) a recibir


tiempo alguno hasta que todas las de mayor prioridad salgan
del estado Ready.

Se define una frecuencia llamada configTICK_RATE_HZ.


La inversa es el lapso que el scheduler asigna a cada
tarea para ejecutarse antes de verificar si debe quitarla
del estado Running.
La definicin de esta frecuencia es un punto importante
del diseo.
Introduccin a los RTOS - 2011 - FI-UBA

Resolucin temporal del sistema

Un valor muy bajo de TICK_RATE hace que el sistema


sea lento para responder a los eventos temporales.

Un valor muy alto de TICK_RATE hace que el scheduler


trabaje ms seguido, ocupando ms tiempo del CPU.

Si la tarea en ejecucin no cede el control del CPU, la prxima


tarea a ejecutarse debe esperar a que termine el lapso actual.
Por esto es que para mantener al sistema gil cada tarea debe
usar el CPU lo mnimo e indispensable, o ms bien cederlo
todas las veces que no lo necesite.

Este tiempo debiera ser despreciable respecto del que


consume la aplicacin.

El TICK_RATE del sistema termina siendo un valor de


compromiso entre estas dos cotas.

34

Recordar que la tarea idle ayuda a contabilizar el grado de


utilizacin del CPU.

Introduccin a los RTOS - 2011 - FI-UBA

Detalle de la interrupcin del scheduler

35

Introduccin a los RTOS - 2011 - FI-UBA

Consideraciones de diseo

Siempre que varios procesos deban ocurrir en


paralelo, son candidatos a ser tareas.
Como primer criterio para asignar prioridades, se
sugiere preguntarse que evento se debe atender y
cul puede esperar si ambos ocurren
simultneamente.
Se debe evitar el hambreado de las tareas de menor
prioridad.

Esto no es necesariamente un error, si la tarea de mayor


prioridad tiene trabajo que hacer, es correcto que no le de
paso a las demas.

Es importante hacer un anlisis detallado de los


eventos, sus respuestas y los compromisos
temporales antes de asignar las prioridades de
36
Introduccin a los RTOS - 2011 - FI-UBA
ejecucin.

Funciones para trabajar con tareas

portBASE_TYPE xTaskCreate( ... );

void vTaskStartScheduler( void );

Se la puede llamar en cualquier momento.


Se pueden crear y destruir tareas durante la ejecucin del
programa.
Si una aplicacin usa varias tareas pero no simultneamente,
puede crearlas a medida que las necesita y luego destruirlas para
recuperar la memoria de datos.
Ver detalles en http://www.freertos.org/ -> API Reference -> Task
Creation

Crea la tarea IDLE


Comienza la ejecucin de las tareas
Ver detalles en http://www.freertos.org/ -> API Reference -> Kernel
Control

void vPrintString(const char *)

37

Enva un string a la consola del entorno LPCxPRESSO


La vamos a utilizar en los ejemplos.
Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 3: Mala asignacin de prioridades


Las funciones de tarea son las mismas del ejemplo 1.

// Punto de entrada de la aplicacin con FreeRTOS


int main( void )
{
// Creo las dos tareas
xTaskCreate( vTask1, "Task 1", 240, NULL, 1, NULL );
xTaskCreate( vTask2, "Task 2", 240, NULL, 2, NULL );
// Inicio el scheduler
vTaskStartScheduler();
// No se llega a este punto si no hubo problemas al iniciar el scheduler
for( ;; );
return 0;
}
38

Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 3: Demostracin

Vemoslo funcionando

39

Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 3: Diagrama de ejecucin

40

Introduccin a los RTOS - 2011 - FI-UBA

Parte 4
Primera prctica con FreeRTOS

Tarea opcional para el hogar

Tarea 1: Destellar un led a una frecuencia


determinada
Tarea 2: Seguir el estado de un pulsador con un led,
incluyendo el anti-rebote elctrico
Tarea 3: Contar pulsaciones de un boton y luego de
un segundo sin pulsaciones destellar un led esa
misma cantidad de veces
Se sugiere implementarlas usando el driver de GPIO
provisto por NXP

42

Introduccin a los RTOS - 2011 - FI-UBA

Recursos de software 1

void vTaskDelay( portTickType xTicksToDelay );

Produce una demora en la tarea que la llama. Cede el


control del CPU mientras este tiempo no expira.
INCLUDE_vTaskDelay must be defined as 1 for this
function to be available.
Uso:
vTaskDelay (500 / portTICK_RATE_MS);

43

Introduccin a los RTOS - 2011 - FI-UBA

Recursos de software 2

void vTaskDelayUntil( portTickType


*pxPreviousWakeTime, portTickType xTimeIncrement );

INCLUDE_vTaskDelayUntil must be defined as 1 for this


function to be available.
Asegura un tiempo constante entre sucesivos llamados a esta
funcin.
Cada vez que se la llama actualiza *pxPreviousWakeTime
Uso:
portTickType xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
for( ;; ) {
vTaskDelayUntil( &xLastWakeTime, xFrequency );

44

Introduccin a los RTOS - 2011 - FI-UBA

Recursos de hardware

Se pueden usar leds y pulsadores del base board


Se pueden insertar el target board en un protoboard y
agregarle pulsadores y leds

Las entradas pueden configurarse con pull-up interno, de


este modo solo debe ponerse un pulsador conectado a
GND

Cuidado, las IO del LPC manejan hasta 4mA (simtrico)


Se sugiere un buffer tipo ULN2003 para manejar los LEDs

Usando una IO como GND y limitndose al LED2 del target


board se pueden hacer las prcticas con solo esta placa y un
botn soldado sobre el rea de prototipado que incluye.

El target board da una salida de 3,3V

45

Toma alimentacin de un regulador de 500mA


Se sugiere no tomar ms de 300mA de esta salida
Introduccin a los RTOS - 2011 - FI-UBA

Parte 5
Ms estados de las tareas

Ms estados de las tareas

Hasta ac solo vimos


tareas en los estados
Running y Ready
Para que no haya
starvation de las tareas
menos prioritarias del
sistema, es necesario que
las ms prioritarias dejen
el estado ready
Cuando una tarea deja de
estar en condiciones de
ejecutar, pas a alguno de
los dos estados
bloqueados: Blocked o
Suspended
47

Funciones de temporizacin

49

Ahora podemos ver con ms detalle el efecto de llamar a


vTaskDelay() y vTaskDelayUntil()
Ponen a la tarea en el estado Blocked hasta que expira
la cantidad de ticks indicada como parmetro
El kernel maneja el tiempo en ticks, es por esto que se
usa siempre la constante portTICK_RATE_MS
Cada vez que expira un perodo de ejecucin, el
scheduler revisa si alguna tarea de mayor prioridad a la
actual sale del estado blocked (pasa al estado ready)

Introduccin a los RTOS - 2011 - FI-UBA

Tareas peridicas

50

Ahora podemos ver como ve el kernel una tarea


peridica.
Pasa la mayor parte de su tiempo en el estado
blocked hasta que expira su tiempo de bloqueo, en
este momento pasa al estado ready.
En FreeRTOS se implementan mediante llamadas a
vTaskDelayUntil().

Introduccin a los RTOS - 2011 - FI-UBA

Parte 6
Sincronizacin entre tareas y
eventos

Tareas aperidicas

52

Acabamos de ver como una tarea puede


permanecer bloqueada durante un tiempo fijo.
Ahora nos interesa que permanezca bloqueada
hasta que ocurra un evento determinado (interno
o externo).
La situacin es la misma, queremos que la tarea
ceda el CPU a las de menor prioridad, ya que no
va a estar haciendo nada.
Para esto existe el concepto de semforo.

Introduccin a los RTOS - 2011 - FI-UBA

Qu es un semforo?

53

Un semforo en informtica representa el mismo


concepto que un semforo vial.
Su funcin es restringir el acceso a una seccin
particular del programa (de la misma manera que uno
vial no me permite cruzar la calle cuando estn pasando
autos).
En ambos casos, nadie me obliga a consultar el
semforo antes de ingresar a la seccin crtica. Sin
embargo, los peligros de ignorar un semforo son bien
conocidos.
El uso de semforos es una convencin a la que
deben adherir todas las tareas involucradas.
Introduccin a los RTOS - 2011 - FI-UBA

Cmo se usan en un RTOS?

54

El uso que le vamos a dar es el de impedir que una tarea


ingrese a cierta parte del cdigo hasta que ocurra el
evento esperado.
Los semforos tienen dos operaciones asociadas:
Tomar el semforo (sera equivalente a ponerlo en
rojo)
Dar el semforo (sera equivalente a ponerlo en verde)
Es responsabilidad del programador tanto tratar de tomar
el semforo antes de acceder a la seccin crtica como
darlo al salir de la misma

Introduccin a los RTOS - 2011 - FI-UBA

Como herramienta de sincronizacin

55

Vamos viendo que una tarea que debe esperar un


evento, lo nico que debe hacer es tomar un semforo
que no est disponible.
Luego la tarea o interrupcin que descubre o genera el
evento tan solo debe liberar el semforo
En ambas operaciones el scheduler verifica cul es la
tarea de mayor prioridad en condiciones de ejecutar,
bloqueando o desbloqueando segn el estado del
semforo y las prioridades de las tareas.
Este semforo particular que solo puede tomarse y darse
una vez, se llama semforo binario.

Introduccin a los RTOS - 2011 - FI-UBA

Como herramienta de sincronizacin

Dependiendo de la tarea, el comportamiento puede


ser:

Volver a bloquear luego de atender el evento. Para esto


se vuelve a tomar el semforo.

Continuar su ejecucin una vez dada la condicin que se


esperaba. En este caso NO se vuelve a tomar el
semforo.

56

Este es el caso tpico de los manejadores de eventos


aperidicos.
En este caso el dado del semforo se puede pensar como un
vale por una nica ejecucin, que luego es descartado.

Se da cuando hay una espera por nica vez, como ser la


inicializacin de un perifrico u otro recurso.
Introduccin a los RTOS - 2011 - FI-UBA

Acotando la espera de eventos

57

Puede ocurrir que el evento que estoy esperando no


llegue nunca. Segn la aplicacin esto puede ser
normal o un error.
Para los casos en que se quiera acotar la espera del
evento a un tiempo finito, se usa un tiempo mximo
de bloqueo o BlockTime.
Todas las funciones de FreeRTOS susceptibles de
bloquear a la tarea que las llama especifican un
tiempo de bloqueo.
En el caso de un bloqueo acotado, hay que verificar
el cdigo de retorno de la llamada para determinar si
se produjo el evento esperado o si expir el
blockTime.
Introduccin a los RTOS - 2011 - FI-UBA

Acotando la espera de eventos

Para esperar un tiempo finito, usar un blockTime no


cero.

Para esperar indefinidamente

portMAX_DELAY
(debe estar #define taskSuspend 1 en
FreeRTOSConfig.h)

Para que la operacin no bloquee

58

500 / portTICK_RATE_MS

usar 0 como blockTime


devuelve pdPASS / pdFALSE si el evento no ocurri
Se debe chequear siempre el valor de retorno de la
llamada, para verificar si ocurri el evento o si expir el
tiempo de bloqueo.
Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 12: Desbloquear una tarea


mediante un semforo

Para simplificar el cdigo, se usa una tarea peridica


como generadora de eventos.

59

Cada vez que de el semforo genera un pulso de


500ms en el LED2 del target board.

El manejo del evento consiste en enviar un mensaje


al entorno.

Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 12: Demostracin

60

Vemoslo funcionando

Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 12: Diagrama de ejecucin

61

Introduccin a los RTOS - 2011 - FI-UBA

API de semforos de FreeRTOS

vSemaphoreCreateBinary( xSemaphoreHandle
xSem )
xSemaphoreTake( xSemaphoreHandle xSem,
portTickType xBlockTime )
xSemaphoreGive( xSemaphoreHandle xSem )

NOTA: Estn implementadas como macros, no


como funciones => reciben los parmetros por valor,
no por referencia (ms adelante veremos por qu)

xSemaphoreHandle es un typedef, debe usarse este


tipo para trabajar con semforos.

62

Introduccin a los RTOS - 2011 - FI-UBA

Cuestiones de implementacin

Los semforos son objetos del kernel. Se toma memoria del sistema por
cada uno que se crea.

El scheduler revisa si debe cambiar el contexto de ejecucin cada vez que


se opera sobre un semforo => se emplea tiempo de CPU.

Si el manejo del evento es inmediato o diferido depender de las prioridades


de las tareas y el estado de las mismas.
En el mejor de los casos, darle ejecucin a una tarea bloqueada causa un
cambio de contexto. Este tiempo debe tenerse en cuenta a la hora de
analizar los requisitos temporales del sistema.

Deben ser vistos por todas las tareas del sistema => se crean en forma
global (y antes de iniciar el scheduler)

Usar con racionalidad

Los semforos son tiles siempre que hay dependencias entre tareas y
eventos o entre tareas solamente.

Nunca se debe tomar un semforo dentro de una interrupcin!

63

Introduccin a los RTOS - 2011 - FI-UBA

Checkpoint!

Los conceptos de
sincronizacin vistos hasta
ahora se repiten en los
prximos captulos.

Preguntas hasta ahora?

64

Introduccin a los RTOS - 2011 - FI-UBA

Parte 7
Manejo de colas para
intercambio de datos

Intercambio de datos entre las tareas

Vimos que las tareas son funciones de C, aplican las


mismas reglas de visibilidad.
Tambin vimos que cuando una tarea sale de
ejecucin dejan de ser vlidas las referencias a su
pila.
Me queda como mecanismo de intercambio el uso
de variables globales, pero se presentan dos
problemas

66

Cuidar el acceso al recurso


Tambin se presenta el caso de tareas aperidicas que
esperan una lectura / escritura de un dato para
procesarlo.

Surge entonces la necesidad de un mecanismo de


comunicacin entre tareas sincronizado.
Introduccin a los RTOS - 2011 - FI-UBA

Intercambio de datos entre las tareas

Para modularizar la implementacin de un sistema, se


suelen seprar los productores de datos de sus
consumidores.
Una tarea produce datos
Otra tarea los consume
Mientras no reciba datos, esta tarea queda
suspendida
Cuando los datos se producen ms rpido que lo que se
los consume (momentneamente), se necesita un
almacenamiento temporario de los mismos.

Si la velocidad media de produccin supera a la de consumo,


no se puede hacer nada.

A este esquema se lo llama patrn productor


67 consumidor.
Introduccin a los RTOS - 2011 - FI-UBA

Intercambio de datos entre las tareas

68

Una primera aproximacin al problema sera usar


semforos, aunque agregara una cierta complejidad
a la aplicacin.
Una solucin ms simple es usar colas (queues) del
RTOS
Son visibles por todas las tareas (deben ser creadas
en forma global)
Incorporan el mecanismo de sincronizacin
De la misma manera que un semforo, se puede
bloquear al leer / escribir datos de una cola.

Introduccin a los RTOS - 2011 - FI-UBA

Cmo se las crea?

Se crean mediante la funcin xQueueCreate()


Trabajan con cualquier tipo de datos, no solo los
nativos.
Los mensajes se pasan en la cola POR COPIA

69

Se debe dimensionar la cantidad de elementos de la cola


y el tamao de los mismos cuando se la crea. Estos
parmetros no pueden cambiarse luego.

Son objetos del OS, toman su memoria del heap del


sistema.
Se la debe crear antes de iniciar el scheduler.
Se la identifica mediante un xQueueHandle devuelto
por la llamada a xQueueCreate.
Introduccin a los RTOS - 2011 - FI-UBA

Operaciones disponibles con colas

Cualquier tarea puede leer y escribir en ellas.


Leer datos de una cola:

Escribir datos en una cola:

xQueueSendToBack(): La escritura normal a una cola.


xQueueSendToFront(): Pone el mensaje en la posicin de
salida. Sera como apilar el dato.

Consultar los mensajes disponibles en las colas.

70

xQueueReceive(): Quita el dato de la cola.


xQueuePeek(): No quita el dato de la cola.

uxQueMessagesWaiting().

Introduccin a los RTOS - 2011 - FI-UBA

Operaciones disponibles con colas

Las operaciones de cola pueden bloquear.

Por esto, se les puede asignar un blockTime igual


que a un semforo. En este caso tambin debe
chequearse el valor de retorno de la operacin.
Con este detalle se puede ver ahora que un
semforo binario no es ms que una cola de un solo
elemento.

71

Intentar leer de una cola vaca


Intenar escribir a una cola llena

Tomar el semaforo es equivalente a escribir en la cola.


Dar el semforo es equivalente a leer de la misma.
Por esta razn es que est implementado con macros.
Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 10: Lectura sincronizada

Presenta el caso tpico de un driver de salida.


Una tarea asociada a un perifrico de salida
espera que el sistema produzca datos para
enviar al mismo.
Mientras no los haya, se mantiene bloqueada.

72

En este caso no tiene sentido especificar un tiempo de


bloqueo.

Este caso particular da prioridad al procesamiento


de los datos => la cola nunca va a tener ms de un
dato almacenado.
Cabe analizar el caso de cola llena.
Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo10: Tarea consumidora de datos


static void vReceiverTask( void *pvParameters )
{
// Seccion de inicializacion
long lReceivedValue;
portBASE_TYPE xStatus;
const portTickType xTicksToWait = 100 / portTICK_RATE_MS;
// Cuerpo de la tarea
for( ;; )
{
xQueueReceive( xQueue, &lReceivedValue, xTicksToWait );
vPrintStringAndNumber( "Received = ", lReceivedValue );
}
}

73

Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo10: Tarea productora de datos


static void vSenderTask( void *pvParameters )
{
// Seccion de incializacion
long lValueToSend;
portBASE_TYPE xStatus;

lValueToSend = ( long ) pvParameters;


for( ;; )
// Cuerpo de la tarea
{
xQueueSendToBack( xQueue, &lValueToSend, 0 );
taskYIELD(); // Cedo el resto de mi timeslice

}
}
74

Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo10: Funcion main()


xQueueHandle xQueue; // Variable para referenciar a la cola
int main( void )
{
xQueue = xQueueCreate( 5, sizeof( long ) );
xTaskCreate( vSenderTask, "Sender1", 240, ( void * ) 100, 1, NULL );
xTaskCreate( vSenderTask, "Sender2", 240, ( void * ) 200, 1, NULL );
xTaskCreate( vReceiverTask, "Receiver", 240, NULL, 2, NULL );
vTaskStartScheduler();
for( ;; );
return 0;
}

75

Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 10: Demostracin

76

Vemoslo funcionando

Introduccin a los RTOS - 2011 - FI-UBA

Ejemplo 10: Diagrama de ejecucin

77

Introduccin a los RTOS - 2011 - FI-UBA

Cuestiones de diseo
La cantidad de elementos de la cola debe contemplar el
peor caso de uso posible.
Si los elementos son muy grandes es preferible usar la
cola para enviar datos por referencia y no por copia. En
este caso debe usarse memoria global. Y debe
preveerse que los datos apuntados se mantengan
vlidos hasta que sean consumidos.
Recordar que las operaciones de cola pueden llevar un
tiempo de bloqueo, en este caso debe chequearse el
valor de retorno de la llamada.
Al analizar las prioridades de las tareas que emplearn la
cola, contemplar los casos de cola llena, cola vaca y si
el envo los datos encolados debe interrumpir a la
dealos
mismos.
78 generacin
Introduccin
los RTOS
- 2011 - FI-UBA

Parte 8
Gestin de recursos

Problemticas de la concurrencia

Cuando varios procesos ejecutan simultneamente,


puede ocurrir que quieran usar un mismo recurso al
mismo tiempo. En realidad, el acceso no es
simultneo sino que ocurre un cambio de contexto
entre que el primer proceso empieza y termina de
modificar el recurso.

Dos tareas quieren escribir a una UART a la vez, los


mensajes se entremezclan.
Un proceso modifica una variable de configuracin
mientras otro la lee, no se sabe en qu estado va a
quedar el recurso.
Operaciones de read-modify-write ( x 1= (1<<7));

Estos problemas se evitan serializando el acceso al


80
Introduccin a los RTOS - 2011 - FI-UBA
recurso.

Exclusin mutua

81

A este serializado de procesos se le llama exclusin


mutua (mutex).
FreeRTOS brinda varias alternativas para
implementar exclusin mutua.

Introduccin a los RTOS - 2011 - FI-UBA

Alternativa 1: Deshabilitar interrupciones

Si se deshabilitan las interrupciones, no puede


ocurrir ningn cambio de contexto preemptive.

82

No hay manejo de SysTick (cuando expira un timeslice)


No se ejecuta ningn cdigo que pueda iniciar un cambio
de contexto.

De este modo, el sistema se vuelve


momentneamente cooperativo y puedo terminar la
operacin crtica.
Adems de estar protegido contra otras tareas,
estoy protegido contra las funciones de interrupcin.
Pero en el interim el sistema pierde la capacidad de
responder a eventos, debe usarse con cuidado.
Introduccin a los RTOS - 2011 - FI-UBA

Alternativa 1: Deshabilitar interrupciones

83

FreeRTOS provee las macros


taskENTER_CRITICAL() y taskEXIT_CRITICAL()
Su uso debe estar apareado (un exit por cada
enter).
Se anidan correctamente. Esto significa que si se
producen N taskENTER_CRITICAL(), el sistema no
rehabilita las interrupciones hasta contar N
taskEXIT_CRITICAL().
Si bien es la operacin ms rpida des/hacer, es la
que ms perturba al sistema, debe reservarse para
operaciones muy breves.
Introduccin a los RTOS - 2011 - FI-UBA

Alternativa 2: Supender el scheduler

Llamando a la funcion vTaskSuspendAll() se


suspenden los cambios de contexto mientras que se
mantienen habilitadas las interrupciones.

Se debe poner el correspondiente xTaskResumeAll()


para reanudar al scheduler.

84

El sistema sigue registrando los eventos externos.


La operacin atmica se lleva a cabo sin problemas.

Estas operaciones se anidan correctamente.

Este recurso debe usarse con cuidado, ya que todos


los eventos del sistema que se pierdan se atendern
al momento de la reanudacin (semforos, colas,
etc).
Introduccin a los RTOS - 2011 - FI-UBA

Alternativa 3: Subir la prioridad de la


tarea

FreeRTOS me permite modificar la prioridad de las


tareas en tiempo de ejecucin.
Se puede aprovechar esto para modificar la
prioridad de la tarea que est entrando a la seccin
crtica.
De este modo las interrupciones quedan habilitadas
y puedo definir un umbral de tareas que no van a
interrumpir a la tarea crtica.

85

unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle


pxTask );
void vTaskPrioritySet( xTaskHandle pxTask, unsigned
portBASE_TYPE uxNewPriority );
xTaskHandle es un parmetro pasado a xTaskCreate, me permite
hacer
referencia
a una
tarea.
Introduccin
a los
RTOS
- 2011 - FI-UBA

Alternativa 4: Usar mutex del sistema

86

Un mutex es una estructura del sistema muy similar a un


semforo binario.
La diferencia es conceptual. Cuando varias tareas
quieren usar un recurso, se guarda al mismo con un
mutex. Puede pensrselo como una llave de acceso al
recurso.
La nica tarea que puede accederlo es la que tiene
tomado el mutex.
Es imprescindible que al terminar de usar el recurso
devuelva el mutex.
Recordar que el uso del mutex es una convencin. El OS
no impide, a ninguna tarea acceder al recurso por las
malas.
Introduccin a los RTOS - 2011 - FI-UBA

Uso de mutex

mutex = xSemaphoreCreateMutex();
xSemaphoreTake(mutex, portMAX_DELAY);

consoleprint(Hola Mundo!);

xSemaphoreGive(mutex);

Esta es una implementacion alternativa de la funcion


vPrintString()
Un mutex resulta la opcin ms sencilla de analizar,
solo podra generar demoras a otras tareas que
estuvieran compitiendo por elrecurso.

87

Introduccin a los RTOS - 2011 - FI-UBA

Alternativa 5: Delegar el manejo del


recurso a una tarea driver

Como se ha visto anteriormente, si varias tareas


necesitan compartir el acceso a un nico recurso, se
puede escribir un driver de este.
Esto traslada la complejidad del caso

Permite un manejo flexible del recurso.

88

Las tareas se vuelven ms simples


Se agrega el trabajo de escribir el driver
Un LCD alfanumrico con varias tareas enviando
mensajes.
Una nica UART compartida por varias tareas, se
comportara como un router ethernet.
Introduccin a los RTOS - 2011 - FI-UBA

Recursos limitados en cantidad

89

Un servidor web puede servir mltiples pginas web


concurrentemente.
Esta concurrencia est limitada por la cantidad de tareas que el
sistema puede crear.
Existe para estos casos un tipo de semforo llamado counting
(contador) que puede darse y tomarse mltiples veces.
Se lo crea con un valor inicial igual a la cantidad de recursos
disponibles.
Su cuenta disminuye una vez cada vez que se lo toma y aumenta
una vez cuando se lo da.
Si la cuenta llega a 0, la tarea que no puede obtener un recurso
pasa al estado Blocked.

Introduccin a los RTOS - 2011 - FI-UBA

Conteo de eventos

Otro uso de los semforos contadores es el de


contar eventos.
Su uso es el dual del anterior:

90

Se lo crea con un valor inicial 0


Se lo da una vez por cada ocurrencia del evento
Se lo descuenta una vez por cada vez que se lo maneja
El manejador del evento pasa al estado blocked cuando
el semforo vuelve a 0 (no quedan ms eventos por
manejar)

Introduccin a los RTOS - 2011 - FI-UBA

API de FreeRTOS para semforos

Los mutex y ambos tipos de semforos se manejan


con las mismas funciones give y take.
Tienen diferentes funciones para ser creados:

91

vSemaphoreCreateBinary( xSemaphoreHandle
xSemaphore )
xSemaphoreHandle
xSemaphoreCreateCounting(uxMaxCount, uxInitialCount
)
xSemaphoreHandle xSemaphoreCreateMutex( void )

Introduccin a los RTOS - 2011 - FI-UBA

Parte 9
Segunda prctica con FreeRTOS

Tarea opcional para el hogar

93

Para todos los ejercicios se sugiere manejar los


perifricos que vayan a ser usados en el proyecto.
El sistema debe pasar en la tarea idle todo el tiempo
posible.
Ejercicio 1: Escribir una tarea que enve un mensaje
al IDE cuando otra tarea registra una pulsacin de
ms de 500ms.
Ejercicio 2: Contar pulsaciones de un botn y enviar
el valor de cuenta a un perif. de salida mediante una
cola.
Ejercicio 3: Reimplementar la funcin vPrintString
usando mutex.
Introduccin a los RTOS - 2011 - FI-UBA

Parte 10
Algunos problemas de los mutex

Recaudos a tomar al usar mutex

Usar mutex como mecanismo de exclusin mutua es


la alternativa ms sencilla y que menos complica el
anlisis del sistema.
Sin embargo no hay que perder de vista que cuando
una tarea toma un mutex para acceder a un recurso
se modifican las reglas de ejecucin, recordar la
tarea mayor prioridad en condiciones de ejecutarse
Se deben preveer dos situaciones que pueden
ocurrir:

95

La inversin de prioridades
El deadlock
Introduccin a los RTOS - 2011 - FI-UBA

Inversin de prioridades

Pongamos un ejemplo:

96

Una tarea peridica de alta prioridad est bloqueada


esperando su tiempo de ejecutar.
Mientras, una tarea de baja prioridad baja toma un mutex
para acceder a un recurso protegido durante un tiempo
prolongado.
La tarea de alta prioridad pasa al estado ready al expirar
su tiempo de bloqueo e intenta acceder al recurso.

En este caso, la tarea de alta prioridad debe esperar


que se libere el mutex. En la prctica, est
esperando a una tarea de baja prioridad, por esto se
dice que se invirtieron las prioridades del sistema.
Introduccin a los RTOS - 2011 - FI-UBA

Inversin de prioridades

Ahora imaginemos que una tercer tarea de prioridad


intermedia pasa al estado Running durante otro
tiempo prolongado.
La tarea de alta prioridad est esperando a una
tarea de baja prioridad que no va a liberar el mutex
ya que no recibe tiempo de ejecucin para terminar
de usar el recurso!
Para evitar esto los mutex de FreeRTOS incorporan
un mecanismo llamado priority inheritance.

97

Cuando ocurre la inversin de prioridades, el scheduler


eleva la prioridad de la tarea que tiene el mutex al nivel
de la tarea de mayor prioridad que est intentando
tomarlo.
Introduccin a los RTOS - 2011 - FI-UBA

Priority inheritance

98

Este mecanismo est incorporado en los mutex de


FreeRTOS, funciona siempre que se los usa.
Esta es la nica excepcin al algoritmo Fixed priority
preemptive scheduling.
No soluciona la inversin de prioridades, pero acota
la duracin de la misma, lo que simplifica el anlisis
de tiempos del sistema.

Introduccin a los RTOS - 2011 - FI-UBA

Como se evita?

99

Se debe tomar en cuenta al disear el sistema y


evitar esta situacin.
Es conveniente delegar el manejo del recurso en un
driver del mismo implementado con una cola, de
modo que ninguna tarea se apropie del recurso.
Para detectarlo, se manifiesta como una tarea que
se ejecuta ms tarde de lo previsto (pudiendo fallar
su plazo) o que no ejecuta en absoluto.

Introduccin a los RTOS - 2011 - FI-UBA

Deadlock

El deadlock ocurre cuando dos tareas estn


bloqueadas esperando un recurso que tiene la otra.

Ms bien, cuando bloquean al tomar un mutex retenido


por la otra tarea.

Ninguna de las dos libera el mutex ya que est


bloqueada esperando el otro.
Finalmente, ninguna de las dos tareas recibe tiempo
de ejecucin.
Un ejemplo sencillo es el tpico intercambio de
prisioneros en las pelculas, donde ninguno de los
protagonistas quiere liberar su recurso hasta no
recibir el del otro.

100

Introduccin a los RTOS - 2011 - FI-UBA

Como se evita?

El deadlock es un problema de diseo, no de


implementacin.
Se debe prever su posible ocurrencia al disear el
sistema y tomar recaudos para que no ocurra.
Puede darse para el caso de N tareas con una
cadena de dependencias, no solo dos.

En
http://es.wikipedia.org/wiki/Problema_de_la_cena_de_los_filosofo
s se puede ver el problema en detalle y varias soluciones al
mismo.

Para detectar el deadlock, tener presente que no se


bloquea el sistema entero sino solo las tareas que lo
causan, el resto se ejecuta con normalidad.

101

Introduccin a los RTOS - 2011 - FI-UBA

Parte 11
Interrupciones y FreeRTOS

Tratamiento particular de las interrupciones

Una ISR siempre debe ejecutar por completo.


En el caso de un sistema multitarea, no debe
forzarse un cambio de contexto dentro de una ISR.
Para esto, todas las funciones de FreeRTOS que
podran generar un cambio de contexto tienen una
variante ISR-safe, que es el mismo nombre de la
funcin con el sufijo FromISR.

103

xSemaphoreGiveFromISR
xQueueSendFromISR
xQueueReceiveFromISR

Introduccin a los RTOS - 2011 - FI-UBA

Operaciones no permitidas en una ISR

Las operaciones cuyo objetivo es justamente


bloquear a la tarea no deben usarse en una ISR y
no tienen una variante FromISR.

104

No hay xSemaphoreTakeFromISR
No hay xDelayFromISR
No hay taskYIELDFromISR

Introduccin a los RTOS - 2011 - FI-UBA

Cambios de contexto sincronizados a una ISR

Las funciones FromISR reciben un parmetro adicional


por referencia en el cual sealizan si debe hacerse un
cambio de contexto.
xSemaphoreGiveFromISR( xSemaphoreHandle
Semaphore, signed portBASE_TYPE
pxHigherPriorityTaskWoken );
El fin de la ISR se hace llamando a la macro
portEND_SWITCHING_ISR() con este valor.
NOTA: Esta macro es la versin ISR-safe de la macro
taskYIELD. El nombre vara segn el port de FreeRTOS
usado.

105

Introduccin a los RTOS - 2011 - FI-UBA

Cambios de contexto sincronizados a una ISR

De este modo el scheduler sabe si debe permanecer en


el mismo contexto o volver de la interrupcin a una tarea
distinta.

En este ltimo caso, se maneja el evento en una


tarea sincronizada a la interrupcin.

Recordar que esto agrega un tiempo extra al tiempo de


respuesta al evento.

En sistemas sin RTOS se suele hacer de la misma


manera, donde las ISR tan solo modifican algn flag
global y el programa principal es el encargado de
manejar el evento.

106

Introduccin a los RTOS - 2011 - FI-UBA

Parte 12
Tercera prctica con FreeRTOS

Evaluacin de proyectos finales

Los que tienen un proyecto en mente, discutmoslo


y empecemos a bosquejar una implementacin.
Para los que no, a continuacin recordamos las
actividades de las dos primeras clases y agregamos
algunas ms.
A trabajar!

108

Introduccin a los RTOS - 2011 - FI-UBA

Tarea opcional para el hogar

Tarea 1: Destellar un led a una frecuencia


determinada
Tarea 2: Seguir el estado de un pulsador con un led,
incluyendo el anti-rebote elctrico
Tarea 3: Contar pulsaciones de un boton y luego de
un segundo sin pulsaciones destellar un led esa
misma cantidad de veces
Se sugiere implementarlas usando el driver de GPIO
provisto por NXP

109

Introduccin a los RTOS - 2011 - FI-UBA

Tarea opcional para el hogar

Para todos los ejercicios se sugiere manejar los


perifricos que vayan a ser usados en el proyecto.
El sistema debe pasar en la tarea idle todo el tiempo
posible.
Ejercicio 1: Escribir una tarea que enve un mensaje
al IDE cuando otra tarea registra una pulsacin de
ms de 500ms.
Ejercicio 2: Contar pulsaciones de un botn y enviar
el valor de cuenta a un perif. de salida mediante una
cola.
Ejercicio 3: Reimplementar la funcin vPrintString
usando mutex.

110

Introduccin a los RTOS - 2011 - FI-UBA

Tarea opcional para el hogar

Ejercicio 4: Atender un evento aperidico dando un


semforo en una ISR.
Ejercicio 5: Implementar un driver de un perifrico de
salida. El dato se genera en una ISR. Debe implementar
las siguientes funciones
void InicializarPeriferico (void);
void Escribir (portBASE_TYPE dato);
La ISR puede ser generada en un pulsador, un fin de
conversin de un ADC, o pueden usarse las macros del
ejemplo 12 desde una tarea peridica.
mainCLEAR_INTERRUPT();
mainTRIGGER_INTERRUPT();

111

Introduccin a los RTOS - 2011 - FI-UBA

Parte 11
Funcionalidad en el estado Idle y
en el Systick handler

Funcionalidad en el estado Idle

Cierta funcionalidad de la aplicacin puede ser


necesario implementarla cuando el sistema est
ocioso

Poner al CPU en estado de bajo consumo


Medir el tiempo disponible del sistema para agregarle
ms tareas
Funcionalidad especfica de la aplicacin

Para esto FreeRTOS llama constantemente a una


misma funcin cuando est ocioso. Este tipo de
funciones se llaman hooks (ganchos) ya que me
permiten enganchar funcionalidad en este punto.
El hook que se llama cuando la Application est Idle
vApplicationIdleHook.
113se llama
Introduccin a los RTOS - 2011 - FI-UBA

Tarea Idle (representacin)


void prvIdleTask( void *pvParameters ){
for( ;; ) {
prvCheckTasksWaitingTermination(); // Garbage-collector
#if ( configUSE_PREEMPTION == 0 ) {

taskYIELD(); // En modo cooperativo ninguna tarea preemptea a la


tarea Idle
} #endif

#if ( configUSE_IDLE_HOOK == 1 ) {
vApplicationIdleHook(); // Hook
} #endif
}
}
114

Introduccin a los RTOS - 2011 - FI-UBA

Cuestiones de implementacin

La tarea Idle NO DEBE BLOQUEAR NI


SUSPENDER

Si lo hiciera no quedara ninguna tarea en estado


Running, y siempre debe haber una.

Para usarla, hay que #define


configUSE_IDLE_HOOK 1
La funcin que implemente el hook debe tener
exactamente el siguiente prototipo

void vApplicationIdleHook (void);

Si se usa vTaskDelete para eliminar tareas, los


recursos de la misma se recuperan en la tarea Idle,
por esta razn no debe acapararse la tarea Idle con
115el Application
Introduccin a Hook.
los RTOS - 2011 - FI-UBA

Uso del Systick timer

Del mismo modo que hay un Application Idle hook,


hay un Systick timer hook.
Se llama dentro de una ISR, aplican las reglas
habituales.

Para usarla, hay que #define


configUSE_TICK_HOOK 1
La funcin que implemente el hook debe tener
exactamente el siguiente prototipo

116

Mantenerla breve
No bloquear
Usar funciones FromISR

void vApplicationTickHook (void);

Introduccin
a los RTOS
- 2011 -transcurrido
FI-UBA
Es til
para contar
tiempo
sin dedicarle

Llamada al TickHook
void vTaskIncrementTick( void )
{ // Esta funcin se llama dentro de una seccin crtica en el Systick
Handler
if( uxSchedulerSuspended == pdFALSE ) {
++xTickCount;
prvCheckDelayedTasks(); // Chequeo de tareas en vTaskDelay
}

#if ( configUSE_TICK_HOOK == 1 )
{
vApplicationTickHook(); // Hook
}
#endif
}
117

Introduccin a los RTOS - 2011 - FI-UBA

Parte 12
Cmo encarar un diseo con
RTOS

Analizar el sistema a implementar

Lo primero es tener en claro cules son las entradas


del sistema, sus respectivas respuestas y los
compromisos temporales asociados.
Amn de las prioridades, de este anlisis surgirn
los tiempos de bloqueo de las operaciones de
sincronismo.

119

Introduccin a los RTOS - 2011 - FI-UBA

Identificar reas independientes

Buscar reas del programa que se puedan


programar independientemente de las dems.

Estas reas son candidatas a tener su propia tarea.


Tener presente que si una tarea est completamente
anidada dentro de otra, puede ser una simple funcin y
no necesita una tarea.
No todo es una tarea!

Las tareas deben tener poca dependencia entre


ellas, una relacin complicada entre ellas es sntoma
de un mal diseo y complica el posterior
mantenimiento del software.

120

Introduccin a los RTOS - 2011 - FI-UBA

Considerar un patrn MVC

MVC es un patrn de diseo usado mucho en web.


Modelo Vistas Controladores.

El modelo es el estado del sistema.


Las vistas son las representaciones del mismo que ve el
usuario.
Los controladores son funciones que modifican el estado
del modelo.

Ayuda a mantener independientes las tareas cuando


hay varias entradas y salidas dependientes del
contexto de la aplicacin:

121

Las entradas envan mensajes al modelo,


Las salidas reciben mensajes del modelo.
Introduccin a los RTOS - 2011 - FI-UBA

Considerar un patrn MVC

El modelo puede ser tan simple como una estructura


en memoria compartida.
Ayuda a evitar que muchas tareas manden
mensajes a muchas otras.

122

Introduccin a los RTOS - 2011 - FI-UBA

Atender a las tareas reentrantes

Algunas tareas se instancias varias veces.


Se debe tener cuidado con el uso que hacen de
recursos compartidos.

123

No se deben usar variables globales, ya que todas las


tareas ven la misma copia.
Si usan un mismo recurso, se lo debe tratar con mutex
como si fueran tareas distintas.

Introduccin a los RTOS - 2011 - FI-UBA

Asignar prioridades a las tareas

Se debe tener en claro qu eventos tienen requisitos


temporales estrictos y cules relajados.
Ayuda pensar en la superposicin de todos los
eventos y determinar cuales deben ser atendidos
primero.
Considerar el caso de semforos y colas

Cuando se libera un semforo, es ms importante la


atencin del evento o la tarea que lo sealiza tiene
todava trabajo por hacer?
Cuando un productor escribe datos en una cola, el
consumidor debe pasar a ejecucin en ese momento o
ms tarde, cuando el productor ceda el CPU?

Cuidado con el starvation!

124

Introduccin a los RTOS - 2011 - FI-UBA

Buscar IPC y sincronismos entre las


tareas

Algunas tareas esperarn eventos externos, otras


esperarn mensajes de otras tareas.
De este anlisis surgen los semforos y colas a
usar.

125

Atento a los valores iniciales de los semforos binarios y


contadores.

Introduccin a los RTOS - 2011 - FI-UBA

Dimensionar las colas de mensajes

Segn las prioridades de los productores y


consumidores de las colas, estas pueden
mantenerse ms bien llenas o vacas. En base a
esto debe determinar la cantidad de elementos a
almacenar en ellas.

126

Introduccin a los RTOS - 2011 - FI-UBA

Identificar los recursos compartidos

Las tareas tienen necesariamente algunos puntos


de contacto. Estos se deben proteger con mutex.

P. ej: Una tarea lee una variable de configuracin y otra


tarea la modifica segn una entrada del sistema. No se
debe corromper el acceso!

Estos recursos pueden ser perifricos del CPU o


posiciones de memoria.
Atento a la inversin de prioridades cuando hay
mutex en juego y tareas de distintas prioridades!

127

El tiempo durante el que se retiene el mutex es crucial


para determinar si habr o no problemas.

Introduccin a los RTOS - 2011 - FI-UBA

Identificar operaciones atmicas

Algunas tareas no pueden ser interrumpidas


Considerar quin puede interrumpir la tarea para
determinar la mejor estrategia de proteccin.

128

Si es slo una tarea, tal vez alcanza con suspenderla o


bajarle la prioridad.
Si cualquier cambio de contexto es problemtico se
puede suspender el scheduler o las interrupciones.

Introduccin a los RTOS - 2011 - FI-UBA

Disear los drivers que hagan falta

Es importante tener clara la funcionalidad requerida


del dispositivo en cuestin.
Un driver puede ser algo tan sencillo como una cola
de entrada y una de salida.
Si una cola es demasiado lenta para el caso, se
puede usar memoria compartida (variables globales
en el caso de FreeRTOS) y semforos para
sealizar los eventos.

129

Introduccin a los RTOS - 2011 - FI-UBA

Implementacin y verificacin

Proceder a implementar las tareas de a una,


verificando que se cumplan los requisitos
temporales.
Se recomienda tener un buen modelo del sistema
antes de proceder a esto.

130

Introduccin a los RTOS - 2011 - FI-UBA

Parte 13
Asignacin dinmica de memoria

Uso de memoria dinmica

El OS asigna memoria dinmica para gestionar sus


objetos cuando los crea:

Tareas
Semaforos / Mutex
Colas

Esta memoria la obtiene del heap definido en


FreeRTOSConfig.h, mediante llamadas similares a
Malloc y Free.
Por esta razn durante el desarrollo debe verificarse
que las llamadas que crean estos objetos no
devuelvan un error.

132

Introduccin a los RTOS - 2011 - FI-UBA

Problema de Malloc y el determinismo

Las aplicaciones de tiempo real no pueden permitirse el


comportamiento del Malloc estndar
Tiempo de ejecucin variable
Puede o no encontrar el bloque de memoria solicitado
Implementacin muy abultada para la memoria disponible
Por esta razn, FreeRTOS separa la asignacin de memoria del
resto del kernel y la ubica en la capa portable, se puede modificar el
algoritmo de manejo de memoria en cada aplicacin.
FreeRTOS proporciona tres algoritmos de manejo de memoria, el
programador puede elegir uno o escribir uno propio.

Heap_1.C, Heap_2.C. Heap_3.C


Debe haber uno solo de estos (o uno propio) en la carpeta portable

Las llamadas a Malloc y Free se reemplazan con pvPortMalloc y


pvPortFree.

133

Introduccin a los RTOS - 2011 - FI-UBA

Heap_1.C

No contempla la liberacin de memoria - no


implementa pvPortFree()
La memoria se asigna secuencialmente hasta que
se acaba
El total disponible para el kernel est definido en
configTOTAL_HEAP_SIZE
Es el ms simple de usar cuando la memoria
disponible es suficiente para todos los objetos que
se van a crear

134

El tiempo de ejecucin es determinista


La memoria no se fragmenta
Introduccin a los RTOS - 2011 - FI-UBA

Heap_2.C

Contempla la liberacin de memoria, implementa pvPortFree()


Usa un algoritmo best-fit.
Recorre todos los bloques disponibles de memoria y
devuelve el que ms se ajusta a lo pedido - No es
determinista!
El sobrante del bloque asignado queda marcado como un
nuevo bloque.
La memoria se fragmenta con las des/asignaciones.
El total disponible para el kernel est definido en
configTOTAL_HEAP_SIZE.
Es til cuando se crean y destruyen distintas tareas pero con
el mismo tamao de stack. De este modo la memoria liberada
se vuelve a ocupar sin desperdicios.

135

Introduccin a los RTOS - 2011 - FI-UBA

Heap_3.C

Usa la implementacin estndar de Malloc y Free


No es determinista
Encierra ambas operaciones en secciones crticas
para hacerlo thread-safe.
No usa el tamao de heap definido por
configTOTAL_HEAP_SIZE, si no el rea de memoria
definida para esto en el linker script.

136

Introduccin a los RTOS - 2011 - FI-UBA

Cul elegir?

Si la totalidad de los objetos de la aplicacin caben en la


memoria disponible, Heap_1 es el ms adecuado.
Si se necesitan ms tareas corriendo simultneamente de las
que se pueden albergar, se puede crear una tarea cuando se
la necesita y eliminarla luego de su uso. En este caso se
necesita al menos Heap_2.
Para optimizar el uso de memoria, las tareas a reciclar
debieran tener el mismo tamao de stack.
Si se van a reciclar tareas con distinto tamao de stack, se
puede usar Heap_3 o escribir un handler propio.
Pero a estas alturas el sistema ya se vuelve complicado de
analizar y predecir, sera mejor revisar el diseo para utilizar
Heap_2 o definir un algoritmo a medida e implementar un
manejador propio.

137

Introduccin a los RTOS - 2011 - FI-UBA

Cmo dimensionar el Heap?

Si se usa Heap_1 o Heap_2, la funcin


xPortGetFreeHeapSize (void) devuelve la memoria
disponible en el heap
Llamarla luego de que se crearon todos los objetos
del sistema me permite saber en cunto disminuir su
tamao sin hacer un anlisis minucioso.

138

Introduccin a los RTOS - 2011 - FI-UBA

Parte 14
Verificacin del uso de las pilas

Proteccin contra el desborde de pila

La pila de una tarea no debe desbordarse en ningun


momento
El parmetro de medicin es qu tan alto lleg el
stack pointer. A este valor se le llama high-water
mark.
FreeRTOS provee una funcin para esto llamada
uxTaskGetStackHighWaterMark (xTaskHandle
tarea);
Devuelve el mnimo disponible que hubo de stack
desde que la tarea empez a ejecutar
Se la puede usar para dimensionar el stack de la
tarea

140

Introduccin a los RTOS - 2011 - FI-UBA

Chequeos en tiempo de ejecucin

El momento ms delicado para la pila es cuando la


tarea sale de ejecucin. Todo el contexto se vuelca
en su pila.

Se puede configurar el kernel para que en ese


momento verifique si la pila desbord.

Por este motivo est definida la constante


configMINIMAL_STACK_SIZE, las tareas no deben tener
una pila menor a este tamao.

Estos chequeos aumentan el tiempo del cambio de


contexto!

Se puede implementar un hook para ayudar a


depurar el problema.

141

void vApplicationStackOverflowHook ()
Introduccin a los RTOS - 2011 - FI-UBA

Dos mtodos

Mtodo 1: Verifica que el stack pointer est dentro de la pila de la


tarea al volcarle el contexto.
Ejecuta rpido
Si la pila desborda durante la ejecucin pero vuelve a un nivel
permitido antes de salir de contexto, no lo detecta.
Mtodo 2: Verifica que los ltimos 20 bytes de la pila mantengan su
valor inicial
Cuando se crea una pila se le da un valor conocido
Es ms lento pero ciertamente ms seguro
Slo fallara en el caso de que el desborde de la pila tenga el
mismo patrn que el valor inicial.
Se elige con #define configCHECK_FOR_STACK_OVERFLOW 1 o
2
Definirlo en 0 deshabilita los chequeos

142

Introduccin a los RTOS - 2011 - FI-UBA

Depuracin

Cuando se produce un desborde de pila el error es


irrecuperable
Lo habitual es atrapar la ejecucin en un lazo infinito
y verificar con el entorno de depuracin qu es lo
fall.

143

Se puede hacer un trace de las instrucciones ejecutadas


o de las funciones llamadas, para determinar el flujo de
ejecucin que llev a esa falla.

Introduccin a los RTOS - 2011 - FI-UBA

Parte 15
Las 5 cosas que no entraron en
el curso

1. Otros problemas de la concurrencia

Reentrancia

Si una tarea se va a instanciar varias veces, no debe


guardar sus datos en variables globales, ya que todas las
instancias ven la misma variable y podran corromperla.

Las variables locales estn en el stack de cada instancia.

A la condicin de no usar variables globales y permitir la


reentrancia se la llama thread-safe.

Carreras crticas (race conditions)

145

Si varias tareas usan una misma variable (p. ej un


contador global), el acceso al mismo debe ser mutex.
Un acceso no mutex a un contador puede hacer que el
cdigo en cuestin ejecute ms o menos veces que lo
que debera.
Introduccin a los RTOS - 2011 - FI-UBA

2. Coroutines

Ver http://www.freertos.org/croutine.html
Las CR son como los threads de un sistema tipo
UNIX.

Una tarea puede tener varias CR


Tienen sus propias prioridades que aplican solo entre las
CR de una misma tarea.
Comparten el stack de la tarea que las contiene.

Son un recurso a tener en cuenta en procesadores


con muy poca memoria de datos.
Se puede implementar un sistema con solo CR, solo
tareas o una mezcla de ambas

146

Introduccin a los RTOS - 2011 - FI-UBA

3. Trazado de la ejecucin

Ver http://www.freertos.org/rtos-trace-macros.html
A lo largo del cdigo hay numerosas macros en
puntos de inters de la aplicacin

traceQUEUE_SEND_FROM_ISR
traceTASK_SWITCHED_IN
traceTASK_SWITCHED_OUT

Por defecto estn definidas sin cuerpo, de modo que


no se agrega overhead a la ejecucin
Se pueden definir con el comportamiento deseado
para analizar la ejecucin de la aplicacin

147

Por ej. Medir el tiempo entre dar un semforo y la


atencin del evento
Introduccin a los RTOS - 2011 - FI-UBA

4. Estadsticas en tiempo de ejecucin

Ver
http://www.freertos.org/rt
os-run-time-stats.html
La API tiene varias
funciones para generar
estos datos
Las demos para
plataformas con interfaz
ethernet contienen una
tarea para mostrar esta
informacin

148

Introduccin a los RTOS - 2011 - FI-UBA

5. Otros algoritmos de scheduling

http://en.wikipedia.org/wiki/Ratemonotonic_scheduling

Es una manera de asignar las prioridades a las tareas.


Consiste en asignarlas de modo inversamente proporcional al
tiempo de ejecucin de la tarea.
Busca maximiza el throughput de tareas ejecutadas
correctamente.

http://en.wikipedia.org/wiki/Earliest_deadline_first_sc
heduling

149

Asigna mayor prioridad a las tareas ms prximas a fallar su


deadline
No es fixed-priority, el scheduler modifica la prioridad de las tareas
dinmicamente para garantizar que ninguna fracase
Si el sistema est sobrecargado es difcil de predecir qu tareas
fallarn
su deadline.
Introduccin
a los RTOS - 2011 - FI-UBA

Fin de la 1era clase


Se sugiere la realizacin de las
actividades propuestas.
Preguntas?

150

Introduccin a los RTOS - 2011 - FI-UBA

Fin de la 2da clase

Se sugiere la realizacin
de las actividades
propuestas.
Preguntas?

Las prximas dos clases


analizaremos los proyectos
finales.
Se sugiere que traigan las
alternativas que estn
manejando para analizar
que proyectos es
conveniente implementar
151
a los RTOS - 2011 - FI-UBA
con Introduccin
FreeRTOS.

Fin de la 3ra clase

Se sugiere la realizacin
de las actividades
propuestas.
Sera bueno que vayan
definiendo los proyectos!
Preguntas?

152

Introduccin a los RTOS - 2011 - FI-UBA

Fin de la exposicin

Preguntas?
A trabajar en los
proyectos!

153

Introduccin a los RTOS - 2011 - FI-UBA