Closed holzingk closed 5 years ago
Which interrupt did you try to register? Could you post the code snipped where PIO_ConfigureIt(...)
is called?
About when is the call done?
Background of the questions is the following: Currently the USB controller driver assumes that it has the port interrupt for itself (for performance reasons). If your registered pin is in the same bank as the USB interrupt pin, that could lead to the given problem.
The module defining PIO_ConfigureIt() contains a system initialization item which calls PIO_SysInitializeInterrupts() during system initialization. It installs some RTEMS_INTERRUPT_UNIQUE interrupt handlers. Maybe this causes the problem. The pio_it.c should be changed to be a bit less greedy.
I use PIO_ConfigureIt(triggerpin, &grisp_ir_handle, data);
triggerpin
is a pointer to:
{PIO_PC12, PIOC, ID_PIOC, PIO_INPUT, PIO_IT_FALL_EDGE}
I am writing an Erlang driver to notify Erlang about pin interrupts and I use the function in the start function. The call is not done at all, as the driver is not even started from the Erlang side. The problem occurs with lone presence of the function, so I guess it has to do with linking, and some automatic initialisation as @sebhub pointed out.
Yes. The initialization that Sebastian mentioned seems more likely. In pio_it.c
a RTEMS_INTERRUPT_UNIQUE
is installed for all port interrupts. That will interfere with the rtems_interrupt_handler_install
that is used in a (quite deeply nested) call during the USB-controller initialization here: https://github.com/grisp/rtems-libbsd/blob/grisp/freebsd/sys/dev/usb/controller/saf1761_otg_fdt.c#L246
I think there are two to three possible solutions to that:
PIO_ConfigureIt
mechanic. That will have an performance impact on all USB (and therefore WiFi) communication. But it will have the advantage that the PIO_ConfigureIt
is usable for other pins on the same port (relevant ones should be JUMPER5, DIO1/AN1 (connector GPIO1), DIO2/AN2 (connector GPIO1), JUMPER3)rtems_interrupt_handler_remove
for that interrupt before the libbsd initialization.In my case I need hardware interrupts on GPIO pins, which are scattered on PIO controllers A, C and D. So option 2. is ok for me, I just cannot have interrupts on all pins then, but I don't need that for my use case anyways.
Option 1 seems more elegant, but I cannot predict performance impact.
I'd go for Option 2 now, would be nice if trying to register a interrupt on PIOC results in a fatal error with some discernable message like "no interrupt allowed on PORTC pins"
I have some other (pressing) work in the next few days so I can't guarantee when I'll find time to take a look at that.
In case you need something to try: My first idea for a workaround would be along the following line: Before the initialization of libbsd:
Basically that would mean something like that (untested):
static void dummy_isr(void *arg)
{
/* do nothing */
(void) arg;
}
static void workarround_function(void)
{
sc = rtems_interrupt_handler_install(
PIOC_IRQn,
"PIO C",
RTEMS_INTERRUPT_UNIQUE | RTEMS_INTERRUPT_REPLACE,
dummy_isr,
NULL
);
assert(sc == RTEMS_SUCCESSFUL);
sc = rtems_interrupt_handler_remove(
PIOC_IRQn,
dummy_isr,
NULL
);
assert(sc == RTEMS_SUCCESSFUL);
}
Thank you @c-mauderer . The mentioned workaround worked fine in my application.
Unfortunately my generic interrupt driver still is not in a state to be merged into the grisp repository.
In my application I try to register an interrupt. As soon as I use the function
PIO_ConfigureIt()
wpa_supplicant
fails to start, even when the function is not called at all. So I guess that something is linked automaticly which interferes withwpa_supplicant
.Boot output looks as follows: