Skip to content

GD32F130 GPIO EXTI4-15 interrupt handler is slow, would be nice to be able to override it #106

Open
@robcazzaro

Description

@robcazzaro

I'm working to help implement a SimpleFOC algorithm for GD32F130-based hoverboards, and running into timing issues with interrupt handling. The GD32F130C8 used on those boards runs at only 48MHz, so every instruction counts when responding to an interrupt.

The current code in this repository is suboptimal in two areas especially when using pins with a high number (e.g. PC14)

void exti_callbackHandler(uint32_t pinNum)
{
    exti_line_enum linex = (exti_line_enum)BIT(pinNum);
    if (RESET != exti_interrupt_flag_get(linex)) {
        exti_interrupt_flag_clear(linex);
        if (NULL != gpio_exti_infor[pinNum].callback) {
            gpio_exti_infor[pinNum].callback();
        }
    }
}
[...]
#elif defined(GD32F3x0) || defined(GD32F1x0)
void EXTI0_1_IRQHandler(void)
{
    uint32_t i;
    for (i = 0; i <= 1; i++) {
        exti_callbackHandler(i);
    }
}

void EXTI2_3_IRQHandler(void)
{
    uint32_t i;
    for (i = 2; i <= 3; i++) {
        exti_callbackHandler(i);
    }
}

void EXTI4_15_IRQHandler(void)
{
    uint32_t i;
    for (i = 4; i <= 15; i++) {
        exti_callbackHandler(i);
    }
}

EXTI4_15_IRQHandler() calls exti_callbackHandler 11 times before finally servicing PC14 and invoking the relevant callback, plus one more time after the callback. As a generic implementation, that works well. But considering in our project we use PC14 and PB11 for Hall sensors, that adds a non-trivial amount of overhead.

Knowing we have only 2 possible EXTI sources, our code could be as follows

void EXTI4_15_IRQHandler(void)
{
    exti_callbackHandler(11);
    exti_callbackHandler(14);
}

Would it be possible to define the EXTI IRQ handlers with __attribute__((weak)) so that they can be overridden by our implementation? I would like to build as much as possible on top of the un-modified GD32 Arduino core. Not sure if that would conflict with the .weak EXTI4_15_IRQHandler definition in startup_gd32f1x0.S, though. I found this warning "If multiple weak definitions are available, the linker generates an error message, unless the linker option --muldefweak is used. In this case, the linker chooses one for use by all calls.", so I'm not sure how that would work. Maybe a global define to enable IRQ handler redefinition?

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions