mattjlewis / diozero

Java Device I/O library that is portable across Single Board Computers and microcontrollers. Tested with Raspberry Pi, Odroid C2, BeagleBone Black, Next Thing CHIP, Asus Tinker Board and Arduinos / Pico. Supports GPIO, I2C, SPI as well as Serial communication. Also known to work with Udoo Quad.
https://www.diozero.com
MIT License
261 stars 59 forks source link

Issue init GPIO on TinkerBoard #70

Closed zixzix closed 3 years ago

zixzix commented 3 years ago

[...] I will do more tests asap [...] Originally posted by @zixzix in https://github.com/mattjlewis/diozero/issues/69#issuecomment-819760978

After many tests I noticed some strange behaviors that I report here in detail

Test Environment

TinkerBoard 1
Armbian Focal 21.02.3
Diozero 1.2.1
Java 16
Tomcat 10
OUT Pin for test: 184, 163, 162
IN Pin for test: 257, 166, 168

Java code for init DigitalInputDevice

DigitalInputDevice pin = new DigitalInputDevice(pinNumber, GpioPullUpDown.PULL_UP, GpioEventTrigger.BOTH);
pin.addListener(event -> {...});

Java code for init DigitalOutputDevice

DigitalOutputDevice pin = new DigitalOutputDevice(pinNumber, true, false);

Java code for close Pin

pin.close();

Java code for shutdown

DeviceFactoryHelper.shutdown();

Scenario 1 (diozero.gpio.chardev=false) First init of new DigitalInputDevice works fine. First init of new DigitalOutputDevice works fine.

After close all initialized pins and call shutdown method

Second init of new DigitalInputDevice fails with following error:

epoll_ctl: error in add, Bad file descriptor
com.diozero.api.RuntimeIOException: Error registering file '/sys/class/gpio/gpio257/value' with epoll
        at com.diozero.util.EpollNative.register(EpollNative.java:168)
        at com.diozero.internal.provider.builtin.SysFsDigitalInputDevice.enableListener(SysFsDigitalInputDevice.java:122)
        at com.diozero.internal.spi.AbstractInputDevice.setListener(AbstractInputDevice.java:58)
        at com.diozero.api.DigitalInputDevice.setListener(DigitalInputDevice.java:252)
        at com.diozero.api.AbstractDigitalInputDevice.enableDeviceListener(AbstractDigitalInputDevice.java:71)
        at com.diozero.api.GpioInputDevice.addListener(GpioInputDevice.java:64)

Second init of new DigitalOutputDevice fails with following error:

java.lang.NullPointerException: Cannot load from object array because "this.gpioBanks" is null
        at com.diozero.internal.board.tinkerboard.TinkerBoardMmapGpio.gpioWrite(TinkerBoardMmapGpio.java:312)
        at com.diozero.internal.provider.builtin.SysFsDigitalOutputDevice.setValue(SysFsDigitalOutputDevice.java:102)
        at com.diozero.internal.provider.builtin.SysFsDigitalOutputDevice.<init>(SysFsDigitalOutputDevice.java:76)
        at com.diozero.internal.provider.builtin.DefaultDeviceFactory.createDigitalOutputDevice(DefaultDeviceFactory.java:262)
        at com.diozero.internal.spi.GpioDeviceFactoryInterface.provisionDigitalOutputDevice(GpioDeviceFactoryInterface.java:84)
        at com.diozero.api.DigitalOutputDevice.<init>(DigitalOutputDevice.java:158)
        at com.diozero.api.DigitalOutputDevice.<init>(DigitalOutputDevice.java:142)

Scenario 2 (diozero.gpio.chardev=false) First init of new DigitalInputDevice works fine. First init of new DigitalOutputDevice works fine.

After close all initialized pins and without call shutdown method

Second init of new DigitalOutputDevice works fine Second init of new DigitalInputDevice give me the following warn but works:


Scenario 3 (diozero.gpio.chardev=true) First init of new DigitalOutputDevice works fine. First init of new DigitalInputDevice fails with following error:

java.lang.IndexOutOfBoundsException
        at java.base/java.nio.Buffer.checkIndex(Unknown Source)
        at java.base/java.nio.DirectIntBufferU.get(Unknown Source)
        at com.diozero.util.MmapIntBuffer.get(MmapIntBuffer.java:56)
        at com.diozero.internal.board.tinkerboard.TinkerBoardMmapGpio.setPullUpDown(TinkerBoardMmapGpio.java:281)
        at com.diozero.internal.provider.builtin.NativeGpioInputDevice.<init>(NativeGpioInputDevice.java:69)
        at com.diozero.internal.provider.builtin.DefaultDeviceFactory.createDigitalInputDevice(DefaultDeviceFactory.java:240)
        at com.diozero.internal.spi.GpioDeviceFactoryInterface.provisionDigitalInputDevice(GpioDeviceFactoryInterface.java:61)
        at com.diozero.api.DigitalInputDevice.<init>(DigitalInputDevice.java:195)
        at com.diozero.api.DigitalInputDevice.<init>(DigitalInputDevice.java:175)

After close all initialized pins and call shutdown method

Second init of new DigitalInputDevice fails with following error:

java.lang.IllegalArgumentException: Can't find chip for id 5
        at com.diozero.internal.provider.builtin.DefaultDeviceFactory.createDigitalInputDevice(DefaultDeviceFactory.java:237)
        at com.diozero.internal.spi.GpioDeviceFactoryInterface.provisionDigitalInputDevice(GpioDeviceFactoryInterface.java:61)
        at com.diozero.api.DigitalInputDevice.<init>(DigitalInputDevice.java:195)
        at com.diozero.api.DigitalInputDevice.<init>(DigitalInputDevice.java:175)

Second init of new DigitalOutputDevice fails with following error:

java.lang.IllegalArgumentException: Can't find chip for id 6
        at com.diozero.internal.provider.builtin.DefaultDeviceFactory.createDigitalOutputDevice(DefaultDeviceFactory.java:256)
        at com.diozero.internal.spi.GpioDeviceFactoryInterface.provisionDigitalOutputDevice(GpioDeviceFactoryInterface.java:84)
        at com.diozero.api.DigitalOutputDevice.<init>(DigitalOutputDevice.java:158)
        at com.diozero.api.DigitalOutputDevice.<init>(DigitalOutputDevice.java:142)

Scenario 4 (diozero.gpio.chardev=true) First init of new DigitalOutputDevice works fine. First init of new DigitalInputDevice fails with following error:

java.lang.IndexOutOfBoundsException
        at java.base/java.nio.Buffer.checkIndex(Unknown Source)
        at java.base/java.nio.DirectIntBufferU.get(Unknown Source)
        at com.diozero.util.MmapIntBuffer.get(MmapIntBuffer.java:56)
        at com.diozero.internal.board.tinkerboard.TinkerBoardMmapGpio.setPullUpDown(TinkerBoardMmapGpio.java:281)
        at com.diozero.internal.provider.builtin.NativeGpioInputDevice.<init>(NativeGpioInputDevice.java:69)
        at com.diozero.internal.provider.builtin.DefaultDeviceFactory.createDigitalInputDevice(DefaultDeviceFactory.java:240)
        at com.diozero.internal.spi.GpioDeviceFactoryInterface.provisionDigitalInputDevice(GpioDeviceFactoryInterface.java:61)
        at com.diozero.api.DigitalInputDevice.<init>(DigitalInputDevice.java:195)
        at com.diozero.api.DigitalInputDevice.<init>(DigitalInputDevice.java:175)

After close all initialized pins and without call shutdown method Second init of new DigitalOutputDevice works fine. Second init of new DigitalInputDevice fails with following error:

Error setting line event: Device or resource busy
com.diozero.api.RuntimeIOException: Error in provisionGpioInputDevice: -16
        at com.diozero.internal.provider.builtin.gpio.GpioChip.provisionGpioInputDevice(GpioChip.java:203)
        at com.diozero.internal.provider.builtin.NativeGpioInputDevice.<init>(NativeGpioInputDevice.java:65)
        at com.diozero.internal.provider.builtin.DefaultDeviceFactory.createDigitalInputDevice(DefaultDeviceFactory.java:240)
        at com.diozero.internal.spi.GpioDeviceFactoryInterface.provisionDigitalInputDevice(GpioDeviceFactoryInterface.java:61)
        at com.diozero.api.DigitalInputDevice.<init>(DigitalInputDevice.java:195)
        at com.diozero.api.DigitalInputDevice.<init>(DigitalInputDevice.java:175)

I am available to provide further data and tests Thank you

mattjlewis commented 3 years ago

Do you mind trying with 1.2.1 - it included some fixes in this area

zixzix commented 3 years ago

Hello @mattjlewis , as specified in the "test environment section" all tests were performed with version 1.2.1 of diozero

mattjlewis commented 3 years ago

Sorry - missed that! Will take a look this weekend.

mattjlewis commented 3 years ago

I think I've reproduced scenarios 1-3 with this test app: https://github.com/mattjlewis/diozero/blob/main/diozero-sampleapps/src/main/java/com/diozero/sampleapps/ShutdownRestartTest.java Scenario 4 might be TinkerBoard specific, will check later. I'll commit and push as 1.2.2 this weekend after further tests.

mattjlewis commented 3 years ago

Could you retry with 1.2.2 please.

mattjlewis commented 3 years ago

Assume fixed.