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:
- Sensors. In addition to specifying the actual, normalized measurement, sensor kind and unit of measure shall be provided.
- Actuators. Commands to perform motions, and motion feedback information shall be provided.
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:
- Software engineers who use the OpenEL to develop middleware and software.
- Device vendors and its engineers who develop devices and components which conforms to the OpenEL.
- Engineers who are interested in embedded software development.
2. Comformance
In order to comply with this specification, the following conditions must be satisfied.
-
All devices must implement the component common definition excluding Actuator and Sensor element (section 7.4.1).
-
Actuator device must implement at least one concrete Actuator class (Section 7.4.1.7).
-
The sensor device must implement at least one concrete Sensor class (Section 7.4.1.8).
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.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
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
Details of each state are shown below.
-
Initializing: A state in which device-specific processing is performed. Methods of HALComponent cannot be called.
-
Initialized: The state where initialization of the device is completed. Only Init() is callable.
-
Active: A state in which it is operating as a HALComponent. All APIs of HALComponent other than Init() and ReInit() can be called.
-
Error: A state in which the operation is stopped due to an internal error etc. ReInit() and Finalize() can be called.
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.6 Execute the initialization process.
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.
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.
- PIM classes are mapped to C structures.
- PIM interfaces are mapped to C functions.
- PIM enumerated types are mapped to C enums or macro.
- Since it is difficult to realize generalization in C, implement the contents defined in all superclasses in the lowest subclass.
- The out-type argument of each method is mapped to a pointer.
7.5.2 Type Definition
Primitive types used in PIM are mapped to the following types respectively.
- Integer: int32_t
- String: pointer
- Real: halfloat(float32_t or float64_t) Also, for elements with multiplicity of *, map to pointer.
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 |