TouchGFX Core开放了几个信号,可用于测量性能。 当这些信号在内部触发时,用户可在应用程序中同步触发单个GPIO,从而实现“渲染时间”和其他有用信号的可视化。
信号在GPIO.hpp
中定义
/* 用于操作GPIO的接口类,以便在目标硬件上进行性能测量 */
class GPIO
{
public:
enum GPIO_ID
{
VSYNC_FREQ, //此引脚在每个VSYNC时切换状态
RENDER_TIME, //当帧渲染开始时,此引脚为高电平;完成时,为低电平
FRAME_RATE, //当帧缓冲交换时,此引脚切换状态
MCU_ACTIVE //当MCU正在工作(即不在空闲任务中)时,此引脚为高电平
};
/* 配置IO引脚的方法 */
static void init();
/**
* 将指定的引脚设置为高电平。
*
* @param id 要设置的引脚标识。
*/
static void set(GPIO_ID id);
/**
* 将指定的引脚设置为低电平。
*
* @param id 要设置的引脚标识。
*/
static void clear(GPIO_ID id);
/**
* 切换指定的引脚状态。
*
* @param id 要切换的引脚标识。
*/
static void toggle(GPIO_ID id);
/**
* 获取指定引脚的状态。
*
* @param id 要获取的引脚标识。
*
* @return 如果引脚为高电平,则返回true;否则返回false。
*/
static bool get(GPIO_ID id);
};
TouchGFX生成器为TouchGFXGPIO.cpp
文件中的GPIO类生成函数。 TouchGFX Core调用TouchGFXGPIO
类上的函数,根据STM32CubeMX中的用户配置,来翻转引脚。 GPIO::set
如下面的代码片段所示
#include <touchgfx/hal/GPIO.hpp>
#include "main.h"
using namespace touchgfx;
/* 配置IO引脚的方法 */
void GPIO::init()
{
}
/**
* 将指定的引脚设置为高电平。
*
* @param id 要设置的引脚标识。
*/
void GPIO::set(GPIO_ID id)
{
switch (id)
{
case GPIO::VSYNC_FREQ:
#if defined(VSYNC_FREQ_GPIO_Port) && defined(VSYNC_FREQ_Pin)
HAL_GPIO_WritePin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin, GPIO_PIN_SET);
#endif
break;
case GPIO::RENDER_TIME:
#if defined(RENDER_TIME_GPIO_Port) && defined(RENDER_TIME_Pin)
HAL_GPIO_WritePin(RENDER_TIME_GPIO_Port, RENDER_TIME_Pin, GPIO_PIN_SET);
#endif
break;
case GPIO::FRAME_RATE:
#if defined(FRAME_RATE_GPIO_Port) && defined(FRAME_RATE_Pin)
HAL_GPIO_WritePin(FRAME_RATE_GPIO_Port, FRAME_RATE_Pin, GPIO_PIN_SET);
#endif
break;
case GPIO::MCU_ACTIVE:
#if defined(MCU_ACTIVE_GPIO_Port) && defined(MCU_ACTIVE_Pin)
HAL_GPIO_WritePin(MCU_ACTIVE_GPIO_Port, MCU_ACTIVE_Pin, GPIO_PIN_SET);
#endif
break;
}
}
/**
* 将指定的引脚设置为低电平。
*
* @param id 要设置的引脚标识。
*/
void GPIO::clear(GPIO_ID id)
{
switch (id)
{
case GPIO::VSYNC_FREQ:
#if defined(VSYNC_FREQ_GPIO_Port) && defined(VSYNC_FREQ_Pin)
HAL_GPIO_WritePin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin, GPIO_PIN_RESET);
#endif
break;
case GPIO::RENDER_TIME:
#if defined(RENDER_TIME_GPIO_Port) && defined(RENDER_TIME_Pin)
HAL_GPIO_WritePin(RENDER_TIME_GPIO_Port, RENDER_TIME_Pin, GPIO_PIN_RESET);
#endif
break;
case GPIO::FRAME_RATE:
#if defined(FRAME_RATE_GPIO_Port) && defined(FRAME_RATE_Pin)
HAL_GPIO_WritePin(FRAME_RATE_GPIO_Port, FRAME_RATE_Pin, GPIO_PIN_RESET);
#endif
break;
case GPIO::MCU_ACTIVE:
#if defined(MCU_ACTIVE_GPIO_Port) && defined(MCU_ACTIVE_Pin)
HAL_GPIO_WritePin(MCU_ACTIVE_GPIO_Port, MCU_ACTIVE_Pin, GPIO_PIN_RESET);
#endif
break;
}
}
/**
* 切换指定的引脚状态。
*
* @param id 要切换的引脚标识。
*/
void GPIO::toggle(GPIO_ID id)
{
switch (id)
{
case GPIO::VSYNC_FREQ:
#if defined(VSYNC_FREQ_GPIO_Port) && defined(VSYNC_FREQ_Pin)
HAL_GPIO_TogglePin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin);
#endif
break;
case GPIO::RENDER_TIME:
#if defined(RENDER_TIME_GPIO_Port) && defined(RENDER_TIME_Pin)
HAL_GPIO_TogglePin(RENDER_TIME_GPIO_Port, RENDER_TIME_Pin);
#endif
break;
case GPIO::FRAME_RATE:
#if defined(FRAME_RATE_GPIO_Port) && defined(FRAME_RATE_Pin)
HAL_GPIO_TogglePin(FRAME_RATE_GPIO_Port, FRAME_RATE_Pin);
#endif
break;
case GPIO::MCU_ACTIVE:
#if defined(MCU_ACTIVE_GPIO_Port) && defined(MCU_ACTIVE_Pin)
HAL_GPIO_TogglePin(MCU_ACTIVE_GPIO_Port, MCU_ACTIVE_Pin);
#endif
break;
}
}
/**
* 获取指定引脚的状态。
*
* @param id 要获取的引脚标识。
*
* @return 如果引脚为高电平,则返回true;否则返回false。
*/
bool GPIO::get(GPIO_ID id)
{
GPIO_PinState bitstatus = GPIO_PIN_RESET;
switch (id)
{
case GPIO::VSYNC_FREQ:
#if defined(VSYNC_FREQ_GPIO_Port) && defined(VSYNC_FREQ_Pin)
bitstatus = HAL_GPIO_ReadPin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin);
#endif
break;
case GPIO::RENDER_TIME:
#if defined(RENDER_TIME_GPIO_Port) && defined(RENDER_TIME_Pin)
bitstatus = HAL_GPIO_ReadPin(RENDER_TIME_GPIO_Port, RENDER_TIME_Pin);
#endif
break;
case GPIO::FRAME_RATE:
#if defined(FRAME_RATE_GPIO_Port) && defined(FRAME_RATE_Pin)
bitstatus = HAL_GPIO_ReadPin(FRAME_RATE_GPIO_Port, FRAME_RATE_Pin);
#endif
break;
case GPIO::MCU_ACTIVE:
#if defined(MCU_ACTIVE_GPIO_Port) && defined(MCU_ACTIVE_Pin)
bitstatus = HAL_GPIO_ReadPin(MCU_ACTIVE_GPIO_Port, MCU_ACTIVE_Pin);
#endif
break;
}
return (bitstatus == GPIO_PIN_SET);
}
如果引脚具有用户标签VSYNC_FREQ CubeMX
将自动为端口、引脚生成匹配符号,例如VSYNC_FREQ_GPIO_Port
、VSYNC_FREQ_Pin
。 使用示波器或逻辑分析仪测量配置信号。 下图为显示了四个信号的逻辑分析仪图形。 该应用程序在STM32F746G-DISCO上运行,带有动画图像UI示例。 此应用的VSYNC
信号由LTDC每16ms生成一次。