eclipse / mraa

Linux Library for low speed IO Communication in C with bindings for C++, Python, Node.js & Java. Supports generic io platforms, as well as Intel Edison, Intel Joule, Raspberry Pi and many more.
http://mraa.io
MIT License
1.37k stars 613 forks source link

GPIO Interrupt problem on CM3 #1121

Open ModnyCo-Navid opened 10 months ago

ModnyCo-Navid commented 10 months ago

I built the library on Debian Bullseye OS on a Radxa CM3 board, and everything goes well but when I tried to set an interrupt on any GPIO using mraa-monitor, the pin value always returns -1. I tried to run the command using sudo, but the result was the same.

tingleby commented 8 months ago

@nascs Is this something you would be aware of?

ModnyCo-Navid commented 8 months ago

I tried to start an ISR in c code too and I found out that before starting the ISR, function mraa_gpio_read returns the GPIO value correctly, but after starting an ISR by calling mraa_gpio_isr, the mraa_gpio_read will always return -1. Then I stopped the ISR by calling mraa_gpio_isr_exit and the value returned by mraa_gpio_read was correct again.

nascs commented 8 months ago

@nascs Is this something you would be aware of?

I didn't know about this. Maybe the test missed it.

nascs commented 8 months ago

Hi @ModnyCo-Navid , Can you show me your sample code so I can reproduce the problem and see how to fix it?

ModnyCo-Navid commented 8 months ago

This is my sample code to test the pin read function before and after interrupt configuration.

` // Function to be called when the interrupt occurs void interruptHandler(void *args) { mraa_gpio_context gpio = (mraa_gpio_context)args; printf("Interrupt occurred! Pin Value= %d\n", mraa_gpio_read(gpio)); } int main() { mraa_gpio_context interrupt_gpio; mraa_gpio_context out_gpio; mraa_init(); // Initialize the GPIO pin for interrupt interrupt_gpio = mraa_gpio_init(28); // Interupt GPIO pin

if (interrupt_gpio == NULL)
{
    fprintf(stderr, "Failed to initialize GPIO %d\n", 3);
    return 1;
}

// Set the GPIO pin as an input
if (mraa_gpio_dir(interrupt_gpio, MRAA_GPIO_IN) != MRAA_SUCCESS)
{
    fprintf(stderr, "Failed to set GPIO in direction\n");
    mraa_gpio_close(interrupt_gpio);
    return 1;
}

printf("Pin Value before starting interrupt= %d\n", mraa_gpio_read(interrupt_gpio));

// Configure an interrupt for the GPIO pin
if (mraa_gpio_isr(interrupt_gpio, MRAA_GPIO_EDGE_BOTH, &interruptHandler, interrupt_gpio) != MRAA_SUCCESS)
{
    fprintf(stderr, "Failed to configure interrupt\n");
    mraa_gpio_close(interrupt_gpio);
    return 1;
}

printf("Pin Value after starting interrupt= %d\n", mraa_gpio_read(interrupt_gpio));

// Sleep for a while to observe the signal
sleep(10);

// Exit the interrupt to check pin value again
mraa_gpio_isr_exit(interrupt_gpio);
printf("Pin Value after exiting interrupt= %d\n", mraa_gpio_read(interrupt_gpio));
// Clean up and close the GPIO pin
mraa_gpio_close(interrupt_gpio);
return 0;

} `

And this is the output of this code.

image

As you can see, when I configure the interrupt, the GPIO read function always returns -1 regardless of the pin value.

nascs commented 8 months ago

Hi @ModnyCo-Navid, Maybe your code needs to be improved, here's an example you can try, on my side it's possible to trigger to the interrupt handle function.

nascs commented 8 months ago
radxa@radxa-cm3-io:~/sample_code/mraa/c$ gcc interrupt.c -lmraa && sudo ./a.out
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
>> This is interrupt handle function !
cnt = 65
ModnyCo-Navid commented 8 months ago

I can get the interrupt trigger and it works fine. There is no problem with the interrupt trigger. My problem is that I can no longer read the pin value when I start the interrupt, and the mraa_gpio_read always returns -1. As you can see in the sample code I sent, the read function doesn't work when I start the interrupt on pin and after exiting the interrupt, the read function works fine.

nascs commented 8 months ago

I have reproduced this problem, and now found that there may be a problem with the parameters returned by the thread when it is created by pthread_create.