【问题标题】:ESP32 hardware ISR sometimes not triggered when wifi is transmittingwifi 传输时,ESP32 硬件 ISR 有时不会触发
【发布时间】:2022-11-04 17:30:06
【问题描述】:

我尝试使用硬件计时器定期从外部设备读取数据。 更具体地说,我实现了一个使用 gpio 模拟 SPI 协议的自定义驱动程序,每当发生硬定时器中断时,都会调用该驱动程序来读取 gpio 状态。计时器设置为 2k。

当中断发生时,isr 应将样本数据放入缓冲区。当缓冲区满时,应用程序会暂停定时器,并通过 mqtt 协议将这些数据发送出去。使用信号发生器和示波器,我发现数据很好。整个过程按预期进行。

问题是采样过程不是连续的。当通过wifi发送数据时,定时器暂停,没有数据可以读入缓冲区。

为了解决这个问题,我创建了一个专门的任务来负责向外传输数据。然后我使用乒乓缓冲区来存储样本数据。当一个缓冲区满时,通知发送任务将这些数据发送出去,同时定时器isr不断将数据放入另一个缓冲区。
起初我想只从 isr 发送通知(使用 xQueueSendFromISR()),这被证明是不可靠的。我发现只有少数通知能够发送到发送任务。所以我不得不使用旗帜。当一个缓冲区已满时,该标志设置为真,当一个特殊任务循环这个标志时,只要发现该标志为真,就会通知发送任务。

timer_isr()
{
    
    read_data_using_gpio;
    if(one buffer is full)
    {
        set the flag to true
    }
}

task_1()
{
    while(1)
    {
        if(the flag is true)
        {
            set the flag to false;
            xQueueSend;
        }
        vTaskDelay(50ms)//it will cost 200ms to fill up the buffer
    }

}

task_2()
{
    while(1)
    {
        xStatus = xQueueReceive;
        if(xStatus==pdPASS) // A message from other tasks is received.
        {
            transmitting data out using mqtt protocol.
        }
    }

}

然后我得到了如下可怕的数据。 terroble data 我用示波器检查了isr中的gpio操作。 oscilloscope1 oscilloscope2 所以似乎有些 isr 没有被触发?但发生了什么?

更奇怪的是:我添加了另一个任务,通过 i2s 从音频芯片获取数据。我再次使用乒乓缓冲区并将通知发送到同一个发送任务。

timer_isr()
{
    
    read_data_using_gpio;
    if(one buffer is full)
    {
        set the flag to true
    }
}

task_1()
{
    while(1)
    {
        if(the flag is true)
        {
            set the flag to false;
            xQueueSend;
        }
        vTaskDelay(50ms)
    }

}
task_3()
{
    while(1)
    {
        i2s_read_to_buffer;
        xQueueSend;
    }
}
task_2()
{
    while(1)
    {
        xStatus = xQueueReceive;
        if(xStatus==pdPASS) // A message from other tasks is received.
        {
            if(data from task_1)
            {
                do something;
                transmitting data out using mqtt protocol
            }
            if(data from task_2)
            {
                do something;
                transmitting data out using mqtt protocol
            }
            
        }
    }

}

而这一次,前一个任务的数据变好了! data_ok

而且,我在发送任务中注释了任务2相关代码后,数据又变坏了! 所以发生了什么事?有人可以给出任何提示吗?

task_2()
{
    while(1)
    {
        xStatus = xQueueReceive;
        if(xStatus==pdPASS) // A message from other tasks is received.
        {
            if(data from task_1)
            {
                do something;
                transmitting data out using mqtt protocol
            }
            if(data from task_2)
            {
                // do something;
                // transmitting data out using mqtt protocol
            }
            
        }
    }

}

【问题讨论】:

    标签: wifi esp32 freertos isr esp-idf


    【解决方案1】:

    我已经解决了这个问题。 如果启用电源管理(idf.py menuconfig-->component config-->power management),APB(advanced peripheral bus)会自动降低频率,这是硬件定时器的时钟源。这样你会看到定时器中断不稳定。 只需禁用电源管理即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多