我应该在中断程序中检索SPI数据吗?

时间:2019-01-11 18:33:01

标签: c freertos esp32

我将esp32用作具有​​24位ADC的spi主设备,该ADC使用SPI传输数据。 ADC表示可以通过降低连接到esp32的IO引脚来准备取回新样本。该SPI事务应该直接在gpio中断处理程序中还是在主循环中完成?我在想,也许只是在中断处理程序中设置一个标志,以指示一个新的样本已经准备好,然后在主循环中不断检查该标志。这是我之前所做的事情,因为我一直对中断例程花费的时间过长保持警惕。

2 个答案:

答案 0 :(得分:0)

在使用freeRTOS时,您应该有一个任务,可以从ADC读取数据。中断例程应仅通知(最有效的方法是使用直接任务通知)读取器任务。因此,在这种情况下,您的方法都不正确。

答案 1 :(得分:0)

您应该在中断处理程序中执行尽可能少的操作。不管您使用的是哪种平台或操作系统,这基本上都是正确的。

非中断级代码必须锁定中断,以确保中断处理程序不会干扰数据结构和I / O。

例如,在您的情况下,您询问是否应在中断处理程序中启动SPI事务。如果这样做,为了安全起见,您需要确保在中断处理程序之外使用SPI的任何地方都可以锁定中断。否则,如果发生中断,您有可能在SPI库或通过SPI访问的硬件中导致状态不一致,如果您在中断处理程序外部执行SPI库时也调用了SPI库。

数据结构也是如此。假设您在中断处理程序外部保留了一个链表,并在中断处理程序内部向其中添加了内容。如果中断在错误的时间发生,除非您在操作或遍历中断时锁定中断,否则都会破坏列表结构。

您希望最大程度地减少锁定中断的时间-锁定中断会干扰计时并导致数据丢失。

这意味着如果您在中断处理程序中进行的工作最少,则最好。这样一来,您就不必将中断锁定在外部,也不会错过任何中断或丢失数据,并且也不会冒损坏数据结构或使I / O硬件处于不一致状态的风险。忘记将中断锁定在代码的重要部分。

我们通常使用一个称为“信号量”的简单变量来指示发生了中断。中断处理程序可以增加信号量,而非中断级别的处理代码可以减少信号量。只要编译器可以在一条指令中管理信号灯,它就不会损坏。

在C语言中,我们需要将信号量变量声明为volatile,以便C编译器知道它随时可能更改。然后,编译器将生成不依赖于变量值在两次操作之间保持不变的代码。

volatile int got_interrupt = 0;

一个中断处理程序将简单地递增got_interrupt,并且在中断处理程序之外运行的代码将对其进行检查,如果它不为零,则将其递减并采取所需的任何操作(在您的情况下,请调用SPI库)。