Several customers have tried to use our C++ or C# libraries with Windows 10 IoT on a Raspberry Pi. Unfortunately, this doesn't work because Windows 10 IoT is not a "true" Windows: it doesn't allow you to run Win32 applications. You can run only the new universal applications. We are currently working on a solution which would allow you to use our modules on all the Windows 10 versions, including Windows IoT. This post gives us the opportunity to review the matter...
UWP, what's that?
With Windows 10, Microsoft tried to unify all of its platforms (computer, phone, XBox, HoloLens, and so on). To do so, they created UWP, for United Windows Platform. Behind this barbarous name is a new type of applications which can be compiled for all of the Windows 10 platforms. This includes computers, tablets, smart phones, XBox One, but also Windows IoT Core.
You can still run traditional applications on a computer or a tablet using the Home, Pro, Enterprise, or Educational version of Windows 10, but the Mobile, XBox, and IoT Core versions of Windows 10 can only run UWP applications. Therefore, to use Windows 10 on a Raspberry Pi, the only solution is to write a "Universal Windows Platform" application. In the opposite to traditional applications (for example Word, Chrome, Steam, and so on) which use the Win32 API, UWP applications use the new Microsoft API: Windows Runtime. This API first appeared with Windows 8 and became truly pertinent with the arrival of Windows 10.
Even if this type of applications gives rise to polemics, the possibility for a developer to create a application which can run on a computer as well as on a phone or even a Raspberry Pi can be interesting. Moreover, Microsoft tries hard to force motivate developers to use UWP instead of the traditional Win32 API. The tools are the same, the programming languages are the same, and a large part of the Win32 API functions is also available in a UWP application. Unfortunately for us, the API to access USB ports is completely different.
This is the reason preventing our C++ and C# libraries to work under Windows IoT Core.
We had to find a solution...
A new UWP library
We first tried to modify our C++ library so that it could be compiled with a UWP application, but this solution was soon abandoned because it wasn't very practical and it was hard to maintain.
So we decided to create a new library designed from the start to be used with UWP applications. This library is written from start to finish in C# and uses only "Core" functions of the Windows Runtime API which are available on all the Microsoft platforms. This means that this library works on all of the Windows 10 versions, XBox One and even theoretically on HoloLens.
Using the new UWP API is not without consequences: the Microsoft API to access USB ports is an asynchronous API, and we therefore had to rethink our API so that it became completely asynchronous as well. Fortunately, the C# language supports the async and await keywords which helped us greatly. Indeed, thanks to these keywords, you can use the asynchronous functions in the same way as traditional functions as long as you follow the two rules below:
- You must add the await keyword when using an asynchronous function
- The method calling an asynchronous function must be declared as asynchronous with the asynch keyword
Microsoft has a page explaining in details how this mechanism works. Concretely, to call the get_currentValue() of the YSensor class, the code is the following:
...
private async void Button_Click(object sender, RoutedEventArgs e)
{
...
double value = await _yoctopuceSensor.get_currentValue();
...
}
...
As this mechanism is similar to the "promises" of the EcmaScript language, we kept the same conventions. Namely, all the methods of our library are asynchronous except:
- the YAPI.GetTickCount() method
- the FindXXX(hwid), FirstXXX(), and nextXXX() methods
- all the methods of the YMeasure, WlanRecord, and CellRecord classes
Another difference with the C# library is the passing by reference of the error message for the YAPI class. You cannot pass a character string by reference to an asynchronous function. We have decided to implement two versions of the YAPI class methods: one version generating an exception and one version using a YRefParam object to pass the error message. You can then call the YAPI.RegisterHub() method in two different ways:
Using exceptions:
await YAPI.RegisterHub("usb");
} catch (YAPI_Exception ex) {
string message = ex.Message;
int errorType = ex.errorType;
}
or using a YRefParam object:
int errorType = await YAPI.RegisterHub("usb", errmsg);
if (errorType != YAPI.SUCCESS) {
string message = errmsg.Value;
}
Here is the Doc-Inventory example with this library:
{
try {
await YAPI.RegisterHub("usb");
Output.Text = "Inventory:\n";
YModule module = YModule.FirstModule();
while (module != null) {
Output.Text += await module.get_serialNumber() + " (" + await module.get_upTime() + ")\n";
module = module.nextModule();
}
YAPI.FreeAPI();
} catch (YAPI_Exception ex) {
Output.Text = "Error:" + ex.Message;
}
}
The code is very similar to the traditional C# library, we simply added the await keyword to the asynchronous functions, and captured the potential exceptions.
Using the USB port
Like for Android applications, UWP applications contain a package.appxmanifest XML file describing the application and the resources to be used. If you want to access the USB ports, you must first show your credentials and list the type of modules which are going to be used. However, in the opposite to Android where you could authorize all the devices of a manufacturer, Microsoft requires each device to be listed.
The syntax is also more complex than under Android. For example, here is the Capabilities section of the file for an application using a Yocto-LatchedRelay and a Yocto-Relay:
<DeviceCapability Name="humaninterfacedevice">
<!-- Yocto-LatchedRelay-->
<Device Id="vidpid:24e0 0032">
<Function Type="usage:ff00 0001" />
</Device>
<!-- Yocto-Relay-->
<Device Id="vidpid:24e0 000c">
<Function Type="usage:ff00 0001" />
</Device>
</DeviceCapability>
</Capabilities>
Beta access
As with all our other libraries, the source code is available and you can use it directly in your project written in C# or in Visual Basic. But, like for EcmaScript, we decided to announce this library while it is still in its Bêta stage. Our aim is to collect a maximum of feedback, in order to be able to adapt/modify/correct our API so that you can easily integrate it in existing projects.
The library is currently only available on GitHub: https://github.com/yoctopuce-examples/UWP_Preview
We still have to fix a few many bugs and to add the documentation and the examples before we can officially publish this library, but things should keep moving along fast. If you feel courageous and if you want to do some beta testing, you can already have a look at the library. Don't hesitate to tell us what you think of this new API.