Using CMSIS DSP Transform Functions (FFT)

Firmware/software/electronics/mechanics
Post Reply
rampudia
Beginner
Posts: 20
Joined: Fri Mar 26, 2021 4:21 pm

Using CMSIS DSP Transform Functions (FFT)

Post by rampudia »

Hi! I am trying to use CMSIS DSP transform functions inside a task I created for the Crazyflie but I am getting an "undefined reference error" (see below) which I find strange because I can successfully use other DSP functions like "arm_sqrt_f32" which I tried as a test. I have also tested the code that I am using in a different platform with an STM32F4 microcontroller so I think the problem is not in the way I am using the library.

Sample code:

Code: Select all

...
#include "arm_math.h"
#define SAMPLES 128
const int samplingFreq = 1000;
...

static void pdAdcTask(void* parameters) {
 
  DEBUG_PRINT("FFT test function is running!");
  
  //Configure delay
  float delay = 500 / portTICK_PERIOD_MS;
  DEBUG_PRINT("Delay in ticks is %f \n", delay);
  const TickType_t xDelay =  delay;

  //Some parameters
  int peakFrequency;
  int f = 150;
  int A = 58;

  while (true) {
    	//Force Delay
   	 vTaskDelay(xDelay);

    	//Create input signal
   	for(int i=0; i<SAMPLES; i++){
   		mySine[i] = A*arm_sin_f32(2*PI*f*i/samplingFreq);
   	}

   	//Create RFFT instance
   	arm_rfft_fast_instance_f32 S;
    	arm_rfft_fast_init_f32(&S, SAMPLES);

    	//RFFT transform
    	arm_rfft_fast_f32(&S, mySine,rfft_output,0);
    	//Calculate magnitude of imaginary coefficients
    	arm_cmplx_mag_f32(rfft_output,test_output, SAMPLES/2);
    	//Set DC component to 0
    	test_output[0] = 0;
    	//Obtain peak frequency
    	arm_max_f32(test_output, SAMPLES/2, &maxvalue, &maxindex);

    	peakFrequency = maxindex * samplingFreq / SAMPLES;

    	DEBUG_PRINT("Peak frequency %d \n\r", peakFrequency);

    	DEBUG_PRINT("Max Value:[%ld]:%f Output=[",maxindex,2*maxvalue/SAMPLES);
    	DEBUG_PRINT("]\r\n");
  }
}

Error when using "make clean && make":
bin/pd_adc.o: In function `pdAdcTask':
/home/bitcraze/Desktop/projects/crazyflie-firmware/.//src/modules/src/pd_adc.c:130: undefined reference to `arm_cfft_init_f32'
bin/libarm_math.a(arm_rfft_fast_init_f32.o): In function `arm_rfft_32_fast_init_f32':
arm_rfft_fast_init_f32.c:(.text.arm_rfft_32_fast_init_f32+0x8): undefined reference to `arm_cfft_init_f32'
bin/libarm_math.a(arm_rfft_fast_init_f32.o): In function `arm_rfft_64_fast_init_f32':
arm_rfft_fast_init_f32.c:(.text.arm_rfft_64_fast_init_f32+0x8): undefined reference to `arm_cfft_init_f32'
bin/libarm_math.a(arm_rfft_fast_init_f32.o): In function `arm_rfft_128_fast_init_f32':
arm_rfft_fast_init_f32.c:(.text.arm_rfft_128_fast_init_f32+0x8): undefined reference to `arm_cfft_init_f32'
bin/libarm_math.a(arm_rfft_fast_init_f32.o): In function `arm_rfft_256_fast_init_f32':
arm_rfft_fast_init_f32.c:(.text.arm_rfft_256_fast_init_f32+0x8): undefined reference to `arm_cfft_init_f32'
bin/libarm_math.a(arm_rfft_fast_init_f32.o):arm_rfft_fast_init_f32.c:(.text.arm_rfft_512_fast_init_f32+0xa): more undefined references to `arm_cfft_init_f32' follow
collect2: error: ld returned 1 exit status

I have tried modyfing the MakeFile in many ways and tried to include the source file explicitly but without success, perhaps you will have any ideas of what could be happening.
rampudia
Beginner
Posts: 20
Joined: Fri Mar 26, 2021 4:21 pm

Re: Using CMSIS DSP Transform Functions (FFT)

Post by rampudia »

In the Crazyflie firmware in tools/make/cmsis/dsp/obj.mk I see that "arm_cfft_init_f32.o" is not present, I tried to add it but I still get the same error when compiling the whole project.
rampudia
Beginner
Posts: 20
Joined: Fri Mar 26, 2021 4:21 pm

Re: Using CMSIS DSP Transform Functions (FFT)

Post by rampudia »

I found a solution:

1- I took the contents of the "CMSIS/CMSIS/DSP/Include/" directory from the CMSIS5 repository directly https://github.com/ARM-software/CMSIS_5 and placed them into a new folder called CMSIS5 inside the crazyflie-firmware --> "crazyflie-firmware/vendor/CMSIS/CMSIS/DSP/Include/CMSIS5/"
2- I placed the source file "arm_cfft_init_f32.c" from "... /DSP/Source/" inside a VPATH folder --> "modules/src/arm_cfft_init_f32.c"
3- I modified "tools/make/config.mk" and explicitly added the object file and includes directory:

Code: Select all

PROJ_OBJ += arm_cfft_init_f32.o
INCLUDES += -I$(CRAZYFLIE_BASE)/vendor/CMSIS/CMSIS/DSP/Include/CMSIS5/
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: Using CMSIS DSP Transform Functions (FFT)

Post by arnaud »

Thanks for posting a solution. This is very strange that it does not work, I tried as well and I saw the same problem as you. The reason we handle the cmsis dsp lib that way is to always compile it with optimization even in debug build, if the dsp lib is built in debug (no optimization) mode, the Kalman filter cannot run. Your workaround does not allow for that.

Anyway, it is great that you found a workaround, thanks for posting it! I am still curious as of why it did not work when compiling cmsis dsp to a lib...
Post Reply