如何避免类似ISR之间的代码重复?

dav*_*nio 0 c embedded refactoring

我有两个中断服务程序(ISR),基本上完全相同,但每个处理来自不同设备的中断(虽然是相同类型的设备).因此,逻辑是相同的,但它们访问不同的CPU寄存器和存储器位置.

作为一个简单的示例,请考虑以下代码:

extern volatile unsigned int dev1_rx_buffer;
extern volatile unsigned int dev2_rx_buffer;

volatile unsigned char data;

void __attribute__((__interrupt__)) _dev1_interrupt(void)
{
    /* Clear interrupt flag */
    dev1.IF = 0;

    if (dev1.IS_FULL) {
         /* Read data from device */
         data = dev1_rx_buffer;
    } else {
         /* do something else using registers of device 1 */
    }
    /* More stuff using registers of device 1 */
}

void __attribute__((__interrupt__)) _dev2_interrupt(void)
{
    /* Clear interrupt flag */
    dev2.IF = 0;

    if (dev2.IS_FULL) {
         /* Read data from device */
         data = dev2_rx_buffer;
    } else {
         /* do something else using registers of device 2 */
    }
    /* More stuff using registers of device 2 */
}
Run Code Online (Sandbox Code Playgroud)

如何避免代码重复与适用于ISR的限制(即我不能将参数传递给ISR,因为它们的开销应该避免函数调用).

我曾想过编写一个模板,使用更高级别的脚本语言从中生成两个ISR,但我更喜欢只使用C或C预处理器宏的解决方案.

Dan*_*Dan 6

在这种情况下,我通常让ISR(向量入口点)的前端设置指向设备特定块的指针,然后使用指向该块的指针调用公共代码.

大致(不担心ISR语法等)

void __attribute__((__interrupt__)) Isr1(void)
{
   CommonISR(&dev1info);
}

void __attribute__((__interrupt__)) Isr2(void)
{
   CommonISR(&dev2info);
}

void CommonISR(Foo *devptr)
{
    devptr->count = 0;
    devptr->reset();
    etc...
}
Run Code Online (Sandbox Code Playgroud)

dev1info和dev2info在启动时配置/初始化; 他们可能有指向HW寄存器等的指针......