Aplicaciones de la Ingeniería Electrónica II

Anuncio
Sistemas Empotrados de Tiempo Real
Máster en Ingeniería Electrónica
Práctica de laboratorio: uCOS-II
Nombre
Curso académico 2011/12
DNI
(1) Preparación (10 min.)
-
Descomprime el archivo SETR_UCOS2.zip. Dentro del directorio LAB, haz
doble click sobre el archivo LAB.SLN para abrir la “solución” en Visual Studio.
Deberías ver la siguiente pantalla:
-
Este fichero contiene los proyectos LAB y UCOS_II. UCOS_II, a partir de los
correspondientes archivos fuente, genera la librería UCOS_II.LIB. Esta librería,
una vez generada, es enlazada con la aplicación al compilar el proyecto LAB.
o Para compilar uC/OS-II, sitúa el cursor del ratón sobre el icono del
proyecto UCOS_II, despliega el menú asociado al botón derecho del
ratón y selecciona ‘Build’ o ‘Rebuild’.
o Para compilar la aplicación-ejemplo, sitúa el cursor del ratón sobre el
icono del proyecto LAB, despliega el menú asociado al botón
derecho del ratón y selecciona ‘Build’ o ‘Rebuild’.
o Para ejecutar la aplicación-ejemplo, despliega el menú ‘Debug’ de la
parte superior de la ventana y selecciona ‘Start without debugging’.
-
El archivo que contiene el código fuente correspondiente a la aplicación-ejemplo
es TEST.C. Este archivo es el que tienes que modificar en las secciones
siguientes.
(2) Análisis de la aplicación y su código fuente (20 min.)
-
Ejecuta la aplicación tal y como se ha descrito anteriormente.
-
Observa los siguientes aspectos de la ejecución de esta aplicación: ejecución
concurrente de las tareas, utilización de la CPU, variabilidad de uso de la pila
para las diferentes tareas, variabilidad de los tiempos de ejecución, etc.
-
Detén el programa cuando quieras pulsando ESC
-
Localiza la función main. Observa cómo se declara la tarea TaskStart: puntero
a la función, paso del puntero correspondiente a la pila de la tarea (localiza la
declaración de la pila en el programa). Observa que cuando se ejecuta OSStart()
el planificador toma el control y comienzan a ejecutarse las tareas en base a su
prioridad y la llegada de eventos.
P - ¿Cómo se llama el array que se utiliza como pila de la tarea TaskStart?
-
Localiza la tarea TaskStart. Observa que esta tarea tiene una parte importante
de inicialización antes de entrar en el bucle infinito típico de las tareas de
uC/OS-II. Observa cómo se declaran las tareas de la aplicación así como los
mailbox.
P - ¿Cómo se llaman los mailbox que se declaran?
-
Localiza las tareas Task1, Task2, Task3, Task4, Task5 y TaskClk.
P - ¿Qué tareas son periódicas y cuáles no? ¿Hay alguna que tenga varios puntos de
suspensión? ¿Qué prioridades tienen? ¿Por qué evento esperan?
Periódicas (Tarea/Prio/Periodo):
Aperiódicas (Tarea/Prio/Evento):
Varios puntos de suspensión (Tarea/Prio):
(3) Modificación 1 (20 min.)
-
Modifica las dos tareas que visualizan las barras giratorias, de forma que sus
códigos fuente sólo tengan un punto de suspensión dentro del bucle infinito (una
única invocación de OSTimeDly).
Código fuente de la tarea que gira la barra en sentido horario:
-
Modifica los tiempos de suspensión de las tareas que visualizan la barra
giratoria. Consigue que la tarea que dibuja la barra giratoria en el sentido de las
agujas del reloj tenga un periodo de 0.5 segundos y la que lo hace en el sentido
contrario tenga un periodo de 0.25 segundos. Utiliza para ello la constante del
sistema OS_TICKS_PER_SEC, cuyo valor es el número de ticks por segundo
con el que está configurado el temporizador del sistema.
Invocaciones a OSTimeDly para ambas tareas:
SENTIDO HORARIO:
SENTIDO ANTI-HORARIO:
(4) Modificación 2 (20 min.)
-
Modifica la tarea que envía un mensaje a través de un mailbox para que
visualice el mensaje antes de enviarlo.
-
Convierte la tarea emisora en tarea receptora del mensaje y viceversa. En vez de
transmitir las letras de la A a la Z, haz que la transmisión sea un número
aleatorio generado por la tarea transmisora. Para ello, utiliza la función de
librería rand() (acuérdate de incluir la cabecera: #include <stdlib.h>), la cual
genera un número aleatorio entre 0 y RAND_MAX (= 32767). También
necesitarás invocar la función sprintf para convertir un entero en cadena (así:
sprintf(str,”%d”,n), donde ‘str’ es una cadena de tamaño suficiente, char str[10],
y ‘n’ es el entero a convertir) y la función de librería de uCOS-II PC_DispStr(x,
y, string, color).
Código final de la tarea transmisora:
(5) Modificación 3 (50 min.)
-
Crea dos tareas Task6 y Task7, de forma que Task6 actúe como productora de
un buffer LIFO (last in first out) y Task7 sea la consumidora, protegiendo
adecuadamente las regiones críticas correspondientes.
Por un lado, el buffer LIFO viene dado por:
#define N 20
int buffer[N];
int nitems = -1; // indica la última posición ocupada
Por otro lado, las operaciones producir y consumir se definen de la siguiente
forma:
PRODUCIR:
CONSUMIR:
if (nitems < (N-1)) {
if (nitems >= 0) {
item = rand();
item = buffer[nitem];
sprintf(str,”%d”,item);
nitems--;
PC_DispStr(70,19,str,<color>);
sprintf(str,”%d”,item);
nitems++;
PC_DispStr(70,20,str,<color>);
buffer[nitem] = item;
}
}
OS_TimeDlyHMSM(0,0,rand()%6,0);
OS_TimeDlyHMSM(0,0,rand()%6,0);
Modifica el fichero OS_CFG.H, habilitando la generación de código para las
funciones de semáforos (#define OS_SEM_EN 1).
Código final de las tareas:
Descargar