STM32 MCU 上 DSP 的中断安全 "FIFO"

Interrupt safe "FIFO" for DSP on STM32 MCU

我有一个 adc,它在中断时读取值并将它们存储在 FIFO 中。

在主程序中,我想像读取常规数组一样读取整个 FIFO,然后执行 FFT 之类的操作。经过一番思考,我意识到中断可能发生在读取过程中,并且数据不再准确。

这可以在不禁用中断的情况下完成吗?

我只找到了推送、弹出 FIFO 的示例,虽然我可以使用一个,但我想,我想知道这是否可行。

这是我的代码:

#define SP_FIFO_SIZE 4096
#define SP_BITMASK_SIZE (SP_FIFO_SIZE - 1)

struct sp_fifo_struct{
    uint16_t array[SP_FIFO_SIZE];
    uint16_t pointer;
};

typedef volatile struct sp_fifo_struct sp_fifo;

void sp_fifo_push(sp_fifo * fifo, uint16_t value){
    fifo->array[fifo->pointer] = value;
    fifo->pointer = ((fifo->pointer + 1) & SP_BITMASK_SIZE);
}

void sp_fifo_read(sp_fifo * fifo, float32_t array[]){
    for(uint16_t i = 0; i < SP_FIFO_SIZE; i++){
        array[i] = (float32_t) fifo->array[((fifo->pointer + i) & SP_BITMASK_SIZE)];
    }
}

在这种情况下,您当然需要互斥锁定您的 fifo。这不是 只有 的情况,当您可以保证数据的原子性 reads/writes 进入队列时。此外,incrementing/decrementing 您的索引变量 可能会或可能不会 是原子的,具体取决于您的硬件平台和数据类型。

关于数据处理,我不知道你的数据格式,不好说。我假设你有固定长度的数据。如果是这种情况,您的 fifo 可能是一个结构队列(固定长度数据的定义)而不是单个字节。这将确保队列的 read/writes 是 "atomic",因为你总是抓住一个 "data point"(无论你如何定义)。

Nordic 的 nRF5 SDK 具有 lock-free 和中断安全 FIFO,Atomic FIFO. It depends on LDREXB and LDREXH 指令。