martes, 8 de septiembre de 2015

ISR con MQX KDS 3.0 SDK 1.2 con Eventos

Objetivo

Realizar la coordinación del encendido del LED RGB  utilizando una estructura de interrupciones ISR, con Eventos de MQX.


Descripción del Programa

El contenido de la práctica, se describe a continuación:

El programa principal (main.c) enlista, mediante una estructura, las tareas que desarrollará el mismo. En este caso, se tiene una sola tarea. Además, se realiza la estructura perteneciente a la interrupcíón, declarando una variable y un apuntador de dicha estructura. También se declaran las funciones de las interrupciones de los puertos A y C; en el puerto A se realiza el incremento tanto del  contador global como de un contador de interrupciones, mientras que el puerto C incremente el contador de interrupciones, y decrementa el contador global. Además, ambas funciones llaman al evento con el valor actual del contador del evento.

La tarea del programa realiza la creación del evento, además de habilitar el uso de los pines (LEDs), habilitar las interrupciones y comprobar si se realizó dicha acción correctamente. En el lazo infinito, se espera por la bandera del evento, para imprimir el valor del contador global, el contador del puerto A y del puerto C, asi como encender el LED del color correspondiente.

El archivo LED_RGB.h contiene la enumeración de los colores que se utilizarán para el encendido del LED. Además contiene el protocolo de las funciones para el encendido del LED y la impresión del color correspondiente.

El archivo LED_RGB.c realiza, de acuerdo al valor del color deseado, encender la combinación de LEDs correspondiente para generar el color deseado. Así mismo, permite la impresión del color correspondiente.


Códigos del Programa

-   main.c

#include <stdio.h>
#include <assert.h>
#include <mqx.h>
#include <bsp.h>
#include <fsl_interrupt_manager.h>
#include "LED_RGB.h"
#include"lwevent.h"

#define EVENT_COUNTER 1

#define MAIN_TASK 10
void main_task(uint32_t initial_data);

_mqx_uint             G_Counter;

LWEVENT_STRUCT lwevent;

const TASK_TEMPLATE_STRUCT  MQX_template_list[] =
{
   /* Indice de la Tarea, Funcion, Stack, Prioridad, Nombre, Atributos, Parametro, Fraccion de tiempo */
    { MAIN_TASK,  main_task, 1000,  8,    "Main",      MQX_AUTO_START_TASK, 0,     0 },
    { 0 }
};


typedef struct my_isr_struct
{
   void                 *OLD_ISR_DATA;
   INT_ISR_FPTR          OLD_ISR;
   _mqx_uint             Counter;
MY_ISR_STRUCT, * MY_ISR_STRUCT_PTR;

MY_ISR_STRUCT  isr_data_PORTA,isr_data_PORTC;


void new_isr_PORTA(void *user_isr_ptr)
{
   MY_ISR_STRUCT_PTR  isr_ptr;
   PORT_HAL_ClearPortIntFlag(PORTA_BASE_PTR);
   isr_ptr = (MY_ISR_STRUCT_PTR)user_isr_ptr;
   isr_ptr->Counter++;
   G_Counter++;
   _lwevent_set(&lwevent,EVENT_COUNTER);
}

void new_isr_PORTC(void *user_isr_ptr)
{
   MY_ISR_STRUCT_PTR  isr_ptr;
   PORT_HAL_ClearPortIntFlag(PORTC_BASE_PTR);
   isr_ptr = (MY_ISR_STRUCT_PTR)user_isr_ptr;
   isr_ptr->Counter++;
   G_Counter--;
   _lwevent_set(&lwevent,EVENT_COUNTER);
}

/*TASK*----------------------------------------------------------
*
* Nombre de la tarea : main_task
* Comentarios  :
*   Esta tarea demuestra la instalación de la interrupción en MQX.
*END*-----------------------------------------------------------*/

void main_task(uint32_t initial_data)
{

    INT_ISR_FPTR old_isr_PORTA,old_isr_PORTC;

    _lwevent_create(&lwevent,LWEVENT_AUTO_CLEAR);

    GPIO_DRV_Init(switchPins,ledPins);

    /* Habilita la interrupción para PORTA_IRQn*/
    INT_SYS_EnableIRQ(PORTA_IRQn);

    /* Habilita la interrupción para PORTC_IRQn*/
    INT_SYS_EnableIRQ(PORTC_IRQn);

    /** Demostracion de la intalación de la interrupción de mqx. Trabaja con la tabla de vectores ubicada en RW como en RO memory **/
    G_Counter=0;

    isr_data_PORTA.Counter      = 0;
    isr_data_PORTA.OLD_ISR_DATA = _int_get_isr_data(PORTA_IRQn);
    isr_data_PORTA.OLD_ISR      = _int_get_isr(PORTA_IRQn);

    isr_data_PORTC.Counter      = 0;
    isr_data_PORTC.OLD_ISR_DATA = _int_get_isr_data(PORTC_IRQn);
    isr_data_PORTC.OLD_ISR      = _int_get_isr(PORTC_IRQn);

    /* Instala la rutina de interrupción de MQX. No cambia la tabla del vector.*/
    old_isr_PORTA = _int_install_isr(PORTA_IRQn, new_isr_PORTA, &isr_data_PORTA);

    old_isr_PORTC = _int_install_isr(PORTC_IRQn, new_isr_PORTC, &isr_data_PORTC);


    /* Verifica si _int_install_isr devuelve lo mismo que _int_get_isr*/
    assert(old_isr_PORTA == isr_data_PORTA.OLD_ISR);

    assert(old_isr_PORTC == isr_data_PORTC.OLD_ISR);


    /* Llama a la interrupción por software 10 veces cada 10ms */
    while(TRUE)
    {
       _lwevent_wait_for(&lwevent,EVENT_COUNTER,FALSE,NULL);

              printf("Counter = %d C_PtoA = %d C_PtoC = %d ", G_Counter, isr_data_PORTA.Counter, isr_data_PORTC.Counter);
              printf_color(G_Counter&0x7);
              led(G_Counter&0x7);

    }

    _task_block();
}

/* EOF */


-   LED_RGB.h

#ifndef LED_RGB_H_
#define LED_RGB_H_

#define SIZE_ARR 8
typedef char string[SIZE_ARR];

typedef enum {BLACK,RED,GREEN,YELLOW,BLUE,MAGENTA,CYAN,WHITEcolor;
enum bits{B0=1,B1=2,B2=4,B3=8,B4=0X10,B5=0X20,B6=0X40,B7=0X80};

void led(color);
void printf_color(color dato);
#endif /* LED_RGB_H_ */

-   LED_RGB.c

#include "LED_RGB.h"
#include <bsp.h>
#include <stdio.h>

void led(color dato)
{
       GPIO_DRV_WritePinOutput(BOARD_GPIO_LED_RED,!(dato&B0));
       GPIO_DRV_WritePinOutput(BOARD_GPIO_LED_GREEN,!(dato&B1));
       GPIO_DRV_WritePinOutput(BOARD_GPIO_LED_BLUE,!(dato&B2));
}

void printf_color(color dato)
{
       string color_names[]={"Black","Red","Green","Yellow","Blue","Magenta","Cyan","White"};

       printf("%s\n",color_names[dato]);
}



Refencias

Manual de microcontroladores de la serie K64:


Para conocer el curso completo de Essentials Course of MQX, visita la página:


Mensajes con MQX KDS 3.0 SDK 1.2

Objetivo


Realizar la coordinación del encendido del LED RGB  en sus colores rojo, verde, azul y sus combinaciones, utilizando los comandos _lwmsgq_init_lwmsgq_receive y _lwmsgq_send.

Descripción del Programa


El contenido de la práctica, se describe a continuación:

El programa principal (main.c) enlista, mediante una estructura, las tareas que desarrollará el mismo. En este caso, se tienen tres tareas, una de inicio, una de envío y una de recepción. Así también, se genera la cola de mensaje y se establecen los protocolos de las funciones y tareas utilizadas.

En la tarea de inicio, que es de autoinicialización, se habilitan los pines que se utilizarán (LEDs), se inicializa la cola de mensaje y se comprueba que las tareas de envío y recepción se hayan creado correctamente.

En la tarea de recepción, se tiene un lazo infito que espera por la llegada del mensaje, imprimiendo el color del dato que contiene el mensaje entrante y encendiendo el LED de ese color.

En la tarea de envío, se tiene un lazo infinito donde se crea el mensaje con un valor asignado por la variable index, el cual es enviado a la tarea de recepción, con un tiempo de retardo de 200 ticks entre mensajes. Dicho indice varía entre 0 y 8 y, una vez alcanzado el valor máximo, se reinicia en 1.

El archivo LED_RGB.h contiene la enumeración de los colores que se utilizarán para el encendido del LED. Además contiene el protocolo de las funciones para el encendido del LED y la impresión del color correspondiente.

El archivo LED_RGB.c realiza, de acuerdo al valor del color deseado, encender la combinación de LEDs correspondiente para generar el color deseado. Así mismo, permite la impresión del color correspondiente.


Códigos del Programa


-   main.c


#include <stdio.h>
#include <mqx.h>
#include <bsp.h>
#include <lwtimer.h>
#include "LED_RGB.h"

/* Task IDs */
/* Task IDs */
#define INIT_TASK          5
#define SEND_TASK       6
#define RECEIVE_TASK       7

#define NUM_MESSAGES  1
#define MSG_SIZE      1

//crea cola de mensaje
       int32_t receive_queue[sizeof(LWMSGQ_STRUCT)/sizeof(uint32_t) + NUM_MESSAGES * MSG_SIZE];

void send_task (uint32_t initial_data);
void receive_task (uint32_t initial_data);

void init_task( uint32_t);
void send_task( uint32_t);
void receive_task( uint32_t);



const TASK_TEMPLATE_STRUCT  MQX_template_list[] =
{
   /* Indice de la Tarea, Funcion, Stack, Prioridad, Nombre, Atributos, Parametro, Fraccion de tiempo */
    { INIT_TASK,    init_task,    700,    9,  "init",    MQX_AUTO_START_TASK, 0,     0 },
    { SEND_TASK,    send_task,    700,    9,  "send",    0,                   0,     0 },
    { RECEIVE_TASK, receive_task, 700,    9,  "receive", 0,                   0,     0 },
    { 0 }
};


void init_task
   (
      uint32_t initial_data
   )
{
       _mqx_uint result;
       _task_id send_task_id, receive_task_id;
       GPIO_DRV_Init(switchPins,ledPins);


       result = _lwmsgq_init((void *)receive_queue, NUM_MESSAGES, MSG_SIZE);
       if (result != MQX_OK) {
             // lwmsgq_init failed
       } /* Endif */

       send_task_id = _task_create(0, SEND_TASK, 0);
          if (send_task_id == MQX_NULL_TASK_ID) {
             printf ("\n Could not create send_task\n");
          }
       receive_task_id = _task_create(0, RECEIVE_TASK, 0);
          if (receive_task_id == MQX_NULL_TASK_ID) {
                printf ("\n Could not create receive_task\n");
          }

       _task_abort(_task_get_id());
}

void receive_task
   (
      uint32_t initial_data
   )
{
       _mqx_uint          msg[MSG_SIZE];
       while(1)
         {

             //espera mensaje
             _lwmsgq_receive((void *)receive_queue, msg, LWMSGQ_RECEIVE_BLOCK_ON_EMPTY, 0, 0);
             printf_color(msg[0]);
             led(msg[0]);
         }
}

void send_task
   (
          uint32_t index
   )
{
   index=0;
   _mqx_uint          msg[MSG_SIZE];
       while(1)
         {
             msg[0] = index;
           _lwmsgq_send((void *)receive_queue, msg, LWMSGQ_SEND_BLOCK_ON_FULL);
             _time_delay_ticks(200);
index++;
if (index==8) index=1;
             //envia mensaje
             //espera medio segundo
             //incrementa apuntador a mensaje
         }
}

/* EOF */

-   LED_RGB.h


#ifndef LED_RGB_H_
#define LED_RGB_H_

#define SIZE_ARR 8
typedef char string[SIZE_ARR];

typedef enum {BLACK,RED,GREEN,YELLOW,BLUE,MAGENTA,CYAN,WHITEcolor;
enum bits{B0=1,B1=2,B2=4,B3=8,B4=0X10,B5=0X20,B6=0X40,B7=0X80};

void led(color);
void printf_color(color dato);
#endif /* LED_RGB_H_ */

-   LED_RGB.c


#include "LED_RGB.h"
#include <bsp.h>
#include <stdio.h>

void led(color dato)
{
       GPIO_DRV_WritePinOutput(BOARD_GPIO_LED_RED,!(dato&B0));
       GPIO_DRV_WritePinOutput(BOARD_GPIO_LED_GREEN,!(dato&B1));
       GPIO_DRV_WritePinOutput(BOARD_GPIO_LED_BLUE,!(dato&B2));
}

void printf_color(color dato)
{
       string color_names[]={"Black","Red","Green","Yellow","Blue","Magenta","Cyan","White"};

       printf("%s\n",color_names[dato]);
}



Refencias


Manual de microcontroladores de la serie K64:


Para mayor información sobre el uso de los MENSAJES, visita la página:



Para conocer el curso completo de Essentials Course of MQX, visita la página: