乐鑫技术交流
直播中

俞舟群

7年用户 1073经验值
擅长:可编程逻辑 电源/新能源
私信 关注
[问答]

esp32设置高采样率,gpio_evt_queue会爆满而程序跑飞怎么解决?

我当前有这样一个项目:硬件上,一个24位ADC,是I2C接口+一个INT接ESP32;软件上,当这个ADC每次采样完成并准备好数据后,会通过INT脚发上升沿中断信号给ESP32;在ESP32里,基于ESP-IDF我是这样处理的:

定义I2C总线驱动;调用xQueueCreate(10, sizeof(uint32_t))创建gpio_evt_queue;定义gpio中断GPIO_PIN_INTR_POSEDGE类型,同时打开中断(中断发生时发送一个gpio_evt_queue);创建Task等待gpio_evt_queue,当接收到一个gpio_evt_queue时,通过I2C读ADC的采样数据;

目前我遇到的问题是:当ADC采样率设置低时,比如80HZ,程序能正常运行;但当设置到更高采样率,比如160HZ时,gpio_evt_queue会爆满而程序跑飞。试着把gpio_evt_queue尺寸调大,这只能延缓queue爆满的过程;试着在Task里,仅读ADC数据并保存到Buffer,仍然会queue爆满;

综上所述,感觉是task loop跟不上gpio中断,请问这样的问题如何优化好?
                                                                                                                                                            

回帖(1)

siyugege

2024-6-22 15:28:03
当ADC采样率设置较高时,例如1kHz或更高,gpio_evt_queue可能会因为事件过多而爆满,导致程序运行不稳定。为了解决这个问题,我们可以采取以下几个步骤:

1. **增加队列容量**:首先尝试增加gpio_evt_queue的大小。例如,将队列大小从10增加到50或100。这可以减少队列满的风险,但可能会增加内存使用。

2. **优化中断处理**:在中断服务程序中,尽量减少执行的操作。例如,只将事件放入队列,而不是立即读取ADC数据。这样可以减少中断处理时间,降低队列溢出的风险。

3. **使用DMA(Direct Memory Access)**:如果硬件和软件支持,可以考虑使用DMA来读取ADC数据。这样,数据可以直接从ADC传输到内存,而不需要CPU干预。这可以大大提高数据处理速度,降低队列溢出的风险。

4. **降低ADC采样率**:如果可能的话,尝试降低ADC的采样率。这可以减少事件的生成,降低队列溢出的风险。

5. **使用多任务处理**:创建多个任务来处理gpio_evt_queue中的事件。这样,当一个任务正在处理事件时,其他任务可以继续从队列中获取事件。这可以提高程序的响应速度,降低队列溢出的风险。

6. **使用事件标志**:考虑使用事件标志(event flags)而不是队列来处理中断。事件标志可以更快地通知任务,减少中断处理时间。

7. **优化I2C通信**:检查I2C通信是否优化。例如,使用I2C总线仲裁、增加I2C时钟频率等方法来提高I2C通信速度。

8. **监控和调试**:使用调试工具监控程序的运行情况,找出可能导致队列溢出的原因。例如,检查是否有任务在处理事件时被阻塞,或者是否有其他任务占用了大量CPU资源。

通过以上步骤,可以降低gpio_evt_queue爆满的风险,提高程序的稳定性。在实际应用中,可能需要根据具体情况调整这些步骤的优先级和实现方式。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分