PSyD - Universidad Complutense de Madrid

Anuncio
Laboratorio 13:
Aplicaciones multitarea bajo un kernel
de planificación no expropiativo
Programación de sistemas y dispositivos
José Manuel Mendías Cuadros
Dpto. Arquitectura de Computadores y Automática
Universidad Complutense de Madrid
J.M. Mendías
2016

Crear una aplicación multitarea bajo un kernel de planificación no expropiativo de tareas multiestado.
laboratorio 12:
Aplicaciones multihebra bajo el RTOS uC/OS‐II
o El punto de partida es una aplicación funcional que consta de 6 tareas:
PSyD
2
• Las tareas serán funcionalmente las mismas que en el Lab 12, todas son periódicas (alguna con periodicidad variable)
• Existirá una hebra en foreground (RTI por temporizador) encargada de pasar a preparadas aquellas taras cuyo periodo de ejecución haya vencido.
• Las tareas preparadas se ejecutarán secuencialmente por orden de prioridad por una única hebra en background.
o Adicionalmente, existirá una hebra adicional: una RTI por pulsación de pulsador
• Cada vez detecte una pulsación de cualquier pulsador, activará un flag para que la hebra en foreground envíe por la UART0 un mensaje.
o La UART0 no es necesario protegerla ya que solo es usado por la hebra en background.
o Las tareas que producen/consumen scancodes utilizarán una variable global compartida que no es necesaria proteger, al no existir expropiación.
o Al igual que en Lab 12, esta aplicación se ampliará con 2 tareas adicionales funcionalmente equivalentes a las allí realizadas.
J.M. Mendías
2016
declaraciones
...
laboratorio 12:
Aplicaciones multihebra bajo el RTOS uC/OS‐II
#define MAX_TASKS
#define TICKS_PER_SEC
PSyD
3
(10)
(100)
typedef struct
{
void (* pfunction) (uint32 *, uint32 *);
uint32 state;
uint32 period;
uint32 ticks;
boolean ready;
} task_t;
Las tareas serán multiestado
uint32 create_task( void (*pfunction)(uint32 *, uint32 *), uint32 state,
uint32 period );
void delete_task( uint32 i );
void scheduler_init( void );
void scheduler( void ) __attribute__ ((interrupt ("IRQ")));
void dispacher( void );
J.M. Mendías
2016
laboratorio 12:
Aplicaciones multihebra bajo el RTOS uC/OS‐II
PSyD
4
declaraciones
#define INIT
#define RUN
(0)
(1)
#define
#define
#define
#define
(1)
(2)
(3)
(4)
WAIT_KEYDOWN
SCAN
WAIT_KEYUP
END_SCAN
Declara los estados en que pueden estar las tareas
uint8 scancode;
boolean flagTask5 = FALSE;
boolean flagTask6 = FALSE;
volatile boolean pb_pressed = FALSE;
Declara los recursos de sincronización entre tareas
void Task1( uint32 *state, uint32 *period );
void Task2( uint32 *state, uint32 *period );
...
void Task6( uint32 *state, uint32 *period );
Declara tareas
void isr_pb( void ) __attribute__ ((interrupt ("IRQ")));
RTI por presión
de pulsador
laboratorio 12:
Aplicaciones multihebra bajo el RTOS uC/OS‐II
J.M. Mendías
2016
programa principal
PSyD
5
void main( void )
{
sys_init();
timers_init();
...
keypad_init();
Inicializa dispositivos
uart0_puts("\n\n Ejecutando kernel de planificación no expropiativo\n");
uart0_puts("----------------------------------\n\n");
scheduler_init();
Inicializa el Kernel
Crea tareas
create_task( Task1, INIT, 50 );
create_task( Task2, INIT, 10 );
...
create_task( Task6, INIT, 10 );
timer0_open_tick( scheduler, TICKS_PER_SEC );
pbs_open( isr_pb );
...
Instala planificador
Instala RTI
J.M. Mendías
2016
programa principal / RTI
laboratorio 12:
Aplicaciones multihebra bajo el RTOS uC/OS‐II
...
PSyD
6
while( 1 )
{
Entra en estado IDLE, sale por interrupción
sleep();
if( pb_pressed )
{
uart0_puts( " (INT) Se ha pulsado algún pushbutton...\n" );
pb_pressed = FALSE;
}
Todas las tareas preparadas se ejecutan por orden de prioridad
dispacher();
}
}
void isr_pb( void )
{
pb_pressed = TRUE;
EXTINTPND = BIT_RIGHTPB;
EXTINTPND = BIT_LEFTPB;
I_ISPC = BIT_PB;
}
Activa flag
J.M. Mendías
2016
laboratorio 12:
Aplicaciones multihebra bajo el RTOS uC/OS‐II
PSyD
7
tareas (i)
void Task1( uint32 *state, uint32 *period
{
switch( *state )
{
case INIT:
Muestra un mensaje de presentación
uart0_puts( " Task 1: iniciada.\n" );
por la UART0
led_on( LEFT_LED );
led_off( RIGHT_LED );
*state = RUN;
break;
default:
led_toggle( LEFT_LED );
Conmuta el estado de los leds
led_toggle( RIGHT_LED );
break;
};
}
J.M. Mendías
2016
laboratorio 12:
Aplicaciones multihebra bajo el RTOS uC/OS‐II
PSyD
8
tareas (ii)
void Task2( uint32 *state, uint32 *period )
{
switch( *state )
{
case INIT:
uart0_puts( " Task 2: iniciada.\n" );
*state = WAIT_KEYDOWN;
break;
case WAIT_KEYDOWN:
if( !(PDATG & 0x2) )
{ *state = SCAN; *period = 3; }
break;
case SCAN:
scancode = keypad_scan();
flagTask5 = flagTask6 = TRUE;
*state = WAIT_KEYUP; *period = 10;
break;
case WAIT_KEYUP:
if( PDATG & 0x2 )
{ *state = END_SCAN; *period = 10; }
break;
case END_SCAN:
*state = WAIT_KEYDOWN; *period = 10;
break;
};
}
Muestra un mensaje de presentación
por la UART0
Muestrea el teclado esperando presión
cada 0,1 segundos (10 ticks)
Espera rebote de presión
Lee el scancode
Activa flags
Muestrea el teclado esperando presión
cada 0,1 segundos (10 ticks)
Espera rebote de depresión
J.M. Mendías
2016
tareas (iii)
void Task3( uint32 *state, uint32 *period
{
rtc_time_t rtc_time;
laboratorio 12:
Aplicaciones multihebra bajo el RTOS uC/OS‐II
switch( *state )
{
case INIT:
Muestra un mensaje de presentación
uart0_puts( " Task 3: iniciada.\n" );
por la UART0
*state = RUN;
break;
default:
Lee la hora del RTC
rtc_gettime( &rtc_time );
uart0_puts( " (Task 3) Hora: " );
uart0_putint( rtc_time.hour );
uart0_putchar( ':' );
uart0_putint( rtc_time.min );
Muestra la hora del RTC por la UART0
uart0_putchar( ':' );
uart0_putint( rtc_time.sec );
uart0_puts( "\n" );
break;
};
PSyD
9
)
}
J.M. Mendías
2016
tareas (iv)
laboratorio 12:
Aplicaciones multihebra bajo el RTOS uC/OS‐II
void Task4( uint32 *state, uint32 *period )
{
static uint32 ticks;
PSyD
10
switch( *state )
{
case INIT:
Muestra un mensaje de presentación
uart0_puts( " Task 4: iniciada.\n" );
por la UART0
ticks = 0;
*state = RUN;
break;
default:
ticks += TICKS_PER_SEC * 10;
Actualiza el numero de ticks trancurridos
uart0_puts( " (Task 4) Ticks: " );
uart0_putint( ticks );
Muestra los ticks transcurridos por la UART0
uart0_puts( "\n" );
break;
};
}
J.M. Mendías
2016
laboratorio 12:
Aplicaciones multihebra bajo el RTOS uC/OS‐II
PSyD
11
tareas (v)
void Task5( uint32 *state, uint32 *period )
{
switch( *state )
{
case INIT:
Muestra un mensaje de presentación
uart0_puts( " Task 5: iniciada.\n" );
por la UART0
*state = RUN;
break;
default:
Chequea si hay nuevo scancode
if( flagTask5 == TRUE )
{
uart0_puts( " (Task 5) Tecla pulsada: " );
Muestra el scancode por la UART0
uart0_puthex( scancode );
uart0_puts( "\n" );
flagTask5 = FALSE;
}
break;
};
}
J.M. Mendías
2016
laboratorio 12:
Aplicaciones multihebra bajo el RTOS uC/OS‐II
PSyD
12
tareas (vi)
void Task6( uint32 *state, uint32 *period )
{
switch( *state )
{
case INIT:
Muestra un mensaje de presentación
uart0_puts( " Task 6: iniciada.\n" );
por la UART0
*state = RUN;
break;
default:
Chequea si hay nuevo scancode
if( flagTask6 == TRUE )
{
Muestra el scancode por el display 7‐segmentos
segs_putchar( scancode );
flagTask6 = FALSE;
}
break;
};
}
J.M. Mendías
2016

Licencia CC (Creative Commons)
laboratorio 12:
Aplicaciones multihebra bajo el RTOS uC/OS‐II
o Ofrece algunos derechos a terceras personas bajo ciertas condiciones. Este documento tiene establecidas las siguientes:
PSyD
13
Reconocimiento (Attribution): En cualquier explotación de la obra autorizada por la licencia
hará falta reconocer la autoría. No comercial (Non commercial): La explotación de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotación autorizada incluye la creación de obras derivadas siempre que mantengan la misma licencia al ser divulgadas.
Más información: https://creativecommons.org/licenses/by‐nc‐sa/4.0/
Descargar