freeRTOSではデフォルトのスタックサイズ128wordsはFFTなどやらせると少なすぎます
どうなるかというとスタック食い潰して暴走するのが普通
<環境>
・STM32F401re
・CubeIDE 1.19.0(@M4 MacBook Pro Tahoe)
・タスク構成:default task/ADC結果をFFTするタスク(fft_task)/LCD表示制御用のタスク(lcd_task)
<スタックサイズ設定>
128wordsでは全く不足と思ったので1024wordsにしたらちゃんと動くようになった、以下はfreertosタスクの設定値、CubeMXで設定すると反映もされますがコードで入力もできる
<スタックサイズの取得>
おそらく一番スタックを消費するであろうfft_taskの最後部分に以下のコードを埋め込み
デバッガー起動してosDelay(1)をbreakpointにして取得した値は以下のとおり
単位はbytesだからword換算だとおよそ230wordsということなで、8割近くは消費しています、この変数はコード実行中の最小値を記録しているらしい
<FFTの実行結果>
まだLCDには表示できないので、デバッガーで取得した値をグラフ化してみた図
FFT実行部分のコード(ADC DMAのISRから起動されて、その後に計算実行
uint32_t flags = osThreadFlagsWait(0x01 | 0x02, osFlagsWaitAny, // 0x01:half, 0x02:full
osWaitForever);
/* 1. int16 → float */
uint32_t base = (flags & 0x01) ? 0 : ADC_RAW_LEN;// buffer start point set
for (uint32_t i = 0; i < ADC_RAW_LEN; i++) {
adc_q15_buf[i] = ((int16_t) adc_dma_buff[base + i] - 2048) << 4;
}
arm_q15_to_float(adc_q15_buf, adc_float_buf, ADC_RAW_LEN);
/* 2. IIR + 1/5 デシメーション */
uint32_t idx = 0;
for (uint32_t i = 0; i < ADC_RAW_LEN; i += DECIMATE_FACTOR)
{
float32_t tmp;
arm_biquad_cascade_df2T_f32(&iir_inst, &adc_float_buf[i], &tmp, 1);
decimated_buf[idx++] = tmp;
}
/* 3. 窓関数適用*/
arm_mult_f32(decimated_buf, hann_window, windowed_input, FFT_LEN);
/* 4. FFT実行 */
arm_rfft_fast_f32(&fft_inst, windowed_input, fft_out, 0);
/* 5. 実効値計算(振幅スペクトル : db) */
for (uint32_t i = 0; i < FFT_LEN / 2; i++) {
float32_t real = fft_out[2 * i];
float32_t imag = fft_out[2 * i + 1];
fft_rms[i] = 10.0f
* log10f(
(real * real + imag * imag) * HANN_GAIN_CORRECTION
+ 1e-12f);
}
admin



