See: Description
Package | Description |
---|---|
com.oracle.deviceaccess |
Provides interfaces and classes for device I/O access and control.
|
com.oracle.deviceaccess.adc |
Interfaces and classes for reading analog inputs using an Analog to Digital Converter (ADC).
|
com.oracle.deviceaccess.atcmd |
Interfaces and classes for controlling a Data Communication Equipment such as a modem or a
cellular module using AT commands.
|
com.oracle.deviceaccess.counter |
Interfaces and classes for counting pulses (or events) on a digital input line.
|
com.oracle.deviceaccess.dac |
Interfaces and classes for writing analog outputs using a Digital to Analog Converter (DAC).
|
com.oracle.deviceaccess.generic |
Interfaces and classes for controlling devices using generic I/O operations.
|
com.oracle.deviceaccess.gpio |
Interfaces and classes for reading and writing from/to GPIO (General Purpose Input Output) pins
and ports of the device.
|
com.oracle.deviceaccess.i2cbus |
Interfaces and classes for I2C (Inter-Integrated Circuit Bus) device access.
|
com.oracle.deviceaccess.mmio |
Interfaces and classes for performing memory-mapped I/O.
|
com.oracle.deviceaccess.modem |
Interfaces and classes for controlling MODEM signals.
|
com.oracle.deviceaccess.power |
Interfaces and classes for power management of peripheral devices.
|
com.oracle.deviceaccess.pwm |
Interfaces and classes for generating PWM pulses on a digital output line.
|
com.oracle.deviceaccess.spi |
Service-provider classes for the
com.oracle.deviceaccess package. |
com.oracle.deviceaccess.spibus |
Interfaces and classes for SPI (Serial Peripheral Interface Bus) device access.
|
com.oracle.deviceaccess.uart |
Interfaces and classes for controlling and reading and writing from/to Universal Asynchronous Receiver/Transmitter
(UART), with optional Modem signals control.
|
com.oracle.deviceaccess.watchdog |
Interfaces and classes for using system watchdog timers (WDT).
|
Peripherals
, or in essence
new peripheral drivers. The Peripheral
interface can be extended to provide new
types of peripherals such as a Real Time Clock or a Touch Screen peripheral.
New implementations of the Peripheral
sub-interfaces defined in this specification may also be
registered. For example, access to the pins and ports of an I2C GPIO expander primarily
supported as an I2C slave device peripheral may be provided by new GPIOPin
and GPIOPort
implementations.
com.oracle.deviceaccess
com.oracle.deviceaccess.power
com.oracle.deviceaccess.spi
PeripheralTypeNotSupportedException
is thrown when attempting to open
a peripheral device whose type is not supported by the platform.PeripheralNotFoundException
is thrown when attempting to open
a peripheral device with capabilities not supported by the platform.UnsupportedOperationException
is thrown when attempting to perform an operation on a peripheral device which is not supported by the driver or underlying hardware. Methods of Peripheral
interfaces
are documented appropriately and include the corresponding @throws
clause documentation.0
and must be unique.
Yet the same peripheral device may be directly and indirectly mapped through several IDs.
For example, an Analog Digital Converter may be both an I2C slave device and an ADC device.
In this case, there may be one ID to retrieve the device as an I2CDevice
instance and four other IDs to retrieve each of its four ADC channels as ADCChannel
instances.
Similarly, a Real-Time Clock device with memory-mapped registers may be mapped to an MMIODevice
through one ID
and to a user-defined Peripheral
implementation providing a higher-level Real-Time Clock abstraction through an other ID
(see the example below).
Peripheral
offering different levels of abstractions. Each of these instances would have the same name.
In the last example above, both implementations of
the real-time clock peripheral device may have the same name "RTC" though they have different IDs and interfaces.
ATDevice
defines - as properties - certain capabilities
for modems.
Properties can be use to represent intrinsic properties of a peripheral device such as its capabilities as well as
extrinsic properties of a peripheral device such as its placement on the board or whether a peripheral device is embedded,
removable or even external to a module. Properties defined for a peripheral device driver may be published as part of its specification.
Using the RTC example,
because of the tight dependency to its hardware chip, the memory-mapped Real-Time Clock peripheral
device may have been registered with the following property: "com.acme.rtc.chip=146818", which actually refers to the RTC chip designation.
The user-defined Peripheral
implementation
may then rely on this property to lookup the MMIODevice
for which it wants to provide
a higher-level abstraction.
Another example is the properties of an I2C slave device which could include whether it supports the SMBus
specification (see http://smbus.org/specs/index.html) or the
properties of a temperature sensor which may include its placement on the board or module.
By convention properties should use the following format:
<name>=
<value>
Note that property-based lookup only uses exact (case-insensitive) matching and does not perform any semantic interpretation.
For example, a negatively asserted boolean property (eg. "com.foobar.rtc.alarm=false") will not match the absence of
the corresponding positively asserted boolean property (eg. "com.foobar.rtc.alarm=true").
"java."
, "javax."
are reserved for definition by this
specification. According to this convention, the property of an I2C slave device to support the SMBus
specification should be named with the prefix "org.smbus."
.
PeripheralConfig
objects when opening a peripheral device with an adhoc configuration.
"RTC"
, interface=I2CSlaveDevice|RealTimeClock
"TEMP_SENSOR"
, interface="ADCChannel"
, property="com.foobar.temp.orientation=TOP"|"com.foobar.temp.orientation=BOTTOM"|...
"WDT"
, interface=WatchdogTimer
Peripheral
sub-interfaces. They are especially not granted the permission to use the PeripheralManager.open(PeripheralConfig)
to open
peripheral devices with an ad-hoc configuration.
Peripheral
interfaces.
Still applications will be able to discover or address peripheral devices which are not part of the pre-configured set
and especially new peripheral devices that may be added to the platform, for example on an I2C bus.
To address and access such a newly plugged in I2C slave device, an application may use an instance of I2CDeviceConfig
with the bus number and slave address properly set.
In order to open a peripheral device with an adhoc configuration, an application must be granted the permission to use
PeripheralManager.open(PeripheralConfig)
.
open
methods
or the register
method of the PeripheralManager
the peripheral manager MUST use the Service-Provider Loading facility supported by the platform
(typically going through the class path of shared libraries)
to locate a PeripheralProvider
that can open Peripheral
instances of the requested type,
configuration and properties.
The class implementing the PeripheralProvider
interface as well as the class implementing
the Peripheral
interface or sub-interface and all associated classes must be located in a shared library or already part of the platform'system libraries.
com.oracle.deviceaccess.PeripheralManager.register
method.
An application may unregister an application-registered peripheral device provided it is granted the PeripheralMgmtPermission.UNREGISTER
permission.
GPIOPin
instances and can be accessed concurrently even
though they may be supported by the same GPIO controller hardware; individual ADC channels are modeled as separate ADCChannel
instances and can be accessed concurrently. While access to the underlying hardware device may be shared and the sharing controlled by the underlying peripheral device driver,
access to individual peripheral device resources modeled as Peripheral
instances may be exclusive or shared.
Whether access to individual peripheral device resources modeled as Peripheral
instances is exclusive or shared
depends on the peripheral's type, configuration and on the underlying device driver implementation.
Three cases of peripheral device resource abstraction may be considered:
Peripheral
instance may be a dedicated abstraction of a peripheral device resource. Only one Peripheral
instance
for that individual peripheral device resource may be open at a particular time and access to the resource through Peripheral
instance is exclusive.
Attempting to open such a peripheral device resource while it is already open will result in a UnavailablePeripheralException
being thrown.
Peripheral
instances are assumed to be dedicated abstraction of peripheral device resources.
Peripheral
instance may be a virtualized abstraction of a peripheral device resource. Several Peripheral
instances
mapped onto that same individual peripheral device resource may be open concurrently and access to the resource through the Peripheral
instances
may appear as exclusive as if dedicated abstractions.
Peripheral
instance may be a shared abstraction of a peripheral device resource. Several Peripheral
instance
mapped onto that same individual peripheral device resource may be open concurrently but access to the resource through the Peripheral
instances
must be explicitly synchronized.
Peripheral.tryLock
and
Peripheral.unlock
. An application may also rely
on peripheral protocol-specific means to synchronize access to a shared peripheral resource. For example, a particular implementation may
configure a specific I2C EEPROM device to be shared. Access to the I2C EEPROM device
through I2CDevice
instances will be by default synchronized on I2C transactions.
PeripheralManager.open
methods always return a new instance upon each call regardless of whether it is a dedicated, virtualized or shared
peripheral device resource abstraction.
Instances of Peripheral
must be thread-safe.
For example, if a thread has already initiated an I/O operation upon a peripheral device through a Peripheral
instance, an
invocation of another I/O method on that same Peripheral
instance will block until the first operation is complete.
PeripheralEvent
)
and are dispatched for processing by application-registered event listeners
(instances of PeripheralEventListener
).
Because some events may be time-sensitive, events are time-stamped. Additionally,
to account for event bursts, that is cases where events are produced more rapidly than they are handled,
events may be coalesced. Coalesced events regroup in one event object several occurrences of events
of the same type and keep track of the number of events that have been coalesced.
Only the last occurring value that may be attached to the event such as the state of a GPIO pin, is retained.
Also, the timestamps of both the first occurrence and the last occurrence are retained.
Not all events can be coalesced. Coalescing of events are event and peripheral -type-dependent.
Event handling methods should be implemented in such a way that they quickly process the events and return.
Event notification implements a unicast model. A single listener can be registered for a particular event type.
Peripheral
-implementing classes) are registered.
PeripheralManager.register
method
the PeripheralMgmtPermission
is checked with a target name composed of the requested peripheral name and ID and with the action PeripheralMgmtPermission.REGISTER
.
For example, if a peripheral device of type GPIOPin
is to be registered the
PeripheralMgmtPermission
is checked with a target name composed of the requested peripheral name and ID
and with the action PeripheralMgmtPermission.REGISTER
.
Peripheral
instance with an adhoc configuration using one of the
PeripheralManager.open(config, ...)
methods
the permission (subclass of PeripheralPermission
)
specific to that Peripheral
instance, if any defined, is checked with a target name
composed of the relevant hardware addressing information and with the action
PeripheralPermission.OPEN
.
In the case of a custom peripheral driver, this permission check SHOULD be performed by the
PeripheralProvider.open
method of the peripheral provider.
For example,
if a peripheral device of type GPIOPin
is to be opened the
GPIOPinPermission
is checked with a target name
composed of the relevant hardware addressing information (the device name or device
number and the pin number) and with the action GPIOPinPermission.OPEN
.
Prior to opening the Peripheral
instance with a registered configuration using one of the
PeripheralManager.open(id, ...)
or
PeripheralManager.open(name, ...)
methods
the PeripheralMgmtPermission
is checked with a target name
composed of the requested peripheral ID and/or name and with the action
PeripheralMgmtPermission.OPEN
.
Note that this permission check is performed prior to any permission checks that the peripheral driver may performed when opening the peripheral device with
the designated configuration.
Note on Protection Upon Opening Compound Peripheral Devices:
A compound/composite peripheral device is composed of different peripheral device components such as a Touch Screen Peripheral assembled from
a Touch Screen SPI (Serial Peripheral Interface bus) slave Peripheral and a GPIO pin Peripheral handling the Pen-Down signal or a
GPIO port configured from a set of individual GPIO pins. When a Peripheral
abstraction for such a compound peripheral is assembled from
component Peripheral
abstractions the permissions that apply upon opening the component Peripheral
abstractions must be granted to the
calling application when opening the compound Peripheral
abstraction. Note that depending on the security architecture of the underlying platform (Java ME or Java SE -based) these permission
checks may or may not require the corresponding permissions to be explicitly granted to the calling application; either because (e.g. on Java SE) the preripheral's
driver code is marked as priviledged and is granted the necessary permission(s) (see API for Priviledged Code) and/or
because (e.g. on Java ME) the Peripheral
configuration being opened is a platform-registered configuration for which the
required privileges and permissions are implicitly or explictly granted.
Peripheral
-implementing class may implement additional security checks to protect certain functions.
See GPIOPinPermission.SET_DIRECTION
for an example.
A peripheral provider may define a new permission (subclass of PeripheralPermission
)
for new type of peripheral (subinterface of Peripheral
). As an example, see
the RealTimeClockPermission
below.
RealTimeClock
can be provided for a memory-mapped Real-Time Clock
chip accessible as an MMIODevice
peripheral.
The Real Time Clock peripheral device interface:
The Real Time Clock peripheral device implementation class:public interface RealTimeClock extends Peripheral<RealTimeClock> { int getHours() throws IOException; int getMinutes() throws IOException; int getSeconds() throws IOException; void setAlarm(byte delaySeconds, byte delayMinutes, byte delayHours, AlarmListener listener) throws IOException; void setHours(int hrs) throws IOException; void setMinutes(int mins) throws IOException; void setSeconds(int secs) throws IOException; void cancelAlarm() throws IOException; interface AlarmListener { void fired(RealTimeClock rtc); } }
The Real Time Clock peripheral device provider class:class RealTimeClockImpl extends AbstractPeripheral<RealTimeClock> implements RealTimeClock { static final String[] PROPERTIES = new String[]{ "com.foobar.rtc.alarm=true", "com.foobar.rtc.time=true" }; private static final int INTERRUPT = 0; private RealTimeClockConfig config; private MMIODevice rtc = null; RawRegister<Byte> seconds; RawRegister<Byte> secAlarm; RawRegister<Byte> minutes; RawRegister<Byte> minAlarm; RawRegister<Byte> hours; RawRegister<Byte> hrAlarm; RawRegister<Byte> registerB; RawRegister<Byte> registerC; RawBlock userRAM; RealTimeClockImpl(RealTimeClockConfig config) { this.config = config; } void open() throws IOException, PeripheralTypeNotSupportedException, PeripheralNotFoundException, UnavailablePeripheralException { if (config != null) { rtc = PeripheralManager.open(MMIODevice.class, config.getMmioConfig()); AccessController.checkPermission(new RealTimeClockPermission( config.getMmioConfig().getDeviceName() + ":" + Long.toHexString(config.getMmioConfig().getAddress()), "open")); } else { AccessController.checkPermission(new RealTimeClockPermission("*", "open")); rtc = PeripheralManager.open(null, MMIODevice.class, "com.acme.rtc.chip=146818"); } // The RealTimeClock device has 14 bytes of clock and control registers and 50 bytes // of general purpose RAM (see the data sheet of the HITACHI HD146818 Real Time Clock). seconds = rtc.getRegister("Seconds", Byte.class); secAlarm = rtc.getRegister("SecAlarm", Byte.class); minutes = rtc.getRegister("Minutes", Byte.class); minAlarm = rtc.getRegister("MinAlarm", Byte.class); hours = rtc.getRegister("Hours", Byte.class); hrAlarm = rtc.getRegister("HrAlarm", Byte.class); // More date registers... but not supported in this example registerB = rtc.getRegister("RegisterB", Byte.class); registerC = rtc.getRegister("RegisterC", Byte.class); userRAM = rtc.getBlock("UserRam"); } @Override public void setSeconds(int secs) throws IOException { seconds.set((byte) secs); } @Override public int getSeconds() throws IOException { return seconds.get(); } @Override public void setMinutes(int mins) throws IOException { minutes.set((byte) mins); } @Override public int getMinutes() throws IOException { return minutes.get(); } @Override public void setHours(int hrs) throws IOException { hours.set((byte) hrs); } @Override public int getHours() throws IOException { return hours.get(); } // Sets the daily alarm for after some delay @Override public void setAlarm(byte delaySeconds, byte delayMinutes, byte delayHours, final AlarmListener listener) throws IOException { // Directly read from/write to the registers using RawByte instances. byte currentSeconds = seconds.get(); byte currentMinutes = minutes.get(); byte currentHours = hours.get(); int i = (currentSeconds + delaySeconds) % 60; int j = (currentSeconds + delaySeconds) / 60; secAlarm.set((byte) i); i = (currentMinutes + delayMinutes + j) % 60; j = (currentMinutes + delayMinutes + j) / 60; minAlarm.set((byte) i); i = (currentHours + delayHours + j) % 24; hrAlarm.set((byte) i); rtc.setMMIOEventListener(INTERRUPT, new MMIOEventListener() { @Override public void eventDispatched(MMIOEvent event) { try { MMIODevice rtc = event.getPeripheral(); RawRegister<Byte> registerC = rtc.getRegister("RegisterC", Byte.class); // Check the Alarm Interrupt Flag (AF) if ((registerC.get() & 0X20) != 0) { listener.fired(RealTimeClockImpl.this); } } catch (IOException ex) { } } }); // Set the Alarm Interrupt Enabled (AIE) flag registerB.set((byte) (registerB.get() | 0X20)); } @Override public void cancelAlarm() throws IOException { // Clear the Alarm Interrupt Enabled (AIE) flag registerB.set((byte) (registerB.get() & ~0X20)); } @Override public void close() throws IOException { if (rtc != null) { rtc.close(); } } @Override public boolean isOpen() { return rtc != null && rtc.isOpen(); } }
Thepublic class RealTimeClockProvider implements PeripheralProvider<RealTimeClock> { public RealTimeClockProvider() { } @Override public RealTimeClock open(PeripheralConfig<? super RealTimeClock> config, String[] properties, int mode) throws IOException, PeripheralException { if (mode == PeripheralManager.SHARED) { throw new UnsupportedAccessModeException(); } if (matches(properties)) { // Makes sure the requested properties are supported RealTimeClockImpl rtc = new RealTimeClockImpl((RealTimeClockConfig) config); rtc.open(); return rtc; } return null; } @Override public Class<RealTimeClock> getType() { return RealTimeClock.class; } @Override public Class<RealTimeClockConfig> getConfigType() { return RealTimeClockConfig.class; } @Override public boolean matches(String[] properties) { if (properties != null) { matched: for (String property : properties) { for (String c : RealTimeClockImpl.PROPERTIES) { if (c.equals(property)) { continue matched; } } return false; } } return true; } }
PeripheralPermission
subclass for the Real Time Clock peripheral device:
Examples of how a new Real Time Clock peripheral device may be registered under the peripheral ID# 10, with the name "RTC" and with a specific set of properties/capabilities:public class RealTimeClockPermission extends MMIOPermission { public RealTimeClockPermission(String name) { super(name); } public RealTimeClockPermission(String name, String actions) { super(name); } //... }
try { MMIODeviceConfig mmioConfig = new MMIODeviceConfig(0x0000FFFF, 64, Peripheral.LITTLE_ENDIAN, new MMIODeviceConfig.RawRegisterConfig<>(0x00, "Seconds", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x01, "SecAlarm", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x02, "Minutes", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x03, "MinAlarm", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x04, "Hours", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x05, "HrAlarm", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x06, "DayOfWk", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x07, "DayOfMo", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x08, "Month", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x09, "Year", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x0A, "RegisterA", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x0B, "RegisterB", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x0C, "RegisterC", Byte.class), new MMIODeviceConfig.RawRegisterConfig<>(0x0D, "RegisterD", Byte.class), new MMIODeviceConfig.RawBlockConfig(0x0E, "UserRam", 50)); PeripheralManager.register(10, RealTimeClock.class, new RealTimeClockConfig(mmioConfig), "RTC", "com.foobar.rtc.alarm=true", "com.foobar.rtc.time=true"); } catch (IOException ioe) { Logger.getLogger(RealTimeClockTest.class.getName()).log(Level.SEVERE, null, ioe); }
PeripheralManager.register(11, // the peripheral device ID UART.class, // the peripheral device type/interface new UARTConfig(0, 0, 2400, UARTConfig.DATABITS_8, UARTConfig.PARITY_EVEN, UARTConfig.STOPBITS_1, UARTConfig.FLOWCONTROL_NONE), // the peripheral device configuration "HOST", // the peripheral deviceName "com.foobar.uart.xxx=true", "com.foobar.uart.yyy=true" // the peripheral device capabilities );
PeripheralManager.register(12, // the peripheral device ID ModemUART.class, // the peripheral device type/interface new UARTConfig(0, 0, 2400, UARTConfig.DATABITS_8, UARTConfig.PARITY_EVEN, UARTConfig.STOPBITS_1, UARTConfig.FLOWCONTROL_NONE), // the peripheral device configuration "MODEM", // the peripheral deviceName "com.foobar.modem.xxx=true", "com.foobar.modem.yyy=true" // the peripheral device capabilities );
Copyright © 2012, 2014, Oracle and/or its affiliates. All rights reserved.
Legal Notices