通过测试FFT计算评估DSP性能,在 RW612 上实现快速傅里叶变换(FFT)可以通过 ARM CMSIS DSP 库完成。
添加 CMSIS DSP 库: 将 arm_math.h 和相关库文件添加到工程中,通过KEIL RTE一键添加十分方便:

然后添加一个测量时间的工具,Cortex-M内核的均支持,一键添加即可使用:

在LED例程基础上修改添加测试代码:
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_gpio.h"
#include "app.h"
#include "arm_math.h"
#include "arm_const_structs.h"
#include "perf_counter.h"
#define TEST_LENGTH_SAMPLES 2048
/* 输入和输出缓冲区 */
float32_t testInput_f32_10khz[TEST_LENGTH_SAMPLES]; // 输入信号
float32_t testOutput[TEST_LENGTH_SAMPLES / 2]; // 输出频谱
/* FFT 参数 */
uint32_t fftSize = 1024; // FFT 点数
uint32_t ifftFlag = 0; // 是否为逆FFT
uint32_t doBitReverse = 1; // 是否进行位反转
int fft_test(void) {
arm_status status;
float32_t maxValue;
uint32_t testIndex;
/* 初始化输入信号(示例数据) */
for (int i = 0; i < TEST_LENGTH_SAMPLES; i++) {
testInput_f32_10khz[i] = arm_sin_f32(2 * PI * i / TEST_LENGTH_SAMPLES);
}
/* 执行 FFT */
arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse);
/* 计算频谱幅值 */
arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);
/* 找到最大幅值及其索引 */
arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);
}
/*******************************************************************************
* Definitions
******************************************************************************/
#define APP_SW_STATE_RELEASED 0U
#define APP_SW_STATE_CONFIRM_PRESSED 1U
#define APP_SW_STATE_PRESSED 2U
#define APP_SW_STATE_CONFIRM_RELEASED 3U
#define APP_SW_FILTER_PERIOD 5
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
volatile uint32_t g_systickCounter;
uint8_t swState = APP_SW_STATE_RELEASED;
int8_t filter = -1;
/*******************************************************************************
* Code
******************************************************************************/
void SysTick_Handler(void)
{
if (g_systickCounter != 0U)
{
g_systickCounter--;
}
}
void SysTick_DelayTicks(uint32_t n)
{
g_systickCounter = n;
while (g_systickCounter != 0U)
{
}
}
/*!
* @brief Main function
*/
int main(void)
{
init_cycle_counter(true);
uint32_t port_state = 0;
/* Define the init structure for the output LED pin*/
gpio_pin_config_t led_config = {
kGPIO_DigitalOutput,
0,
};
/* Board pin, clock, debug console init */
BOARD_InitHardware();
/* Print a note to terminal. */
PRINTF("\r\n GPIO Driver example\r\n");
start_cycle_counter();
fft_test();
int64_t lCycleUsed = stop_cycle_counter();
PRINTF("cycle counter = %d\r\n",lCycleUsed);
PRINTF("\r\n The LED is taking turns to shine.\r\n");
/* Init output LED GPIO. */
GPIO_PortInit(GPIO, APP_BOARD_TEST_LED_PORT);
GPIO_PortInit(GPIO, APP_SW_PORT);
GPIO_PinInit(GPIO, APP_BOARD_TEST_LED_PORT, APP_BOARD_TEST_LED_PIN, &led_config);
GPIO_PinWrite(GPIO, APP_BOARD_TEST_LED_PORT, APP_BOARD_TEST_LED_PIN, 1);
/* Port masking */
GPIO_PortMaskedSet(GPIO, APP_BOARD_TEST_LED_PORT, 0x0000FFFF);
GPIO_PortMaskedWrite(GPIO, APP_BOARD_TEST_LED_PORT, 0xFFFFFFFF);
port_state = GPIO_PortRead(GPIO, APP_BOARD_TEST_LED_PORT);
PRINTF("\r\n Standard port read: %x\r\n", port_state);
port_state = GPIO_PortMaskedRead(GPIO, APP_BOARD_TEST_LED_PORT);
PRINTF("\r\n Masked port read: %x\r\n", port_state);
/* Set systick reload value to generate 1ms interrupt */
if (SysTick_Config(SystemCoreClock / 1000U))
{
while (1)
{
}
}
while (1)
{
port_state = GPIO_PortRead(GPIO, APP_SW_PORT);
switch (swState)
{
case APP_SW_STATE_RELEASED:
if (!(port_state & (1 << APP_SW_PIN)))
{
swState = APP_SW_STATE_CONFIRM_PRESSED;
filter = APP_SW_FILTER_PERIOD;
}
break;
case APP_SW_STATE_CONFIRM_PRESSED:
if (!(port_state & (1 << APP_SW_PIN)))
{
if (filter == 0)
{
PRINTF("\r\n Port state: %x\r\n", port_state);
GPIO_PortToggle(GPIO, APP_BOARD_TEST_LED_PORT, 1u << APP_BOARD_TEST_LED_PIN);
swState = APP_SW_STATE_PRESSED;
}
else
{
filter--;
}
}
else
{
swState = APP_SW_STATE_RELEASED;
}
break;
case APP_SW_STATE_PRESSED:
if ((port_state & (1 << APP_SW_PIN)))
{
swState = APP_SW_STATE_CONFIRM_RELEASED;
filter = APP_SW_FILTER_PERIOD;
}
break;
case APP_SW_STATE_CONFIRM_RELEASED:
if ((port_state & (1 << APP_SW_PIN)))
{
if (filter == 0)
{
swState = APP_SW_STATE_RELEASED;
}
else
{
filter--;
}
}
else
{
swState = APP_SW_STATE_PRESSED;
}
break;
default:
swState = APP_SW_STATE_RELEASED;
break;
}
SysTick_DelayTicks(1U);
}
}开启最大优化

测试结果

我要赚赏金
