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

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

通过使用FreeRTOS,实现触摸控制LED和串口通讯调节LED亮度。前面实现了这两个功能的裸机程序。通过创建任务和信号量,修改原有的代码,将两个功能添加到同一个程序中。
创建触摸控制LED任务
在Stack中创建Thread对象,FSP配置工具会创建FreeRTOS中相应的线程。线程的属性栏分为Common和Thread。Thread是对创建线程的定义、线程的创建方式等。

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

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

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

[【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亮度的功能。

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