Wockets (Alpha Version)

System Description


The wockets system is a best-effort event-based concurrent real-time system. The system is best-effort because it cannot guarantee delivering the accelerometer data (e.g. due to wireless failure). It is event-based because the system responds to external requests from applications in an event-based fashion where the system generally stays in a low-power state waiting for interesting events to happen (e.g. data arrives) and the responds appropriately (e.g visualizing the data). Finally, the system is concurrent in that it can easily share data among multiple applications (i.e processes) with minimal overhead. The system also delivers data in real-time.



Architectural Overview


image001.png

Figure 1. Wockets Architecture


Figure 1 shows the general architecture of the wockets system. The system consists of 2 components:

1. The Kernel
This is a stand-alone application that is responsible for critical functions of the system including:

a. Establishing and managing connections with wockets over Bluetooth
b. Reading and saving wockets data in efficient binary format
c. Decoding and encoding wockets data
d. Copying wockets data into shared memory buffers that can be mapped by different processes into their address spaces.

An important aspect of the kernel is that it is non-blocking (i.e. when the kernel acquires a lock it releases it soon after even when the request was not fulfilled such as connecting to a wocket). Subsequently, if the request is succeeds or fails, the kernel responds in an asynchronous fashion.


2. The Clients
These are applications that wish to use the wockets data. For example, an application might be interested at visualizing the data or using it for a game. To access wockets data, the application has to register with the kernel. This process establishes 2-way event-based channels between the application and the kernel that are used for subsequent interactions.
Figure 1 highlights some of the typical interactions that the wockets client applications can have with the kernel.


Application-Kernel Interactions

The wockets system supports 3 different ways for applications to interact with the Kernel depending on the type of messages being exchanged.

1. The Windows Registry
The registry stores information about the current configuration of the wockets system (e.g. what wockets are being used or have been discovered). Figure 2 shows a typical format of the registry.

The registry is also used to exchange parameters of infrequent control commands. For example, if an application wishes to register with the kernel to read wockets data and to receive event notifications. The application would set the COMMAND registry entry to value “REGISTER” and pass its “GUID” then the application would signal the kernel which in turn would process the registration and setup 2 way communication with the application. Later, we describe a typical interaction scenario with the kernel.

image003.jpg
external image clip_image004.jpgFigure 2. Typical format of the registry.

2. Named Events
The second form of data exchange between an application and the kernel are events. When an application wishes to talk to the kernel, there has to be a light-weight mechanism to notify the kernel of the applications request. The wockets use system-wide uniquely named events to signal the kernel. Named events are both robust and reliable constructs in the system that are typically used by the operating system kernel and drivers for asynchronous communication. We leverage these entities in our system to take advantage of their robustness, reliability and low overhead. Exchanging event channel names is done during the initial registration process. This opens a 2 way channel between an application and the kernel that can be used to issue requests or receive response.

3. Shared Mapped Memory Files
Finally, the system supports a light-weight data sharing construct for high throughput data namely shared mapped memory files. These are specialized files that can be directly mapped to the address space of an application and are less frequently paged-out unlike buffers that are allocated in the process heap. As a result, they have very low overhead and are efficient for sharing data among separate processes. In early pilot testing, using shared mapped memory files seem to have lower overhead than using memory that we allocated in our application. See performance section for more details where we compare the power consumption of a phone that uses shared memory vs heap allocated memory.


System Synchronization and Conflict Resolution


The kernel is designed to remain non-blocking. Therefore, if the kernel acquires a lock it releases the lock shortly after the lock was acquired to ensure that the system continues to operate smoothly without interruption, blocking or dead-locks. We provide in our software base core libraries that implement kernel events and ensure proper locking and synchronization of shared resources. Developers who choose to manipulate shared resources (such as registries) need to be careful in order not to introduce access exception. More clearly:

Registry Locking: Control commands are very infrequent but some require writing to the registry. In windows mobile, the registry is stored in TFAT files that allow a single writer. Attempting to write 2 commands at the same time to the registry will generate an access violation exception. Therefore, we lock the registry during these critical transactions using a system wide semaphore. Developers who wish to change the registry need to do a P() on the semaphore and then a V().

Kernel Locking: Multiple events might arrive at the same time and can result in corrupting shared data. We protect against that by maintaining a kernel lock.
It is important to emphasize that it is possible for the wockets kernel to receive contradictory commands from multiple applications. For example, an application requests a connection and another application requests a disconnection for the same wocket. Implementing policies for dealing with conflicts is important but is not directly supported by the wockets system. Such policies can be implemented on top of the kernel. Further, the wocket system is prone to flooding and thrashing, for example from repeated requests. It is the responsibility of the application to regulate the flow of events and their load on the system. Mechanisms can be added to the kernel to prevent this from happening.


Performance (on-going)


We are currently in the process of profiling the wockets system performance. To do that, we log the current drawn and voltage levels that are reported by the battery device driver. Figure 3,4,5 and 6 show the voltage dissipation and current consumption using shared memory and heap allocated memory. We saw no significant difference. One thing to note in the current consumption charts are the spikes on the edges that are produced by turning on the screen to start and stop the software. These measurements were done using a 1350 mA battery.external image clip_image006.jpg


image005.png

Figure 3. Voltage Dissipation using Shared memory

Figure 4. Voltage Dissipation using Heap Allocated memory

image007.png

Figure 5. Current Consumption using Shared memory

Figure 6. Current Consumption using Heap Allocated memory



Conclusion

The design decisions that we made were motivated by the following:

Control commands should be event-based: Most modules in the wockets source tree are event-based. The modules continuously wait in a low power state for interesting things to happen. For example, when a request to connect to a wocket is made, the kernel is signaled to process this request then goes to sleep. In addition, the event mechanism can allow us to exert flow control and simplifies the programming of many components. There are however one part of the system that is time-triggered (i.e. responds to changes at regular intervals) and that is the polling threads that wakeup every 30mseconds to service a bluetooth stream. It should be noted that time-triggering is ideal when the event stream is predictable; in this case, we know that the wockets run at 90Hz and that data arrives frequently.

Data exchange should be asynchronous: Because many of the requests to the kernel have no instantaneous responses, we preferred an event-based mechanism rather than a time-triggered mechanism. It should be noted that the system uses time-triggering when the events are predictable, for example, receive socket calls are time-triggered. Using time-triggering is ideal when we have a predictable event stream. The asynchrony in communication has the desirable side effect of making the programming easier and lower overhead for the system. Moreover, the use of system-wide named events makes the exchange as reliable as asynchronous exchanges of device drivers in the system.

The system need to tolerate faulty applications: The kernel contains very short and critical segments of the system that record and decode the data. The separation of this component from the rest of the system makes the data gathering portion of the system more reliable and reduces the complexity of the system. For example, failures that occur in the GUI will not cause the system to stop gathering data which is particularly important when running real-time experiments.

Wockets support concurrent use: Similar to existing mobile applications that use internal accelerometers, we anticipate that the wockets will be used by multiple applications. It was therefore necessary to design the system in a way to allow data sharing among applications with minimal overhead.





Kernel Interface Specification

Kernel Commands (on-going)

  • REGISTER: notifies the kernel that the application will start using its services.
  • UNREGISTER: notifies the kernel that the application will stop using its services.
  • DISCOVER: tells the kernel to start discovering wockets available within the Bluetooth range.
  • SET_SENSORS: tells the kernel which sensors will be used.
  • CONNECT: tells the kernel to connect to the selected wockets.
  • DISCONNECT: tells the kernel to disconnect the selected wockets.
  • BOOT: starts the kernel thread (this command will be implemented in the future).
  • UNBOOT: stops the kernel thread (this command will be implemented in the future).

Kernel Responses (on-going)

  • REGISTER_COMPLETED: notifies that the REGISTER command was successfully completed.
  • DISCOVERY_COMPLETED: notifies that the DISCOVERY command was successfully completed.
  • CONNECT_SUCCESS: notifies that the CONNECT command was successfully completed.
  • CONNECT_FAILURE: notifies that the CONNECT command was not completed due to an error.
  • DISCONNECT_SUCCESS: notifies that the DISCONNECT command was successfully completed.
  • DISCONNECT_FAILURE: notifies that the DISCONNECT command was not completed due to an error.
  • SET_SENSORS_SUCCESS: notifies that the SET_SENSOR command was successfully completed.
  • SET_SENSORS_FAILURE: notifies that the SET_SENSOR command was not completed due to an error.






CODE EXAMPLES



Register the application with the kernel


1. Send the REGISTER command:
When the application starts, it sends the REGISTER command to the kernel to notify that it will use the kernel services.


image009.png



2. Receive the REGISTER_SUCCESS message:
If the REGISTER command was successfully completed, spoon the kernel listener thread (see example code above).



Discover Wockets


A. Discover wockets using the example application.

  • Go to the Wockets application main screen and press the settings button. Once in the settings screen, press the Bluetooth button.

image012.png

  • Press the refresh/search button and wait until the search for wockets ends.

image014.png


  • When the Discover command finishes, a list of available wockets within the Bluetooth range will be displayed.
image016.png



B. Discover wockets via code.


1. DISCOVER wockets command:

image019.jpg

2. Wait for the DISCOVER_COMPLETED message:
First, get the message:

image021.jpg



Then, check for the message:

image023.jpg



Connect to wockets


A. Connect to wockets using the example application.

  • Select the wockets that will be used for the application by clicking on the plus symbol.
image026.jpg



  • Return to the home screen (by pressing the back button). Then, in the home screen, click the CONNECT button.

image027.png



B. Connect to wockets using via code.


1. Send the CONNECT command:
image029.jpg

2. Wait for the CONNECT_SUCCESS message:

image031.jpg



Disconnect wockets


A. Disconnect to wockets using the example application.

  • In the home screen, click the disconnect button.

image033.png



B. Disconnect to wockets using via code.


1. Send the DISCONNECT command:

image035.jpg


2. Wait for the DISCONNECT_SUCCESS message:

image037.jpg



Terminate kernel via code


image040.jpg




Plot the accelerometers signals


  • After connecting the wockets, press the ploting button located in the main screen.
  • When plotting, you will see a blue background with the real-time plots of the accelerometer signals.
image041.png

  • To go back to the main screen, press the green inverted arrow at the lower tight corner of the screen.