Gasync

From GIMX
Jump to: navigation, search

The gasync (Gimx ASYNChronous) library is the evolution of the GE (Gimx Events) library.
In addition to input devices (mice, keyboards, joysticks), gasync also handles the following components:

  • serial ports (DIY USB adapter)
  • high-resolution timers (delayed or periodic tasks)
  • USB devices (authentication sources)
  • HID devices (Logitech Wheels, GPP/Cronus/Titan One, custom input device drivers)

It also provides a waiting interface based on poll on GNU/Linux and MsgWaitForMultipleObject on Windows.

Abstract

Gimx asks the kernel to be notified about events on a set of resources (file descriptors on GNU/Linux and handles on Windows).
Each resource has callbacks that are called on events like data available, write completed, or IO error.
Resources can be of various types: USB device, timer, input device, HID device, serial device, network socket (server mode), bluetooth socket. Network and bluetooth sockets are not integrated into gasync yet.
When data is available a read is performed and the data is passed to the callback. The callback then processes the data and may submit some IOs depending on various conditions.

Components

gpoll

This interface allows to wait on a set of resources: it asks the kernel to be notified about events on a set of resources.
Resources are registered / unregistered by the other gasync components (detailed below).
Resources are registered through gpoll_register_fd() or gpoll_register_handle() function calls.
Resources are unregistered through gpoll_remove_fd() or gpoll_remove_handle() function calls.
Once the desired resources are registered, the gpoll() function is called. When a resource is notified, it calls the callback provided at registration.
The gpoll function returns when a callback returns a value different from 0. This allows to terminate the process cleanly.

ginput

This component allows access to input devices, such as mice, keyboards, and joysticks.
It also allows to grab the inputs, so that it's possible to prevent other applications from getting inputs.

gserial

This component provides access to serial ports.
The only serial port setting available is the baudrate.
The serial port parameters are fixed (8N1) and the transmission is in raw mode.

gtimer

This component provides periodic timers, that allow to execute tasks at periodic intervals.
One-shot timers are possible disabling the timer the first time it fires.
The period may be rounded depending on the available timer resolution.
Strict periodicity is not guaranteed, and a timer may drift over the time.
Two timers may drift relatively, even if they have the same period.
The only guarantee is the interval between two timer firing to be not lower than the (rounded) period.
For example, if the timer is started at t0 and the period is 4ms, it is possible to have the following timeline:
t0 + 4: 1st firing, t0 + 8: firing missed (the kernel did not schedule the process), t0 + 9: 2nd firing, t0 + 13: 3nd firing (at least 4ms after the 2nd firing), ...

gusb

This component provides access to USB devices.

ghid

This component provides access to HID devices.

guhid

This component is GNU/Linux specific, and allows to connect a userspace-managed HID device to the kernel HID driver.

gprio

This component allows to set the process scheduling class and priority level to the highest available.
It does not register resources.

Implementation

GNU/Linux

gpoll ginput gserial gtimer gusb ghid
poll evdev jsdev X.Org Xi2 ghid termios timerfd libusb

Notes:

  • ghid is not based on hidraw because write() does not support non-blocking mode.
  • ghid claims the HID interface and detaches the kernel driver.
  • guhid is a uhid wrapper that allows to connect a ghid device back to the kernel.

Windows

gpoll ginput gserial gtimer gusb ghid
MsgWaitForMultipleObject Raw Input libSDL ghid COM ports Waitable Timers libusb HID API

Notes:

  • The libSDL events are processed synchronously.
  • The Windows HID API does not provide access to mouse and keyboards devices.
  • gtimer rounds the timer period to the highest multiple of the timer resolution not higher than the requested period (e.g. with a typical resolution of 0.5ms it rounds 16.66ms to 16.5ms).

Porting to Darwin / MAC OS X

gpoll ginput gserial gtimer gusb ghid
poll libSDL ghid termios TODO libusb

Notes:

  • gtimer has to provide a file descriptor to be given to gpoll.
  • ginput has to provide a way to capture the inputs (like constraining the mouse cursor into a window).
  • The libSDL events are processed synchronously.
  • Native input events could be added alongside the libSDL events.

Test programs

The gasync/test folder contains programs that show how to use the components and that can be used to test and validate the functionalities.

ghid_test

This program enumerates the available HID devices and asks the user to select one.
It then tries to read reports and writes force feedback for some known devices (Logitech Rumble Pad, Dualshock 4, Logitech Driving Force GT).

ginput_test

This program asks the user to select an event source for mouse and keyboards devices (physical inputs or window system).
It then shows the available input devices (mice, keyboards and joysticks) and prints the events.

gserial_test

This program writes packets to a serial port and checks if the packet can be read on the same port. The tx and rx pins have to be connected together. The following command writes / reads 1000 66-byte packets on /dev/ttyUSB0 at 500 000 bps:

./gserial_test -p /dev/ttyUSB0 -b 500000 -n 1000 -s 66

gtimer_test

This program checks the accuracy of the gtimer component.
It starts a few periodic timers and prints a message if the accuracy exceeds 10% of the period.

guhid_test

This program enumerates the available HID devices and asks the user to select one.
It then configures a uhid device, read reports and writes them to the uhid device.