我目前正在为 AVR 微控制器上的 USB 设备创建固件。由于 USB 时序非常严格,因此我不能允许非 USB 中断阻塞超过几个指令周期。因此,我的 USART RXC(接收到的字符)中断如下所示:
\n\nvoid usart_rxc_wrapped() __attribute__ ((interrupt));\nvoid usart_rxc_wrapped(){\n uint8_t c=UDR;\n if(!ringBufferFull(&rx)){\n ringBufferWrite(&rx, c);\n }\n // Reenable nterrupt\n UCSRB|=1<<RXCIE;\n}\n\n// This cannot be ISR_NOBLOCK, since the interrupt would go\n// into infinite loop, since we wouldn\'t get up to reading\n// UDR register. Instead, we use assembly to do the job\n// manually and then jump to the real handler.\nISR(USART_RXC_vect, ISR_NAKED){\n // Disable this interrupt by clearing its Interrupt Enable flag.\n __asm__ volatile("cbi %0, %1"::\n "I"(_SFR_IO_ADDR(UCSRB)),"I"(RXCIE));\n __asm__ volatile("sei"::);\n __asm__ volatile("rjmp usart_rxc_wrapped"::);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,我不能只将主中断代码放入 ISR 例程中,因为 avr-gcc 为该函数生成了相当长的序言(毕竟,我从那里调用其他函数,需要推送很多寄存器)。即使 C 代码中的第一条指令正在清除中断标志,它仍然会延迟许多周期。
\n\n这个解决方案工作正常,但我对 avr-gcc 的警告感到担心:
\n\nuart.c:128:6: warning: \xe2\x80\x98usart_rxc_wrapped\xe2\x80\x99 appears to be a misspelled interrupt handler\nRun Code Online (Sandbox Code Playgroud)\n\n这是因为我__attribute__((interrupt))在其定义中使用它是为了通知编译器保存寄存器,就像它是一个 ISR 一样。我在编译器中找不到任何选项来禁用此警告。有没有一种解决方法可以减少编译的噪音?或者也许有更好的方法来处理这种情况?
我发现了这个 8 年前的补丁:http://savannah.nongnu.org/bugs/download.php? file_id=15656 。显然,警告是无条件生成的(没有-WnoXXX编译标志)。但是,仅当函数名称不以 开头时,avr-gcc 才会生成此警告__vector。为了解决我的问题,我只是将包装函数重命名为__vector_usart_rxc_wrapped.
| 归档时间: |
|
| 查看次数: |
1481 次 |
| 最近记录: |