Closed tatery closed 2 years ago
For almost all use cases you will need to create a single Context
instance and share and re-use that in your application. A Context
object contains all the runtime and management state of the I/O. If you had multiple Context
objects and attempted to REUSE certain I/O hardware or I/O providers it's possible that they could conflict or get out of sync. I would avoid multiple Context
instances unless you really have a very specific use case where you were using separate I/O providers.
I can't think of many use cases for multiple Context
instances. Perhaps if you had a system that supported multiple "hot-plug" add-on boards that exposed additional I/O capability and where your software needed to manage the lifecycle of those add-on board I/Os independently. As you can see ... I'm stretching to identify a viable use case :-)
Thanks for clarification.
Please consider expanding the description of the context
to include the above explanation.
I have additional questions:
Let's assume there is only one context
in an application. What happens when different parts of the application try to access the same I/O hardware? Does the context
retain a reference
to the already created handler to the hardware and can return it somehow?
Yes the context maintains a reference to each I/O instance created. (Until pi4j.shutdown()
is called.)
Somewhere you will need to create()
your I/O instance giving it a unique id
(string). If you try to call create()
a second time with the same id
, you will get an IOAlreadyExistsException
pi4j.digitalOutput().create(1, "my-gpio");
Elsewhere in your application, you can get access to existing I/O instances using the Context's io()
or getIO()
methods.
if(pi4j.hasIO("my-gpio")){
DigitalOutput myOutput = pi4j.io("my-gpio");
}
Additional methods to access the registered I/O instances can be obtained thru the Registry
class..
pi4j.registry().*
@savageautomate Again, many thanks. I have just started a project with pi4j v2 so more questions may arise in the near future ;)
Hello,
Since the SPI configuration is currently limited (please see: https://github.com/Pi4J/pi4j-v2/issues/77) I have to use PiGpioNativeImpl
to be able to communicate with the device on second SPI bus:
piGpio = PiGpioNativeImpl.newInstance();
spiHandler = piGpio.spiOpen(SpiChipEnable.CE_1.getChannel(), 15600000, flags);
Questions:
pi4j = Pj4Context.getInstance();
var ledConfig = DigitalOutput.newConfigBuilder(pi4j)
.id("led")
.name("LED Flasher")
.address(PIN_LED)
.shutdown(DigitalState.LOW)
.initial(DigitalState.LOW)
.provider("pigpio-digital-output");
pi4j.shutdown();
also close/release the resources allocated by piGpio = PiGpioNativeImpl.newInstance();
?PiGpioNativeImpl
from context
?1) Is it possible to access PiGpioNativeImpl and additionally at the same time use PiGpio as a provider for other I/O hardware, for example:
I don't think the PiGpioNativeImpl
class is exported in the module-info
. So accessing it might be troublesome. However the PiGpio
interface is exported and it has the following static default method which effectively is the same thing:
PiGpio.newNativeInstance()
Yes, it's technically possible; however, it really is not intended for direct use outside and in combination with the Pi4J framework. I'm not entirely sure of any problems as longs as you keep careful and distinct control over the IO hardware you are accessing separate. I can't guarantee no conflicts will occur :-)
2) Does pi4j.shutdown(); also close/release the resources allocated by piGpio = PiGpioNativeImpl.newInstance();?
Yes if your Pi4J context includes the PiGPIO providers it will call into the provider and invoke the shutdown()
against the PiGpioNativeImpl
library. However, if your program did not load the PiGPIO providers into the Pi4J context, then no.
3) Is it possible to get reference to PiGpioNativeImpl from context?
I don't believe so. The Pi4J context should only provide Pi4J I/O interfaces and not direct library interfaces for interacting with the I/O. In fact, the Pi4J runtime/context only knows about the PiGPIO providers. The PiGPIO providers are who internally reference the PiGpioNativeImpl
library.
@savageautomate Thanks for clarification.
Thanks @tatery and @savageautomate for these clear questions and answers. I used part of it to extend the page https://pi4j.com/documentation/create-context/. OK?
Hi,
I wonder what is the right way to manage contexts, as it is possible to create multiple contexts (Version 1 was implemented using a static singleton, while version 2 uses a “Context” to avoid static singletons). Should I create one context and share it across my application classes, or can each class manage its own pi4j context? Documentation says: "Terminating/destroying the context stops and releases all resources, threads, listeners, and provisioned I/O instances held by the context" - does this mean that the created contexts are independent and destroying one does not affect the others? If so, is it possible to have reference to the same device (e.g. the same i2c device) in few contexts?
Thanks in advance for clarification.