miércoles, 8 de febrero de 2017

PRACTICA # 19 FreeRTOS

OBJETIVO: 
       Implementaremos el sistema operativo en tiempo real FreeRTOS el MCU R5F563NB de la tarjeta de evaluación YRDKRX63N. Utilizaremos los leds de la tarjeta para la manifestación de diversas tareas en ejecución.
  • Configuraremos stack FreeRTOS
  • Ampliaremos la memoria del stack del MCU
  • Crearemos algunas tareas de demostración 

DESARROLLO:
  • Del documento Renesas RX63N RDK User's Manual ubicamos los leds 4, 5, 8 y 10.


PASOS:
  • Creación de un proyecto:
1.- Abrir el software e2studio
2.- New/ C Project / Renesas RXC ToolChain


3.- Seleccionar el target R5F563NB, debug hardware Segger jLink, después next


4.- Seleccionar C/C++ Source file y por ultimo Finish.


5.- Cambiar el valor del stack del archivo sbrk.h:

/* size of area managed by sbrk */
#define HEAPSIZE 0xD000

6.- Configurar el archivo de arranque hardware_setup.c:

#include <stdint.h>
#include "iodefine.h"
#include "FreeRTOS/FreeRTOS.h"
void io_set_cpg(void);
void ConfigurePortPins(void);
void EnablePeripheralModules(void);
/******************************************************************************
* Function Name: HardwareSetup
* Description  : This function does initial setting for CPG port pins used in
*              : the Demo including the MII pins of the Ethernet PHY connection.
* Arguments    : none
* Return Value : none
******************************************************************************/
void HardwareSetup(void)
{
            /* CPG setting */
            io_set_cpg();

    /* Enables peripherals */
    EnablePeripheralModules();

}
/******************************************************************************
* Function Name: EnablePeripheralModules
* Description  : Enables Peripheral Modules before use
* Arguments    : none
* Return Value : none
******************************************************************************/
void EnablePeripheralModules(void)
{
            /*  Module standby clear */
            /* SYSTEM.MSTPCRB.BIT.MSTPB15 = 0; */                  /* EtherC, EDMAC  イーサネットは使わない*/
    SYSTEM.MSTPCRA.BIT.MSTPA15 = 0;             /* CMT0 動作可*/
}
/******************************************************************************
* Function Name: ConfigurePortPins
* Description  : Configures port pins.
* Arguments    : none
* Return Value : none
******************************************************************************/
void ConfigurePortPins(void)
{
/* Port pins default to inputs. To ensure safe initialisation set the pin states
before changing the data direction registers. This will avoid any unintentional
state changes on the external ports.
Many peripheral modules will override the setting of the port registers. Ensure
that the state is safe for external devices if the internal peripheral module is
disabled or powered down. */

}
/******************************************************************************
* Function Name: io_set_cpg
* Description  : Sets up operating speed
* Arguments    : none
* Return Value : none
******************************************************************************/
void io_set_cpg(void)
{
            unsigned long i;

            SYSTEM.PRCR.WORD = 0xA503; /* Access registers via PRCR                    */
            SYSTEM.SOSCCR.BYTE = 0x00; /* Sub-clock oscillator ON                      */

            SYSTEM.HOCOPCR.BYTE = 0x00; /* HOCO ON                                      */

            SYSTEM.MOSCWTCR.BYTE = 0x0e; /* Main Clock Oscillator Wait Control Register  */
            /* 262144 states                                */
            SYSTEM.PLLWTCR.BYTE = 0x0e; /* PLL Wait Control Register                    */
            /* 2097152 states                               */

            SYSTEM.MOSCCR.BYTE = 0x00; /* EXTAL ON                                     */
            SYSTEM.PLLCR2.BYTE = 0x01; /* PLL OFF                                      */
            SYSTEM.PLLCR.WORD = 0x0f00; /* x16 @PLL                                     */
            /* Input to PLL = EXTAL                            */
            /* Therefore:                                   */
            /*   PLL = EXTAL                                */
            /*       = 12                                   */
            /*   PLL * 16 = 192MHz                          */
            /* External oscillation input selection         */
            SYSTEM.PLLCR2.BYTE = 0x00; /* PLL ON                                       */

            for (i = 0; i < 2500; i++) /* Wait for stabilisation of PLL and main clock */
            { /* = 20ms                                       */
                        /*   (2500 x 1/125kHz = 20ms)                   */

            }

            /************************************************************************/
            /*                                                                      */
            /*  SYSTEM.SCKCR.BIT.PCKB   = 2; ( b11: b8 ) PLL/4 = 48MHz                           */
            /*  SYSTEM.SCKCR.BIT.PCKA   = 2; ( b15:b12 ) PLL/4 = 48MHz                           */
            /*  SYSTEM.SCKCR.BIT.BCK    = 2; ( b16:b19 ) PLL/4 = 48MHz                           */
            /*  SYSTEM.SCKCR.BIT.PSTOP0 = 1; ( b22     ) SDCLK CLK OUT Disabled     */
            /*  SYSTEM.SCKCR.BIT.PSTOP1 = 1; ( b23     ) BUS CLK OUT   Disabled     */
            /*  SYSTEM.SCKCR.BIT.ICK    = 1; ( b24:b27 ) PLL/2 = 96MHz                           */
            /*  SYSTEM.SCKCR.BIT.FCK    = 2; ( b31:b28 ) PLL/3 = 48MHz                           */
            /*                                                                      */
            /*  SYSTEM.SCKCR2.BIT.UCK   = 2;                        PLL/4 = 48MHz              */
            /*  SYSTEM.SCKCR2.BIT.IEBCK = 3;                        PLL/4 = 48MHz                            */
            /************************************************************************/

            SYSTEM.SCKCR.LONG = 0x21c22222; /* set these bits to the same a this bit   */
            /*                             |||               |                   |             */
            /*                             |++---------------+                   |             */
            /*                                                                    |                                     |             */
            /*                             +-------------------------------------+             */

            SYSTEM.SCKCR2.WORD = 0x0033;
            //          SYSTEM.SCKCR3.WORD = 0x0000;                            /* LOCO -> LOCO         */
            //          SYSTEM.SCKCR3.WORD = 0x0100;                            /* LOCO -> HOCO         */
            //          SYSTEM.SCKCR3.WORD = 0x0200;                            /* LOCO -> MAIN         */
            //          SYSTEM.SCKCR3.WORD = 0x0300;                            /* LOCO -> Sub-Clock    */
            SYSTEM.SCKCR3.WORD = 0x0400; /* LOCO -> PLL          */

            /* Gain access to the Port Function Select Registers */
            MPC.PWPR.BIT.B0WI = 0;
            MPC.PWPR.BIT.PFSWE = 1;
}
/* This variable is not used by this simple Blinky example.  It is defined
purely to allow the project to link as it is used by the full build
configuration. */
volatile unsigned long ulHighFrequencyTickCount = 0UL;

/*-----------------------------------------------------------*/


/* A callback function named vApplicationSetupTimerInterrupt() must be defined
to configure a tick interrupt source, and configTICK_VECTOR set in
FreeRTOSConfig.h to install the tick interrupt handler in the correct position
in the vector table.  This example uses a compare match timer.  It can be
into any FreeRTOS project, provided the same compare match timer is available. */
void vApplicationSetupTimerInterrupt( void )
{
            /* Enable compare match timer 0. */
            MSTP( CMT0 ) = 0;

            /* Interrupt on compare match. */
            CMT0.CMCR.BIT.CMIE = 1;

            /* Set the compare match value. */
            CMT0.CMCOR = ( unsigned short ) ( ( ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ) -1 ) / 8 );

            /* Divide the PCLK by 8. */
            CMT0.CMCR.BIT.CKS = 0;

            /* Enable the interrupt... */
            _IEN( _CMT0_CMI0 ) = 1;

            /* ...and set its priority to the application defined kernel priority. */
            _IPR( _CMT0_CMI0 ) = configKERNEL_INTERRUPT_PRIORITY;

            /* Start the timer. */
            CMT.CMSTR0.BIT.STR0 = 1;
}

7.- En el archivo vect.h comentar las siguientes interrupciones que se utilizan en el stack FreeRTOS:

// ICU SWINT
//#pragma interrupt (Excep_ICU_SWINT(vect=27))
//void Excep_ICU_SWINT(void);

// CMT0 CMI0
//#pragma interrupt (Excep_CMT0_CMI0(vect=28))
//void Excep_CMT0_CMI0(void);

8.- La carpeta del stack FreeRTOS así como los demás archivos se muestran a continuación:


9.- La función principal main.c queda de la siguiente forma:

#include <stdio.h>
#include "iodefine.h"

/* Kernel includes. */
#include "FreeRTOS/FreeRTOS.h"
#include "FreeRTOS/task.h"
#include "FreeRTOS/queue.h"

/* Priorities at which the tasks are created. */
#define configQUEUE_TASK_1_PRIORITY         ( tskIDLE_PRIORITY + 1 )
#define    configQUEUE_TASK_2_PRIORITY      ( tskIDLE_PRIORITY + 2 )
#define    configQUEUE_TASK_3_PRIORITY      ( tskIDLE_PRIORITY + 3 )
#define    configQUEUE_TASK_4_PRIORITY      ( tskIDLE_PRIORITY + 4 )


void vTask1(void *pvParameters)
{
            while(1) {
                        PORTD.PODR.BIT.B5 = ~PORTD.PODR.BIT.B5;
                        vTaskDelay(100/portTICK_PERIOD_MS);
            }
}
void vTask2(void *pvParameters)
{
            while(1) {
                        PORTD.PODR.BIT.B2 = ~PORTD.PODR.BIT.B2;
                        vTaskDelay(200/portTICK_PERIOD_MS);
            }
}

void vTask3(void *pvParameters)
{
            while(1) {
                        PORTD.PODR.BIT.B4 = ~PORTD.PODR.BIT.B4;
                        vTaskDelay(300/portTICK_PERIOD_MS);
            }
}

void vTask4(void *pvParameters)
{
            while(1) {
                        PORTD.PODR.BIT.B1 = ~PORTD.PODR.BIT.B1;
                        vTaskDelay(400/portTICK_PERIOD_MS);
            }
}

void main(void)
{
            /* Renesas provided CPU configuration routine.  The clocks are configured in
            here. */

            /* Turn all LEDs off. */
            PORTD.PODR.BYTE = 0xFF;
            PORTD.PDR.BYTE = 0xFF;
            PORTD.PMR.BYTE = 0x00;


            xTaskCreate(vTask1,"Task1",configMINIMAL_STACK_SIZE,NULL,configQUEUE_TASK_1_PRIORITY,NULL);
            xTaskCreate(vTask2,"Task2",configMINIMAL_STACK_SIZE,NULL,configQUEUE_TASK_2_PRIORITY,NULL);
            xTaskCreate(vTask3,"Task3",configMINIMAL_STACK_SIZE,NULL,configQUEUE_TASK_3_PRIORITY,NULL);
            xTaskCreate(vTask4,"Task4",configMINIMAL_STACK_SIZE,NULL,configQUEUE_TASK_4_PRIORITY,NULL);


            /* Create the queue. */
            vTaskStartScheduler();

            /* If all is well the next line of code will not be reached as the scheduler
            will be    running.  If the next line is reached then it is likely that there was
            insufficient heap available for the idle task to be created. */
            for( ;; );
}


  • Agregar código, compilar y debug:
1.- Bajar el código de:
--> Practica #19

2.- Compilar con el icono del martillo y debug con el icono del insecto:


VÍDEO:

No hay comentarios.:

Publicar un comentario