Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue: Unable to Reuse GPIO Pin After Removal from Registry #440

Open
moreorover opened this issue Jan 24, 2025 · 1 comment
Open

Issue: Unable to Reuse GPIO Pin After Removal from Registry #440

moreorover opened this issue Jan 24, 2025 · 1 comment

Comments

@moreorover
Copy link

Description
When attempting to remove a DigitalInput instance from the Pi4J registry and then reinitialize it, the system fails with an error indicating that the GPIO pin is still busy. It seems that Pi4J is unable to fully release the pin even after calling registry().remove() and shutdown().

Steps to Reproduce
The following code reproduces the issue:

DigitalInputConfigBuilder buttonConfig = DigitalInput.newConfigBuilder(pi4j)
        .id("button-" + 22)
        .name("Button on pin " + 22)
        .address(22)
        .pull(PullResistance.PULL_DOWN)
        .debounce(3000L);
DigitalInput button = pi4j.create(buttonConfig);

// Remove the instance from the Pi4J registry and shut it down
pi4j.registry().remove(button.id());
button.shutdown(pi4j);

// Attempt to reinitialize the same pin
DigitalInputConfigBuilder buttonConfig2 = DigitalInput.newConfigBuilder(pi4j)
        .id("button-" + 22)
        .name("Button on pin " + 22)
        .address(22)
        .pull(PullResistance.PULL_DOWN)
        .debounce(3000L);
DigitalInput button2 = pi4j.create(buttonConfig2); // Error occurs here

Observed Behavior
The system throws the following exception when trying to reinitialize the pin:

Caused by: java.lang.IllegalStateException: Failed to initialize IO button-22 at com.pi4j.registry.impl.DefaultRuntimeRegistry.add(DefaultRuntimeRegistry.java:102) ~[pi4j-core-2.7.0.jar!/:na] at com.pi4j.registry.impl.DefaultRegistry.add(DefaultRegistry.java:97) ~[pi4j-core-2.7.0.jar!/:na] at com.pi4j.plugin.gpiod.provider.gpio.digital.GpioDDigitalInputProviderImpl.create(GpioDDigitalInputProviderImpl.java:33) ~[pi4j-plugin-gpiod-2.7.0.jar!/:na] ... Caused by: com.pi4j.library.gpiod.internal.GpioDException: c_gpiod_line_request_both_edges_events_flags failed: -1 (Device or resource busy) at com.pi4j.library.gpiod.internal.GpioD.lineRequestBothEdgeEventsFlags(GpioD.java:221) ~[pi4j-library-gpiod-2.7.0.jar!/:na]

Expected Behavior
After calling registry().remove() and shutdown(), the GPIO pin should be fully released and available for reuse. The DigitalInput instance should be re-creatable without encountering any "Device or resource busy" errors.

Environment

  • Pi4J Version: 2.7.0
  • Java Version: 17
  • OS: Raspberry Pi OS on Raspberry Pi 4 Model B Rev 1.4
  • libgpiod Version: 1.6.3

Additional Notes
It appears that the underlying GPIO line remains locked at the OS level even after calling shutdown() and removing the pin from the Pi4J registry. This may require additional handling in Pi4J to ensure proper release of GPIO resources.

@moreorover
Copy link
Author

The following code seems to release the GPIO pin at the OS level, allowing me to reassign the pin successfully:

DigitalInputConfigBuilder buttonConfig = DigitalInput.newConfigBuilder(pi4j)
        .id("button-" + 22)
        .name("Button on pin " + 22)
        .address(22)
        .pull(PullResistance.PULL_DOWN)
        .debounce(3000L);
DigitalInput button = pi4j.create(buttonConfig);

// Remove the instance from the Pi4J registry and shut it down
pi4j.registry().remove(button.id());
button.shutdown(pi4j);
+pi4j.shutdown();
+pi4j = Pi4J.newAutoContext();
// Attempt to reinitialize the same pin
DigitalInputConfigBuilder buttonConfig2 = DigitalInput.newConfigBuilder(pi4j)
        .id("button-" + 22)
        .name("Button on pin " + 22)
        .address(22)
        .pull(PullResistance.PULL_DOWN)
        .debounce(3000L);
DigitalInput button2 = pi4j.create(buttonConfig2); // Error occurs here

However, I was wondering if button.shutdown(pi4j) alone should be sufficient to release the pin. My understanding is that shutdown() should properly clean up resources and release the GPIO line, but without calling pi4j.shutdown() and recreating the context, the pin remains busy, and reinitialization fails. Is this the expected behavior, or could it be a bug in how shutdown() works for individual GPIO resources?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant