When building embedded devices, it is common to have to interface with external hardware.
This hardware may be removable, may have a separate microcontroller, typically requires custom protocols, and may also require firmware update support.
This introduces significant complexity to the embedded software stack as typically this external hardware plays a critical role in the overall device function and many processes cannot start until the hardware becomes available.
This is complicated by removable hardware that may be disconnected during operation as part of a diagnostic process.
KOS provides significant infrastructure to support hardware integration, including support for hot swap of hardware in a live system where it is electrically capable.
External hardware support in KOS is based on the abstraction of a board.
Every external device is represented within KOS as a logical board in the form of a Board class.
These classes are created at boot time and added to the assembly that defines the overall device.
These board objects provide access to the functionality of the underlying hardware, but communicate to the actual hardware via a link object.
Typically, the link object is a protocol gateway to the physical hardware, allowing methods in the board object to send corresponding operations to the physical hardware, often referred to as the physical board.
When a logical board is first created, it is not linked to a physical board.
Any operations performed on the local board will simply fail in a way that indicates the board is not linked.
Once linked, the logical board begins to function as expected, handling events from and passing operations to the actual hardware.
As logical boards are just java objects, they can be wired into the software stack like any other java objects. This allows control systems to be set up and configured during the boot process, but not fully activated until the underlying hardware is discovered and linked.
The core KOS runtime is java based but java has poor hardware integration capabilities.
Technologies such as JNI are brittle and can crash the entire java virtual machine.
So how does KOS integrate hardware into java?
The most common approach is by writing a native adapter.
An adapter is a native program, commonly written in C, which interfaces directly to the underlying hardware and connects to java over a network socket using the KOS blink protocol.
This native library is provided as part of the KOS SDK and supports command/response messages as well as asynchronous events.
All data is sent in packed binary format, which typically allows adapters to receive messages as C structures that can be operated on directly without any decoding.
As the blink protocol is endian independent, it is even possible to transparently mix different endian hardware in a single device.
As the blink protocol runs over a network socket, adapters can be run on remote nodes, making all hardware network transparent. This allows hardware on one board to be pointed to code running on another board, making remote development easy as well as providing many simplifying options for multi-node devices.
The process of linking hardware is typically driven by a discovery process.
For example, consider USB devices.
As the hardware boots, USB devices generate udev events which can be used to detect the devices.
This is typically followed by a device recognition process which may be as simple as a vendorId / productId check, but may be as complex as serial probing the device to determine what it actually is.
Ultimately, this results in dynamically starting the associated adapter, which will connect to the hardware and open a socket back to java.
When the socket is opened, it is wrapped in a link object and passed to HardwareService to be paired with a logical board.
Similarly, if the device is removed, the adapter needs to be shut down, and closing the socket then triggers the hardware to be unlinked.
This entire process is streamlined within KOS and typically involves writing an adapter and a few java classes. This model is also easily extended to other hardware interconnects such as CAN and so on.
An integral part of hardware integration is firmware update support, and KOS treats this as a first-class concept by providing a dedicated firmware service that manages all firmware updates in the device. While developers are responsible for implementing the process of retrieving firmware versions and actually putting the bits on the hardware, KOS manages everything else. KOS supports the concept of multiple firmware types per board (such as bootloader and application updates), provides progress, automatic retry and quarantine support for failed hardware, and guarantees that all devices are running firmware deemed compatible with the current software stack before the hardware is linked for use.