打印
[技术讨论]

【RA生态开发板-RA-Eco-RA4M2】3.RA4M2开发板FreeRTOS开发

[复制链接]
114|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

RA生态开发板RAEco-RA4M2使用:

[【RA生态开发板-RA-Eco-RA4M2】1.RA4M2开发板硬件资源以及开发环境搭建]https://bbs.21ic.com/icview-3443748-1-1.html

[【RA生态开发板-RA-Eco-RA4M2】2.RA4M2开发板CTSU使用]https://bbs.21ic.com/icview-3443780-1-1.html

触摸按键的检测程序采用轮询的方式,对嵌入式处理器的资源效率不高,可以通过使用操作系统来改善这一情况。FreeRTOS是嵌入式开发中常见的嵌入式操作系统。借助FSP配置工具,用户可以快速配置FreeRTOS、定义任务、分配资源,快速地实现FreeRTOS应用的开发。

在创建工程页面,将NORTOS下拉框改为FreeRTOS

project_rtos_selection.png

创建工程后,在FSP的Stacks界面可以创建和配置外设的驱动、软件栈,还可以定义FreeRTOS的线程,配置FreeRTOS组件。

FreeRTOS_Component_create.png

通过使用FreeRTOS,实现触摸控制LED和串口通讯调节LED亮度。前面实现了这两个功能的裸机程序。通过创建任务和信号量,修改原有的代码,将两个功能添加到同一个程序中。

创建触摸控制LED任务

在Stack中创建Thread对象,FSP配置工具会创建FreeRTOS中相应的线程。线程的属性栏分为Common和Thread。Thread是对创建线程的定义、线程的创建方式等。

ctsu_monitor_thread_prop.png

Common是对FreeRTOS进行配置,其实是FreeRTOS_Config.h的中部分配置的图形化工具。

RTOS_common_thread_prop.png

在对应的任务中添加硬件资源,可以限制该硬件资源用于该线程使用。任务中使用到的是触摸按键,对应添加触摸按键的Touch驱动,同时添加对动态内存管理的支持。

Thread_stacks.png

完成触摸按键监控进程的创建。在系统中会出现名为ctsu_monitor_thread_entry.c的文件,其中有对应线程的定义。

thread_generate_src.png

[【RA生态开发板-RA-Eco-RA4M2】2.RA4M2开发板CTSU使用]https://bbs.21ic.com/icview-3443780-1-1.html实现触摸按键控制LED的功能。参考其中利用QE for Capacitive生成触摸按键驱动的过程,生成对应的触摸驱动和监控程序。

在ctsu_monitor_thread_entry.c中,调用按键检测的主函数qe_touch_main(),同时添加LED的相关代码。这样,很快就可以把触摸按键处理的功能移植到这里。ctsu_monitor_thread_entry.c的源码如下

//添加触摸触动头文件、bsp头文件
#include "ctsu_monitor_thread.h"
#include "qe_touch_config.h"
#include "bsp_api.h"
#define TOUCH_SCAN_INTERVAL_EXAMPLE (20)    /* milliseconds */

/****按键和LED相关的结构体****/
static uint64_t button_status;
static uint64_t button_status_pre;
static uint16_t count;
static uint8_t press_valid;
static uint8_t press_valid_pre;

/** Array of LED IOPORT pins. */
static const uint16_t g_bsp_prv_leds[] =
{
    (uint16_t) BSP_IO_PORT_04_PIN_04,  ///< LED2
    (uint16_t) BSP_IO_PORT_00_PIN_02,  ///< LED3
};

/** Information on how many LEDs and what pins they are on. */
typedef struct st_bsp_leds
{
    uint16_t         led_count;        ///< The number of LEDs on this board
    uint16_t const * p_leds;           ///< Pointer to an array of IOPORT pins for controlling LEDs
} bsp_leds_t;

const bsp_leds_t g_bsp_leds =
{
    .led_count = (uint16_t) ((sizeof(g_bsp_prv_leds) / sizeof(g_bsp_prv_leds[0]))),
    .p_leds    = &g_bsp_prv_leds[0]
};

typedef enum e_bsp_led
{
    BSP_LED_LED2,                      ///< LED2
    BSP_LED_LED3,                      ///< LED3
} bsp_led_t;

/* Holds level to set for pins */
bsp_io_level_t pin_level_led2 = BSP_IO_LEVEL_LOW;
bsp_io_level_t pin_level_led3 = BSP_IO_LEVEL_LOW;


/* Ctsu_monitor entry function */
/* pvParameters contains TaskHandle_t */
void ctsu_monitor_thread_entry(void *pvParameters)
{
    FSP_PARAMETER_NOT_USED (pvParameters);

    /* TODO: add your own code here */
    fsp_err_t err;
    R_BSP_PinAccessEnable();
    /* Open Touch middleware */
    err = RM_TOUCH_Open(g_qe_touch_instance_config01.p_ctrl, g_qe_touch_instance_config01.p_cfg);
    if (FSP_SUCCESS != err)
    {
        while (true) {}
    }

    /* Main loop */
    while (true)
    {
        /* for [CONFIG01] configuration */
        err = RM_TOUCH_ScanStart(g_qe_touch_instance_config01.p_ctrl);
        if (FSP_SUCCESS != err)
        {
            while (true) {}
        }
        while (0 == g_qe_touch_flag) {}
        g_qe_touch_flag = 0;

        err = RM_TOUCH_DataGet(g_qe_touch_instance_config01.p_ctrl, &button_status, NULL, NULL);
        if (FSP_SUCCESS == err)
        {
            /* TODO: Add your own code here. */
        }
        //触摸按键滤波处理以及LED登控制
        if(button_status!=0&&button_status_pre==button_status)
        {
            count++;
            if(count>10)
                press_valid=1;

            if(press_valid!=press_valid_pre)
            {
                switch(button_status)
                {
                    case 1:
                        /* Toggle level for next write */
                        if (BSP_IO_LEVEL_LOW == pin_level_led2)
                        {
                            pin_level_led2 = BSP_IO_LEVEL_HIGH;
                        }
                        else
                        {
                            pin_level_led2 = BSP_IO_LEVEL_LOW;
                        }
                        R_BSP_PinWrite((bsp_io_port_pin_t) g_bsp_leds.p_leds[0], pin_level_led2);
                        break;
                    case 2:
                        if (BSP_IO_LEVEL_LOW == pin_level_led3)
                        {
                            pin_level_led3 = BSP_IO_LEVEL_HIGH;
                        }
                        else
                        {
                            pin_level_led3 = BSP_IO_LEVEL_LOW;
                        }
                        R_BSP_PinWrite((bsp_io_port_pin_t) g_bsp_leds.p_leds[1], pin_level_led3);
                        break;
                    default:
                        ;
                }
            }

        }
        else if(button_status==0&&button_status_pre==button_status)
        {
            press_valid=0;
            count=0;
        }
        else
        {
            count=0;
        }

        button_status_pre=button_status;
        press_valid_pre=press_valid;


        /* 采用软件延时的方式周期性对触摸按键进行检测 */
        vTaskDelay(TOUCH_SCAN_INTERVAL_EXAMPLE);
    }
}

创建串口调节LED亮度任务

参考触摸按键处理进程的创建方式,在FSP中建立进程,同时添加串口、PWM等硬件驱动。FSP工具生成代码后,在工程中可以看到uart_ep_thread_entry.c,其中定义uart_ep_thread进程入口函数。

参考[【RA生态开发板-RA-Eco-RA4M2】1.RA4M2开发板硬件资源以及开发环境搭建]https://bbs.21ic.com/icview-3443748-1-1.html,添加对应的外设驱动并复制src文件夹中的文件。同样地,只需要将uart_ep_thread_entry.c中线程函数的代码,替换为逻辑程序中hal_entry中的代码即可

/* uart_ep entry function */
/* pvParameters contains TaskHandle_t */
void uart_ep_thread_entry(void *pvParameters)
{
    FSP_PARAMETER_NOT_USED (pvParameters);

    fsp_err_t err = FSP_SUCCESS;
    fsp_pack_version_t version = {RESET_VALUE};

    /* Version get API for FLEX pack information */
    R_FSP_VersionGet(&version);

    /* Example Project information printed on the Console */
    APP_PRINT(BANNER_1);
    APP_PRINT(BANNER_2);
    APP_PRINT(BANNER_3,EP_VERSION);
    APP_PRINT(BANNER_4,version.version_id_b.major, version.version_id_b.minor, version.version_id_b.patch );
    APP_PRINT(BANNER_5);
    APP_PRINT(BANNER_6);

    APP_PRINT("\r\n\r\nThe project initializes the UART with baud rate of 115200 bps.");
    APP_PRINT("\r\nOpen Serial Terminal with this baud rate value and");
    APP_PRINT("\r\nProvide Input ranging from 1 - 100 to set LED Intensity\r\n");

    /* Initializing GPT in PWM mode */
    err = gpt_initialize();
    if (FSP_SUCCESS != err)
    {
        APP_PRINT ("\r\n ** GPT TIMER INIT FAILED ** \r\n");
        APP_ERR_TRAP(err);
    }

    /* Starting GPT */
    err = gpt_start();
    if (FSP_SUCCESS != err)
    {
        APP_PRINT ("\r\n ** GPT START FAILED ** \r\n");
        timer_gpt_deinit();
        APP_ERR_TRAP(err);
    }

    /* Initializing UART */
    err = uart_initialize();
    if (FSP_SUCCESS != err)
    {
        APP_PRINT ("\r\n ** UART INIT FAILED ** \r\n");
        timer_gpt_deinit();
        APP_ERR_TRAP(err);
    }

    /* User defined function to demonstrate UART functionality */
    err = uart_ep_demo();
    if (FSP_SUCCESS != err)
    {
        APP_PRINT ("\r\n ** UART EP Demo FAILED ** \r\n");
        timer_gpt_deinit();
        deinit_uart();
        APP_ERR_TRAP(err)
    }
}

程序运行

编译完成后,调试并运行程序,可以实现触摸控制LED、UART调节LED亮度的功能。

03_FreeRTOS.gif

总结

瑞萨提供的FreeRTOS工具,对熟悉FreeRTOS的开发者来说,熟悉工具的使用后,可以很快地实现应用原型。

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

453

帖子

3

粉丝