为什么AVR中断向量不能是__属性__((弱))'?

时间:2017-08-03 10:15:07

标签: interrupt avr-gcc

我刚刚尝试将__attribute__ ((weak))添加到我的一个中断处理程序定义中,我注意到没有实现向量跳转 - 但是中断体出现在已编译的二进制文件中。

示例,"弱"中断:

ISR(TIMER1_COMPA_vect, __attribute__ ((weak)))
{
    // some compiled code
    ...
}

产生的汇编代码 - 没有跳转:

    00000000 <__vectors>:
       0:   48 c0           rjmp    .+144           ; 0x92 <__ctors_end>
       4:   92 c0           rjmp    .+292           ; 0x12a <__bad_interrupt>
       8:   90 c0           rjmp    .+288           ; 0x12a <__bad_interrupt>
       c:   8e c0           rjmp    .+284           ; 0x12a <__bad_interrupt>
      10:   8c c0           rjmp    .+280           ; 0x12a <__bad_interrupt>
      14:   8a c0           rjmp    .+276           ; 0x12a <__bad_interrupt>
      18:   88 c0           rjmp    .+272           ; 0x12a <__bad_interrupt>
      1c:   86 c0           rjmp    .+268           ; 0x12a <__bad_interrupt>
      20:   84 c0           rjmp    .+264           ; 0x12a <__bad_interrupt>
      24:   82 c0           rjmp    .+260           ; 0x12a <__bad_interrupt>
      28:   80 c0           rjmp    .+256           ; 0x12a <__bad_interrupt>
      2c:   7e c0           rjmp    .+252           ; 0x12a <__bad_interrupt>
      30:   7c c0           rjmp    .+248           ; 0x12a <__bad_interrupt>
      34:   7a c0           rjmp    .+244           ; 0x12a <__bad_interrupt>
      38:   78 c0           rjmp    .+240           ; 0x12a <__bad_interrupt>
      3c:   76 c0           rjmp    .+236           ; 0x12a <__bad_interrupt>
      40:   74 c0           rjmp    .+232           ; 0x12a <__bad_interrupt>
      44:   72 c0           rjmp    .+228           ; 0x12a <__bad_interrupt>
      48:   70 c0           rjmp    .+224           ; 0x12a <__bad_interrupt>
      4c:   6e c0           rjmp    .+220           ; 0x12a <__bad_interrupt>
      50:   6c c0           rjmp    .+216           ; 0x12a <__bad_interrupt>
      54:   6a c0           rjmp    .+212           ; 0x12a <__bad_interrupt>
      58:   68 c0           rjmp    .+208           ; 0x12a <__bad_interrupt>
      5c:   66 c0           rjmp    .+204           ; 0x12a <__bad_interrupt>
      60:   64 c0           rjmp    .+200           ; 0x12a <__bad_interrupt>
      64:   62 c0           rjmp    .+196           ; 0x12a <__bad_interrupt>
      68:   60 c0           rjmp    .+192           ; 0x12a <__bad_interrupt>
      6c:   5e c0           rjmp    .+188           ; 0x12a <__bad_interrupt>

现在没有weak属性:

    00000000 <__vectors>:
       0:   48 c0           rjmp    .+144           ; 0x92 <__ctors_end>
       4:   92 c0           rjmp    .+292           ; 0x12a <__bad_interrupt>
       8:   90 c0           rjmp    .+288           ; 0x12a <__bad_interrupt>
       c:   8e c0           rjmp    .+284           ; 0x12a <__bad_interrupt>
      10:   8c c0           rjmp    .+280           ; 0x12a <__bad_interrupt>
      14:   8a c0           rjmp    .+276           ; 0x12a <__bad_interrupt>
      18:   88 c0           rjmp    .+272           ; 0x12a <__bad_interrupt>
      1c:   29 c0           rjmp    .+82            ; 0x70 <__vector_7>
      20:   84 c0           rjmp    .+264           ; 0x12a <__bad_interrupt>
      24:   82 c0           rjmp    .+260           ; 0x12a <__bad_interrupt>
      28:   80 c0           rjmp    .+256           ; 0x12a <__bad_interrupt>
      2c:   7e c0           rjmp    .+252           ; 0x12a <__bad_interrupt>

            ...

这是avr-gcc中的错误(我尝试过版本 5.3.x 7.1.0 )还是错过了什么?

1 个答案:

答案 0 :(得分:3)

avr-libc使用弱符号实现ISR向量表,以便您的代码可以将正确的符号定义为非弱,以覆盖默认的ISR处理程序__bad_interrupt(参见crt1/gcrt1.S avr-libc代码。)

因此,只有非弱ISR才能覆盖avr-libc的弱ISR。

如果您需要这种可覆盖性,您可能希望将非弱ISR调用作为弱函数。