lunes, 27 de enero de 2014

Mutaxes. (Codigo)

Código del programa.

#include"Cpu.h"
#include"Events.h"
#include"mqx_tasks.h"
#include"mutex.h"

/* User includes (#include below this line is not maintained by Processor Expert) */
MUTEX_STRUCT mutex;    //Sedeclaraunaestructuramutex


voidTask1_task(uint32_t task_init_data)
{
int counter = 0;
//_mqx_uint result;
_mutex_init(&mutex, NULL);   //Seinicializamutexconlosvalorespredeterminados
_task_abort(_task_get_id());  //Seterminalatarea
while(1) {
    counter++;

/* Write your code here ... */
  }
}

voidTask2_task(uint32_t task_init_data)
{
int counter = 0;

while(1) {
    counter++;
    _mutex_lock(&mutex);                                  //Sebloquea el recurso
    Rojo_ClrVal( Rojo_DeviceData );
    Verde_SetVal( Verde_DeviceData );
Azul_SetVal( Azul_DeviceData );
_time_delay_ticks(100);
     _mutex_unlock(&mutex);
/* Write your code here ... */

  }
}


voidTask3_task(uint32_t task_init_data)
{
int counter = 0;

while(1) {
    counter++;
    _mutex_lock(&mutex);
Verde_ClrVal( Verde_DeviceData );
      Rojo_SetVal( Rojo_DeviceData );
Azul_SetVal( Azul_DeviceData );
      _time_delay_ticks(100);
      _mutex_unlock(&mutex);

/* Write your code here ... */

  }
}

voidTask4_task(uint32_t task_init_data)
{
int counter = 0;

while(1) {
    counter++;
     _mutex_lock(&mutex);
Azul_ClrVal( Azul_DeviceData );
     Verde_SetVal( Verde_DeviceData );
Rojo_SetVal( Rojo_DeviceData );
     _time_delay_ticks(100);
     _mutex_unlock(&mutex);
/* Write your code here ... */

  }
}

Mutaxes

MARCO TEORICO

Se utilizan para que una sola tarea trabaje a la vez, es decir, la tarea en ejecución se adueña del mutex y esta misma será quien libere el mutex una vez que haya terminado su función.

A continuación se ilustra un ejemplo acerca de la forma en que funciona esta herramienta:

1.       Existen 3 tareas, la tarea 2 se adueña del mutex:


Figura 1. Tarea 2 solicita Mutex.
2.       La tarea 3 trata de adueñarse del mutex pero esto ya no puede ser ya que en este momento pertenece a la tarea 2, por lo que la tarea 3 pasa a la fila del mutex:


Figura 2. Tarea 3 solicita Mutex.

                                                                                                                                      
3.       La tarea uno trata de adueñarse del mutex pero este ya pertenece a la tarea dos por lo que pasa de igual manera a la fila del mutex:
Figura 3. Tarea 2 solicita Mutex.


4.       La tarea 2 libera el mutex y la tarea 3 se adueña de este:
Figura 4. Tarea 2 libera Mutex.

5.       La tarea 3 libera el mutex y la tarea 1 se adueña de este:


Figura 5. Tarea 3 libera Mutex.

Creación de un Mutex.

MUTEX_STRUCTmutex;

·         Para inicializar el mutex con atributos por default:
  • result = _mutex_init(mutex_ptr, NULL)

·         Para solicitar el mutex:
  • _mqx_uint _mutex_lock(mutex_ptr)

·         Para liberar el mutex:
  • _mqx_uint _mutex_unlock(mutex_ptr)

Ejemplo.


El programa consiste en la creación de un mutex, el cual es una herramienta para sincronizar tareas y compartir recursos. EL programa consta de 4 tareas, la cual la primera que se ejecuta sirve para inicializar al mutex, para posteriormente bloquearse.
Una vez que se ejecuta alguna de las otras tareas, la tarea activa se apropia del mutex por lo cual no permite que ninguna otra trabaje hasta que esta lo libere, y de esta forma se puedan ejecutar las demás, las cuales tienen la misma lógica.

Eventos. (Codigo)

Código del programa.

#include"Cpu.h"
#include"Events.h"
#include"mqx_tasks.h"
//#include "user_config.h"
#include"lwevent.h"

#define ROJO 1
#define VERDE 2
#define AZUL 4
/* User includes (#include below this line is not maintained by Processor Expert) */
  LWEVENT_STRUCT lwevent;


voidTask1_task(uint32_t task_init_data)
{
int counter = 0;
  _lwevent_create(&lwevent,LWEVENT_AUTO_CLEAR);  //Poneencero a los bits delevento
  _lwevent_set(&lwevent,ROJO);                    //activa el bit ROJO
  _task_abort(_task_get_id());
while(1) {
    counter++;
/* Write your code here ... */
  }
}

voidTask2_task(uint32_t task_init_data)
{
int counter = 0;

while(1) {
    counter++;
_lwevent_wait_for(&lwevent,ROJO,FALSE,NULL);
/* Write your code here ... */
Rojo_ClrVal(Rojo_DeviceData);
Verde_SetVal(Verde_DeviceData);
Azul_SetVal(Azul_DeviceData);
_time_delay_ticks(100);
    _lwevent_set(&lwevent,VERDE);
  }
}


voidTask3_task(uint32_t task_init_data)
{
int counter = 0;

while(1) {
    counter++;
_lwevent_wait_for(&lwevent,VERDE,FALSE,NULL);  //Puedeser TRUE o FALSE
/* Write your code here ... */
Verde_ClrVal(Verde_DeviceData);
    Rojo_SetVal(Rojo_DeviceData);
Azul_SetVal(Azul_DeviceData);
    _time_delay_ticks(100);
    _lwevent_set(&lwevent,AZUL);
/* Write your code here ... */

  }
}

voidTask4_task(uint32_t task_init_data)
{
int counter = 0;

while(1) {
    counter++;
_lwevent_wait_for(&lwevent,AZUL,FALSE,NULL);
Azul_ClrVal(Azul_DeviceData);
    Rojo_SetVal(Rojo_DeviceData);
Verde_SetVal(Verde_DeviceData);
    _time_delay_ticks(100);
/* Write your code here ... */
    _lwevent_set(&lwevent,ROJO);
/* Write your code here ... */

  }

}

Eventos

MARCO TEÓRICO

Las tareas pueden esperar a que una combinación de eventos de bits sea puesta en 1. Una tarea puede poner en 1 o 0 una combinación de eventos de bits. Los eventos también pueden ser utilizados para sincronizar una tarea con otra.
El componente llamado evento consiste en grupos de eventos, los cuales son agrupaciones de los eventos de bits.
  • Las tareas pueden esperar por todos o cualquier evento de bits que se ponga en 1.
  • Los grupos de eventos pueden ser identificados por nombre o por index.
  • Cualquier tarea puede esperar por eventos de bits en cualquier grupo de eventos.
  • Cuando el evento de bits esta puesto en 1, MQX pone todas las tareas en espera, las cuales esperaran por una condición conocida en la fila.
  • Si un grupo de eventos tiene eventos de bits de autoclearing, MQX limpia los bits de evento tan pronto como estos fueron puestos en 1.


Para poder utilizar los eventos en MQX lightweight, es necesario habilitarlo en “component inspector” además de agregar el archivo de cabecera “lwevents.h”.

Creación de Eventos.

LWEVENT_STRUCT lwevent;  //Crea una variable del tipo evento

·         Para crear un grupo de eventos:
_mqx_uint _lwevent_create(lwevent_ptr, flags)

·         Para colocar especificado bit de evento en un grupo de eventos:
_mqx_uint _lwevent_set(lwevent_ptr, mask)

·         Para limpiar especificado bit de evento en un grupo de eventos:
_mqx_uint _lwevent_clear(lwevent_ptr, mask)


Ejemplo.

El programa consiste en 4 tareas. A continuación se muestra la tabla de características.


Name
Stack Size
Priority
MQX_AUTO_START_TASK
Task1
Inicio
512
8
Enable
Task2
Rojo
512
9
Enable
Task3
Verde
512
9
Enable
Task4
Azul
512
9
Enable
Tabla 4. Características de las tareas.

El programa inicia con la creación del evento dentro del código de la tarea Inicio, que es la que se ejecuta primero por tener la más alta prioridad. Una vez creado el evento, la tarea se bloquea y el administrador ejecuta la siguiente tarea.

Ver Codigo

Semaforos

MARCO TEORICO


El semáforo es una herramienta que permite controlar el acceso  a un recurso compartido, es una señalización de que un evento ha terminado y permite a dos tareas sincronizar sus actividades.
Un semáforo contiene:
  • Contador: es el máximo número de accesos que van a ocurrir antes de que este llegue a cero y haga esperar a la siguiente tarea hasta que se encuentre habilitado.
  • Cola: es el lugar en que las tareas esperan para poder ejecutarse.

Funcionamiento

  1. Una tarea espera por el semáforo:

  • Si el contador es mayor que cero, este se decrementa en uno, la tarea obtiene el                         semáforo y esta puede trabajar.
  • Si no es posible, la tarea es puesta en la fila.


     2.  Si una tarea pone en post a un semáforo:
  • Si al menos una tarea se encuentra en la fila del semáforo, la tarea es realizada de acuerdo      a la política de filas de los semáforos.
  • Si no, el contador es incrementado en  una unidad.

Si el contador es inicializado en 2 y se tienen tres tareas con la misma prioridad, todas ellas ligadas entre si, en espera del semáforo y una vez que estas terminan de ejecutarse ponen post al semáforo, la manera en que estas serán puestas en función es:
  1. Se ejecutara la tarea task1 (contador=1) y task2 (contador=0) simultáneamente, mientras que la tarea task3 esperará en la fila del semáforo.
  2. Una vez ejecutadas, el semáforo atiende a task3 que está en la fila y atiende a la última tarea que fue ejecutada es decir, a task2, mientras task1 se pone en la fila del semáforo.
  3. Una vez que se ejecutaron task3 y task2, el semáforo atiende a la tarea que estaba en la fila, es decir, a task1 y de igual manera ejecuta a la última tarea anterior en ejecutarse task2, mientras task3 se queda en fila esperando.

Este procedimiento se repite de manera indefinida.

Ejemplificando con el ejercicio anterior, teniendo un contador mayor igual  a tres, la manera en que las tareas se ejecuten es la siguiente:
  •  task1, task2  y task3 simultáneamente.
  • task3, task2 y task1 simultáneamente.

Este procedimiento será repetido de manera indefinida.

Finalmente se muestran la manera de declarar, crear, esperar y habilitar un semáforo.

Creación de un Semáforo.

·         Para crear un semáforo:
  • _mqx_uint _lwsem_create(lwsem_ptr,initial_count)

·         Para esperar por un semáforo:
  • _mqx_uint _lwsem_wait(lwsem_ptr)

·         Para habilitar un semáforo:
  • _mqx_uint _lwsem_post(lwsem_ptr)


En esta práctica se hace uso de los semáforos, el programa sigue una secuencia de leds. Primero enciende el led rojo, posteriormente el verde y por último el azul.
El proyecto consta de cuatro tareas, las características son las siguientes:


Name
Stack Size
Priority
MQX_AUTO_START_TASK
TASK1
Crea_Sem
1000
8
Enable
TASK2
Led_Rojo
1000
9
Enable
TASK3
Led_Verde
1000
9
Enable
TASK4
Led_Azul
1000
9
Enable
Tabla 3.  Propiedades de las tareas.

Ejemplo.

El programa consiste en 4 tareas de autostart, una de las cuales es de mayor prioridad, por lo que es la que se ejecutara primero. El objetivo de que se inicie la tarea Crea_Sem en primer lugar, es el de crear un semáforo e inicializarlo en 1, y posteriormente se bloquee.
Una vez inicializado el semáforo, el administrador seguirá con el programa por lo que ejecutara cualquiera de las tareas (ya que tienen la misma prioridad), y una vez que inicie la ejecución, la tarea activa esperara por el semáforo y ya que este se inicializo con 1, ejecutará su código y decrementará el contador del semáforo por lo que este quedara en cero y por lo tanto cuando alguna otra tarea espere por su contador, no permitirá la ejecución de su código, y esta será puesta en la lista de espera.
El proyecto consta de tres Beans los cuales se encuentran configurados para  que controlen el led tricolor con que cuenta la tarjeta.
Adicionalmente se agrego la capacidad al programa para que imprima en pantalla el color del led que se encuentra trabajando.