Skip to the content.

OpenEL

OpenEL(Open Embedded Library) is a unified API(Application Programming Interface) for actuators and sensors. The specifications and implementation have been developed by JASA(Japan Embedded Systems Technology Association) since 2011.

As of October 30, 2021, version 3.2 is available.

1. Scope

This specification specifies OpenEL, which defines the minimum common API(Application Program Interface) required for hardware devices(actuators and sensors) used in embedded systems.

This specification defines the Platform-Independent Model (PIM) of a Hardware Abstraction Layer(HAL) for embedded systems that is capable to support at least the following devices:

In addition, this specification defines the Platform Specific Model (PSM) in language C based on the HAL PIM. This specification aims to enable engineers such as application vendors and device vendors to build software without any concern about the differences among the targeted devices, by standardizing the API of these devices.

Target readers of this specification include:

2. Comformance

In order to comply with this specification, the following conditions must be satisfied.

3. References

3.1 Normative References

The following normative documents contain provisions which, through reference in this text, constitute provisions of this specification. For dated references, subsequent amendments to, or revisions of, any of these publications do not apply.

[UML] Object Management Group, OMG Unified Modeling Language (OMG UML)

[ISO/IEC-9899] International Organization for Standardization, Programming languages - C, 1999

3.2 Non-normative References

4. Terms and Definition

For the purposes of this specification, the following terms and definitions apply.

None

5. Symbols

[HAL] Hardware Abstraction Layer

[OpenEL] Open Embedded Library

6. Additional Information

None

7. Hardware Abstraction Layer for embedded system(OpenEL)

7.1 General

The Hardware Abstraction Layer for embedded system(OpenEL) is a standard specification for implementing control software systems. In OpenEL, to reduce constraints on implementers such as device vendors as much as possible, only the necessary minimum common API is specified.

It is a feature of embedded system that multiple devices operate in cooperation such as synchronous control of multiple actuators and measurement using multiple sensors, therefore this specification introduces the concept of “time”.

By using the standardized API specified in this specification, portability and usability of various devices and drivers can be improved. The use case and component diagram of OpenEL is shown below.

Note: HAL4RT is the standard name when JASA proposed standardization to OMG.

Figure 7.1 Use case of OpenEL

Figure 7.1 Use case of OpenEL

Figure 7.2 Architecture of OpenEL

Figure 7.2 Architecture of OpenEL

7.2 Format and Conventions

7.2.1 Class and Interface

Classes and interfaces described in this PIM are documented using tables of the following format:

Table x.x : <Class / Interface Name>

Description : <description>
Derived From: <parent class>
Attributes
<attribute name> <attribute type> <obligation> <occurrence> <description>
Operations
<operation name> <description>
<direction> <parameter name> <parameter type> <description>

Note that derived attributes or operations are not described explicitly.

The ‘obligation’ and ‘occurrence’ are defined as follows.

Obligation

M (mandatory): This attribute shall always be supplied.
O (optional): This attribute may be supplied.
C (conditional): This attribute shall be supplied under a condition. The condition is given as a part of the attribute description.

Occurrence

The occurrence column indicates the maximum number of occurrences of the attribute values that are permissible. The followings denote special meanings.

N: No upper limit in the number of occurrences.
ord: The appearance of the attribute values shall be ordered.
unq: The appeared attribute values shall be unique.

7.2.2 Enumeration

Enumerations are documented as follows:

Table x.x: < enumeration name >

< constant name > < description>
... ...

7.3 Return Codes

At the PIM level we have modeled errors as operation return codes typed ReturnCode. Each PSM may map these to either return codes or exceptions. The complete list of return codes is indicated below.

Table 7.1: ReturnCode enumeration

HAL_OK The operation completed successfully.
HAL_ERROR An error occurred during execution of processing.

7.4 Platform Independent Model (PIM)

7.4.1 Common definition

The common part defines a mechanism for managing devices. All the components need to implement the contents defined in the common part excluding Actuator and Sensor element. The class diagram of the common part is shown below.

Figure 7.3 Common part

Figure 7.3 Common part

7.4.1.1 HALComponent

HALComponent is an element that holds information that all components should have in common.

It is possible to define a HALComponent with both Sensor and Actuator characteristics, such as cameras with gimbal mechanisms.

Derived From: None
Attributes
halId HALId M 1 ID for identifying the component.
property Property M 1 Details of the implementation content of each component.
observerList HALObserver O N A list of observers to notify upper-level applications of component-side information.
time Integer O 1 Component time information.
Time information of timer (OS timer, timer possessed by device, etc.) referenced by HALComponent.
It is used to acquire data with time from a sensor without time information.
The unit of time is implementation dependent.
Operations
Init Perform initialization processing of HALComponent.
ReInit Reset HALComponent. Reset error condition and return to normal state.
Finalize Quit HAL Component.
AddObserver Register an observer for notifying the event from the HALComponent to the upper application.
in target HALObserver M Observer to be registered.
RemoveObserver Unregister observer set in HALComponent.
in target HALObserver M Observer to be unregistered.
GetProfile Acquire property information of HALComponent
out profile Profile M Profile information of HALComponent.
GetTime Get the time information of HALComponent. For components that do not have the time attribute, HAL_Error is returned.
out time Integer M Time information of HALComponent

State transition

The State Machine of the HAL Component is shown below. Note that state transitions specific to each device are defined within the “Active” state.

Figure 7.4 State Machine of HALComponent

Figure 7.4 State Machine of HALComponent

Details of each state are shown below.

7.4.1.2 HALId

HALId is an element representing the Id identifying a HALComponent.

Derived From: None
Attributes
deviceKindId Integer M 1 Identifier for identifying the type of device.
JASA performs management.
vendorId Integer M 1 Identifier for identifying the device vendor.
JASA performs management.
productId Integer M 1 Identifier for identifying the product.
The device vendor gives a unique numbering.
instanceId Integer M 1 An identifier for identifying each device. When multiple products of the same type are used in the target system, they are used to identify them.
The application creator sets in advance by some means.

7.4.1.3 Property

Property is an element for holding details of the function of HALComponent.

Derived From: None
Attributes
id HALId M 1 An identifier representing the corresponding HALComponent.
deviceName String M 1 Name of HALComponent.
functionList String M 1 List of function names implemented by HALComponent.
When a device vendor adds and extends its own method, it describes which method is implemented by the target HALComponent. The whole image of the expanded original method is prepared by the device vendor with a spec sheet etc. The application creator shall know in advance what kind of extension method is defined.

7.4.1.4 EventTimer

The EventTimer is an element used when synchronous control is performed for a plurality of HALComponents.

There are many kind of event timers (POSIX, proprietary RTOS, … etc). The EventTimer unifies the APIs of different timers.

The EventTimer class is independent of HALComponent.

Derived From: None
Attributes
observerList TimerObserver O N A list of observers to notify upper applications that the timer has timed out
Operations
StartTimer Start the event timer.
StopTimer Stop the event timer.
SetEventPeriod Set the event occurrence cycle.
in EventPeriod Integer M Event occurrence cycle
AddObserver Register an observer for notifying the timeout event from the EventTimer to the upper application.
in target TimerObserver M Observer to be registered
RemoveObserver Unregister the observer set in EventTimer.
in target TimerObserver M Observer to be unregistered

7.4.1.5 HALObserver

ALObserver is an interface for communicating the event occurrences in HALComponent to the application. For applications that use HALComponent, it is necessary to implement elements that realize this interface.

Operations
notify_event Notify of an event occurred in HALComponent.
in source HALComponent M HALComponent object that occurred the event.
in event_id Integer M An identifier for distinguishing the type of event that has occurred.
It is not an identifier for distinguishing individual events that have occurred.
notify_error Notify of errors occurred in HALComponent.
in source HALComponent M HALComponent object that occurred the error.
in error_id Integer M An identifier to distinguish the type of error that occurred.
It is not an identifier for distinguishing individual errors that have occurred.

7.4.1.6 TimerObserver

TimerObserver is an interface for communicating the timeout event generated by the EventTimer to the application. Applications that use timer information, such as synchronous control of multiple actuators using EventTimer, need to implement elements that realize this interface.

Operations
notify_timer Notify of timeout event generated by EventTimer.
in eventTimer EventTimer M EventTimer object that timed out.

7.4.1.7 Actuator

The Actuator element defines the API that an Actuator device with one degree of freedom should provide.

Derived From: HALComponent
Attributes
value Real M NOrd Actual value of the target actuator. If the actual angle / position / velocity / torque cannot be measured, estimated value or command value.
Unit: [rad] or [m] / [rad/s] or [m/s] / [Nm] or [N]
Operations
GetValue Obtain the actual angle / position / velocity / torque of the target actuator. If the actual angle / position / velocity / torque cannot be measured, return the estimated value or command value.
out value Real 1 Actual actuator angle / position / velocity / torque.
Unit: [rad] or [m] / [rad/s] or [m/s] / [Nm] or [N]
in command Enum 1 Actuator Controller mode.
Command : POSITION / VELOCITY / TORQUE
SetValue Move the actuator to the target angle / position / velocity / torque.
This method is asynchronous and does not wait until the actuator reaches the target angle / position / velocity / torque.
If this method is called again before the actuator reaches the target angle / position / velocity / torque, the target angle / position / velocity / torque is updated.
The fact that the actuator has reached the target angle / position / velocity / torque is notified to the application side using HALObserver. However, this notification is issued only when it reaches the final target angle / position / velocity / torque. Therefore, when this method is called a plurality of times and the target angle / position / velocity / torque is updated, only the notification corresponding to the method setting the final target angle / position / velocity / torque is performed.
in value Real 1 Target angle / position / velocity / torque command.
Unit: [rad] or [m] / [rad/s] or [m/s] / [Nm] or [N]
in command Integer 1 Actuator Controller mode.
Command : POSITION_CONTROL=1 / VELOCITY_CONTROL=2 / TORQUE_CONTROL=3

The sample sequence diagram for synchronous control of multiple actuators using the API defined above is shown below.

Figure 7.5 The sample sequence diagram for synchronous control of multiple actuators.

Figure 7.5 The sample sequence diagram for synchronous control of multiple actuators.

Figure 7.6 Execute the initialization process.

Figure 7.6 Execute the initialization process.

Figure 7.7 Execute synchronous control.

Figure 7.7 Execute synchronous control.

7.4.1.8 Sensor

The Sensor element defines the API that a Sensor device should provide.

Like actuator devices, observers can be added and removed for sensor devices as well.

Derived From: HALComponent
Attributes
value Real M NOrd Measurement value of sensor device
Operations
GetValue Acquire sensor measurement value.
Used to acquire the sensor measurement value from the application side.
The sensor measurement value is output in the International System of Units.
out value Real NOrd Sensor measurement value.
out num Integer M Number of value.
GetTimedValue Acquire sensor measurement value and measurement time.
Used to acquire the sensor measurement value from the application side. Time returns the time value defined by HALComponent.
The sensor measurement value is in the International System of Units.
out value Real NOrd Sensor measurement value.
out num Integer M Number of value.
out time Integer M Time value defined by HALComponent

The sample sequence diagram for synchronizing time information among multiple sensors using the API defined above is shown below.

Figure 7.8 Execute synchronous control of multiple sensors.

Figure 7.8 Execute synchronous control of multiple sensors.

7.5 Platform Specific Model(PSM)

This section specifies the PSM for OpenEL. OpenEL offers only one PSM, which is based on the ISO/IEC 9899:1999 Programming Language C (also known as C99).

7.5.1 PIM-PSM mapping rule

The mapping rules between PIM and PSM are shown below.

7.5.2 Type Definition

Primitive types used in PIM are mapped to the following types respectively.

7.5.3 C PSM

Note:

The correct (system-specific) header file defining sized types (here: int32_t) must be included.

In macOS and probably other BSD-based systems that would be:

#include </usr/include/sys/types.h>

In many Linux systems this would be:

#include </usr/include/stdint.h>

But the actual path and header name may vary from system to system

/* ==================================================
* IMPORTANT - You need to inlude the system-specific header file
* that defines type "int32_t" here.
* ================================================== */

#ifndef HAL4RT_H
#define HAL4RT_H

#ifdef __cplusplus
namespace hal {
extern "C" {
#endif /* __cplusplus */

enum ReturnCode {
  HAL_OK = 0,
  HAL_ERROR
};

/* typedef definition */
typedef float  float32_t;
typedef double float64_t;
#if HAL_SW_FLOAT_SIZE
  typedef float32_t HALFLOAT_T;
#else
  typedef float64_t HALFLOAT_T;
#endif

typedef struct HalLinkedList_st {
        struct HalLinkedList_st *pNext;
} HAL_LINKED_LIST_T;

#define HAL_LINKED_LIST_HEAD HAL_LINKED_LIST_T linkedList;

typedef struct HalID_st {
  int32_t deviceKindId;
  int32_t vendorId;
  int32_t productId;
  int32_t instanceId;
} HALID_T;

typedef struct HalProperty_st {
  char *deviceName;
  char **sizeFunctionList;
} HALPROPERTY_T;

typedef struct HalComponent_st HALCOMPONENT_T;

typedef struct HALObserver {
  HAL_LINKED_LIST_HEAD
  void (*notify_event)(HALCOMPONENT_T *halComponent, int32_t eventId);
  void (*notify_error)(HALCOMPONENT_T *halComponent, int32_t errorId);
} HALOBSERVER_T;

#define HALCOMPONENT_BASE_MEMBER \
  int32_t handle; \
  HALID_T halId;\
  HALPROPERTY_T *property;\
  HALOBSERVER_T *observerList;\
  int32_t time;

typedef struct HalComponent_st {
  HALCOMPONENT_BASE_MEMBER
} HALCOMPONENT_T;

enum ReturnCode HalInit(HALCOMPONENT_T *halComponent);
enum ReturnCode HalReInit(HALCOMPONENT_T *halComponent);
enum ReturnCode HalFinalize(HALCOMPONENT_T *halComponent);
enum ReturnCode HalAddObserver(HALCOMPONENT_T *halComponent, HALOBSERVER_T *halObserver);
enum ReturnCode HalRemoveObserver(HALCOMPONENT_T *halComponent, HALOBSERVER_T *halObserver);
enum ReturnCode HalGetProperty(HALCOMPONENT_T *halComponent, HALPROPERTY_T *property);
enum ReturnCode HalGetTime(HALCOMPONENT_T *halComponent, int32_t *time_value);

typedef struct HalEventTimer_st HALEVENTTIMER_T;

typedef struct HalTimerObserver_st {
  HAL_LINKED_LIST_HEAD
  void (*notify_timer)(EVENTTIMER_T *eventTimer);
} HALTIMEROBSERVER_T;

typedef struct HalEventTimer_st {
  TIMEROBSERVER_T *observerList;
  int32_t eventPeriod;
} HALEVENTTIMER_T;

enum ReturnCode HalEventTimerStartTimer(EVENTTIMER_T *eventTimer);
enum ReturnCode HalEventTimerStopTimer(EVENTTIMER_T *eventTimer);
enum ReturnCode HalEventTimerSetEventPeriod(EVENTTIMER_T *eventTimer, int32_t eventPeriod);
enum ReturnCode HalEventTimerAddObserver(EVENTTIMER_T *eventTimer, TIMEROBSERVER_T *timerObserver);
enum ReturnCode HalEventTimerRemoveObserver(EVENTTIMER_T *eventTimer, TIMEROBSERVER_T *timerObserver);

typedef struct Actuator_st {
  /* HALCOMPONENT */
  HALCOMPONENT_BASE_MEMBER
  /* ACTUATOR */
  HALFLOAT_T *valueList;
} ACTUATOR_T;

#define HAL_REQUEST_POSITION_CONTROL   (1)
#define HAL_REQUEST_VELOCITY_CONTROL    (2)
#define HAL_REQUEST_TORQUE_CONTROL      (3)

enum ReturnCode HalMotorSetCommandValue(HALCOMPONENT_T *halComponent, int32_t request, HALFLOAT_T value);
enum ReturnCode HalMotorGetActualValue(HALCOMPONENT_T *halComponent, int32_t request, HALFLOAT_T *value);

typedef struct Sensor_st {
  /* HALCOMPONENT */
  HALCOMPONENT_BASE_MEMBER
  /* SENSOR */
  HALFLOAT_T *valueList;
} SENSOR_T;

enum ReturnCode HalSensorGetValueList(HALCOMPONENT_T *halComponent, int32_t *num, HALFLOAT_T *list);
enum ReturnCode HalSensorGetTimedValueList(HALCOMPONENT_T *halComponent, int32_t *num, HALFLOAT_T *list, int32_t *time);

#ifdef __cplusplus
} /* extern "C" */
} /* namespace hal */
#endif /* __cplusplus */

#endif /* HAL4RT_H */

Appendix A. HAL ID

Table A.1 : Device Kind ID

No Device Kind ID Device name Description Applicant Application date Approval date Authorizer Remarks
0 0x00000000 Test For development use JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
1 0x00000001 Motor Motor JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
2 0x00000002 GyroSensor Gyroscope Sensor JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
3 0x00000003 TorqueSensor Torque sensor JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
4 0x00000004 AccelerationSensor Acceleration Sensor JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
5 0x00000005 CompassSensor Compass Sensor JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
6 0x00000006 DistanceSensor Distance Sensor JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
7 0x00000007 ForceSensor Force Sensor JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
8 0x00000008 TemperatureSensor Temperature Sensor JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
9 0x00000009 HumiditySensor Humidity Sensor JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
10 0x0000000A CO2Sensor CO2 Sensor UTI 2021/2/1 2021/3/29 JASA JASA OpenEL WG
11 0x0000000B ColorSensor Color Sensor UTI 2021/4/19 2021/4/19 JASA JASA OpenEL WG
12 0x0000000C TouchSensor Touch Sensor UTI 2021/4/19 2021/4/19 JASA JASA OpenEL WG
13 0x0000000D CurrentSensor Current Sensor UTI 2022/2/1 2022/2/28 JASA JASA OpenEL WG
14 0x0000000E
15 0x0000000F
0xFFFFFFFF Test For development use JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee

Table A.2 : Vendor ID

No Vendor ID Vendor Short Name Vendor Name Applicant Application date Approval date Authorizer Remarks
0 0x00000000 TEST For development use JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
1 0x00000001 JASA Japan Embedded Systems Technology Association JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
2 0x00000002 UTI Upwind Technology, Inc. UTI 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
3 0x00000003 OM ORIENTAL MOTOR Co., Ltd. OM 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
4 0x00000004 NIDEC NIDEC CORPORATION NIDEC 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
5 0x00000005 RT RT Corporation UTI 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
6 0x00000006 AG ASAKUSAGIKEN UTI 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee
7 0x00000007 SEN Sensirion UTI 2021/2/1 2021/3/29 JASA JASA OpenEL WG
8 0x00000008 DIA Diarkis DIA 2021/2/1 2021/3/29 JASA JASA OpenEL WG
9 0x00000009 LEGO LEGO UTI 2021/4/19 2021/4/19 JASA JASA OpenEL WG
10 0x0000000A M5 M5Stack UTI 2021/4/19 2021/4/19 JASA JASA OpenEL WG
11 0x0000000B NVIDIA NVIDIA UTI 2022/2/1 2022/2/28 JASA JASA OpenEL WG
12 0x0000000C
13 0x0000000D
14 0x0000000E
15 0x0000000F
0xFFFFFFFF TEST For development use JASA 2018/5/7 2018/5/7 JASA JASA OpenEL International Standardization Committee

Table A.3 : Product ID

Vendor ID Vendor Short Name Vendor Name Product ID Product Name
0x00000000 TEST For development use
0x00000001 JASA Japan Embedded Systems Technology Association
0x00000002 UTI Upwind Technology, Inc. 0x00000001 UTRX-17
0x00000003 OM ORIENTAL MOTOR Co., Ltd.
0x00000004 NIDEC NIDEC CORPORATION
0x00000005 RT RT Corporation 0x00000001 USB-9AXIS
0x00000006 AG ASAKUSAGIKEN 0x00000001 AGB65-DCM
0x00000007 SEN Sensirion 0x00000001 SCD30
0x00000008 DIA Diarkis 0x00000001 Diarkis
0x00000009 LEGO LEGO 0x00000001 EV3
0x0000000A M5 M5Stack 0x00000001 BALA2
0x0000000B NVIDIA NVIDIA 0x00000001 JETBOT
0x0000000C
0x0000000D
0x0000000E
0x0000000F
0xFFFFFFFF TEST For development use