【问题标题】:FIQ & IRQ mix usage causes kernel to freeze, why?FIQ 和 IRQ 混合使用导致内核冻结,为什么?
【发布时间】:2012-12-14 04:09:03
【问题描述】:

启用 3 个中断,1 个 UART 到 IRQ(串行端口),Timer1 到 IRQ(控制闪烁的 LED),Timer0 到 FIQ(生成输出步进信号)。

第一个 FIQ 处理程序为空:

void FIQ_HANDLER(void) __fiq
{
   if(FIQSTA & TIMER0)
   {
        T0CLR = 0;
        break;
   }
}

IRQ 处理程序:

void IRQ_HANDLER(void) __irq
{
   if(IRQSTA & TIMER1)
   {
        T1CLR = 0;
        MAKE_LED_FLASH();
        break;
   }
   if(IRQSTA & UART)
   {
        BLAH_BLAH_BLAH();
        break;
   }
}

上面的代码运行良好,LED 闪烁、UART 响应和其他功能都很好。但是在我向 FIQ 处理程序添加了一些代码之后,主要是设置一个计数器(uint16)并让 IO 变为高/低:

void FIQ_HANDLER(void) __fiq
    {
       if(FIQSTA & TIMER0)
       {
            if(cts>0)
            {
                IO_BLAH_BLAH_BLAH();
                cts--;
            }
            T0CLR = 0;
            break;
       }
    }

CPU 将在启动后几秒钟(约 2 秒)锁定自身,然后 LED 停止闪烁,UART 没有响应。甚至变量 cts 在开始时也设置为 0(因此无法输入 if())。

我最初认为这可能是因为 timer0 设置得太快(这样更多的 FIQ 堆叠在一起而更少被清除)。所以我将 timer0 设置为不那么频繁。而且..好吧,启动时似乎没问题,LED一直闪烁......但是如果我通过串行端口(UART)发送一些字符,系统会立即再次锁定。 -_-!怎么了?

如果我遗漏了要写在这里的任何重要信息,请告诉我。

【问题讨论】:

  • FIQ 多久触发一次?听起来它可能只是在消耗所有处理器时间。
  • 嗯.. 'IO_BLAH_BLAH_BLAH()' 函数使用 R0-R7 吗?我猜测实际的 FIQ 处理程序本身不会因为 '__fiq' 属性向编译器发出信号,只使用 R8-R14,但如果该处理程序调用其他任何内容,R0-R7 可能会损坏?

标签: embedded arm irq


【解决方案1】:

也许一个堆栈溢出并破坏了另一个堆栈。检查您是否已正确初始化 FIQ、IRQ 和其他堆栈,并且您已为每个堆栈保留足够的内存。

【讨论】:

  • +1 - 是的,另一个很好的可能性。到目前为止,我已经设法摆脱了完全不使用堆栈的全汇编 FIQ 处理程序,只使用交换寄存器,但并不总是可能......
  • 谢谢大家。我检查了汇编程序(在 IDE 中),发现了 IRQ 内存和代码优化的相关配置。刚刚关闭了所有的内存和代码优化。不能 100% 依赖这些处理程序了......
猜你喜欢
  • 2012-09-07
  • 2015-11-14
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 2012-11-26
  • 2017-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多