Hello,
I’m running freeRTOS on STM32F4. I have no problem with using cmsis-dsp functions without freeRTOS.
But when I want to call a function (in which cmsis-dsp functions like arm_cfft_radix4_f3,arm_rfft_f32 ,… are called) from a task(thread):
1.If I pass local arrays (defined in that task) as fft input and output ,output becomes zero!!
2.If I pass global arrays, I have non-zero(correct) output, but using global variables in freeRTOS tasks can cause some problems as we know.
3.If I pass global arrays as fft input and output but send output to another task using queues I receive zero values there!!
I don’t know if there is problem with freeRTOS variables that is defined in its heap and cmsis-dsp functions defined out of freeRTOS heap.
How are you passing the data via a queue? Do you just queue a pointer
to the data? That might not work if the array is on the stack but the
tack frame no longer exists. I presume you are talking about the task
stack, not the stack of main(), as the main() stack will also no longer
exist.
Stack overflow method 1 is turned on. Heap size for my task is sufficeint and no overflow is occurred. I pass data via queue using pointer to an array defined in task stack. Note that I use cmsis-rtos functions so instead of xQueueSend or xQueueReceive I have osMailPut and osMailGet but they are defined based on freeRTOS functions as you know.
Here is my code:
void waveformFFT(float32_t *input,float32_t *output,uint16_t fftSize)
{
arm_cfft_radix4_instance_f32 fftStruct;
arm_cfft_radix4_init_f32(&fftStruct,fftSize,0,1);
arm_cfft_radix4_f32(&fftStruct,input);
arm_cmplx_mag_f32(input, output, fftSize);
}
// waveformProcess task
void waveformProccess(void const * argument)
{
/* USER CODE BEGIN waveformProccess /
uint16_t i,j,k;
osEvent tenCycle;
uint16_t buffAddr,waveSample;
uint8_t hBuff[4480];
uint8_t cylceNum;
int32_t waveBuff[256];
float32_t fftRes[256];
char uartBuff[20];
waveformInfo waveInfo= (waveformInfo )osMailAlloc(waveToUarthandle,100);
/ Infinite loop /
for(;
{
tenCycle=osSignalWait(BIT_0,200); // waits for recieveing waveform ten cycle samples.
if(tenCycle.status == osEventSignal)
{
for(i=0;i<4480;i++)
hBuff[i]=hBuff_t[i];
for(i=0 ; i <160 ; i++){
waveBuff[160cylceNum+i]=(uint32_t)(hBuff[28i+4] << 24 ) | (uint32_t)(hBuff[28i+5] << 16 ) | (uint32_t)(hBuff[28i+6] << 8 ) | (uint32_t)(hBuff[28i+7]); //
waveInfo->waveform[i]=waveBuff[i];
}
cylceNum++;
// Take FFT of one cycle of waveform
if(cylceNum==1)
{
osMailFree(waveToUarthandle,waveInfo);
waveformInfo *waveInfo= (waveformInfo *)osMailAlloc(waveToUarthandle,100);
for(i=160;i<256;i++)
{
waveBuff[i]=0;
waveInfo->waveform[i]=waveBuff[i];
}
waveformFFT((float32_t )waveBuff,fftRes,256);
cylceNum = 0;
for(i=0;i<256;i++)
{
waveInfo->waveFFT[i]=fftRes[i];
}
osMailPut(waveToUarthandle,waveInfo); // sends fft input and output to uart task using mail.
}
}
}
/ USER CODE END waveformProccess */
}
I have the same problem if I use cmsis-dsp function directly in the task ( instead of calling a function like waveformProccess in which cmsis-dsp functions are called)
Please help me with this problem/
Thanks
I pressed on Post too early, wanted to ask you more:
Can you make sure that all floating point variables on stack are well-aligned?
but using global variables in freeRTOS tasks can cause some problems as we know
I don’t know, why? It is considered as “bad practice” to use global variables, but they don’t cause problems as such.
You can also make them static within the module, or static within the function. When you do that, the function can run with a normal-size stack.
Don’t you check the result of osMailAlloc()? Can it fail?
but send output to another task using queues I receive zero values there!!
How do you send these values? Does each byte go into a FreeRTOS queue? Or do you allocate a new buffer and pass a pointer ( and the ownership ) of the buffer to the queue?