Despite the 5-year old 6865 post about a similar issue with CMSIS FFT, I still wish to ask about debugging memory corruption issues when using an FFT library. I successfully used CMSIS to run a FFT (correlation) in QEMU for the TI Stellaris as shown with
void do_fft(void* param)
{char c[20];
q31_t *in=param;
arm_cfft_q31(&arm_cfft_sR_q31_len256, in, 0, 1); // FFT
while(1) {vTaskDelay(301/portTICK_RATE_MS);}
}
int main()
{// static uint32_t c1[2*N],c2[2*N],meas[2*N]; // N*4*2 bytes crashes
static int32_t *c0,*c1,*c2,*meas; // N*4*2 bytes OK
int k;
c0=(int32_t*)malloc((2*N+1)*sizeof(int32_t));
c1=(int32_t*)malloc((2*N+1)*sizeof(int32_t));
c2=(int32_t*)malloc((2*N+1)*sizeof(int32_t));
meas=(int32_t*)malloc((2*N+1)*sizeof(int32_t));
#define S 4096
if (!(pdPASS == xTaskCreate( do_fft, (const char*) "fft1", STACK_BYTES(S), c1, 1,NULL ))) {uart_puts("1\0");goto hell;}
if (!(pdPASS == xTaskCreate( do_fft, (const char*) "fft2", STACK_BYTES(S), c2, 3,NULL ))) {uart_puts("2\0");goto hell;}
if (!(pdPASS == xTaskCreate( do_fft, (const char*) "fftm", STACK_BYTES(S), meas,2,NULL ))) {uart_puts("3\0");goto hell;}
However CMSIS uses ARM assembly language, preventing cross-platform portability amongst non-ARM architectures. I hence wish to replace CMSIS with KISSFFT. To avoid al FPU related issues, I compile KISSFFT as a Q31 fixed point library I link against. Baremetal examples works well as shown below
void do_fft(kiss_fft_cpx *in,kiss_fft_cpx *out,int direction)
{char c[20];
kiss_fft_cfg cfg;
uart_puts("fft\0");
/* solution 1
if (direction==0) kfc_fft(N,in,out);
else kfc_ifft(N,in,out);
kfc_cleanup();
*/
/* solution 2 */
if ((cfg = kiss_fft_alloc(N, direction, NULL, NULL)) != NULL)
{kiss_fft( cfg , in , out );
kiss_fft_free(cfg);
}
else uart_puts("FFT out of memory\0");
uart_putc(':');hex(in[N].r,c); uart_puts(c);uart_puts("\n\0");
}
int main()
{kiss_fft_cpx *in,*out1,*out2,*outm;
int k;
char c[9];
in =(kiss_fft_cpx*)malloc((N+1)*sizeof(kiss_fft_cpx));
out1 =(kiss_fft_cpx*)malloc((N+1)*sizeof(kiss_fft_cpx));
out2 =(kiss_fft_cpx*)malloc((N+1)*sizeof(kiss_fft_cpx));
outm =(kiss_fft_cpx*)malloc((N+1)*sizeof(kiss_fft_cpx));
for (k=0;k<N;k++) {in[k].r=(pattern1[k]<<30);in[k].i=0;}
for (k=0;k<3;k++)
{hex(k,c);uart_puts(c);uart_putc(':');
do_fft(in,out1,0);
}
for (k=0;k<N;k++) {in[k].r=(pattern2[k]<<30);in[k].i=0;}
for (k=0;k<3;k++)
{hex(k,c);uart_puts(c);uart_putc(':');
do_fft(in,out2,0);
}
However, calling the do_fft() function found in the baremetal example as a FreeRTOS task crashes at the third instance (the first two tasks complete properly). I have stack corruption detection active, am using heap_4.c from the CM4, and gdb tells me that after the second task completed the FFT and the third do_fft() is supposed to be launched, the CPU hangs in a blocking_handler(void)
infinite loop which is the libopencm3 way of handling hard_fault_handler
, mem_manage_handler
, or bus_fault_handler
.
I have no clue how to debug this as it sounds like a kernel task launching issue, happening whether the *in
and *out
buffers used for the FFT are created within the task or in the main() and passed as void*(pointer), whether I statically allocate in[N]
and out[N]
or whether I pvPortMalloc
and vPortFree
, even protecting the task with a mutex to make sure it is not preempted.
Any clue on how to debug this issue?
Thanks