Aperçu de la librairie Windows UWP

Aperçu de la librairie Windows UWP

Plusieurs clients ont essayé d'utiliser nos librairies C++ ou C# avec Windows 10 IoT sur un Rapberry Pi. Hélas, cela ne fonctionne pas car Windows 10 IoT n'est pas un "vrai" Windows: il ne permet pas d’exécuter des applications Win32. Seules les nouvelles applications universelles peuvent être exécutées. Nous travaillons actuellement sur une solution qui permettrait d'utiliser nos modules sur toutes les versions de Windows 10, y compris Windows IoT. Cet article est l'occasion de faire le point sur la question...

UWP, c'est quoi?


Avec Windows 10, Microsoft a cherché à unifier toutes ses plateformes (PC, téléphone, XBox, HoloLens, etc). Pour ce faire, ils ont créé UWP, pour United Windows Platform. Derrière ce nom barbare se cache un nouveau type d'applications qui peut être compilée pour toutes les plateformes Windows 10. Cela comprend les PCs, les tablettes, les smartphones, la XBox One, mais aussi Windows IoT Core.

Il est toujours possible d'exécuter les applications traditionnelles sur un PC ou une tablette qui utilise la version Home, Pro, Enterprise ou Education de Windows 10, mais les versions Mobile, XBox et IoT Core de Windows 10 peuvent uniquement exécuter les applications UWP. Donc, pour utiliser Windows 10 sur un Raspberry Pi, la seule solution est d’écrire une application "Universal Windows Platforme". Contrairement aux applications traditionnelles (ex: Word, Chrome, Steam, etc) qui utilisent l'API Win32, les applications UWP utilisent la nouvelle API de Microsoft : Windows Runtime. Cette API est apparue la première fois avec Windows 8 et est devenue vraiment pertinente avec l'arrivée de Windows 10.

Même si ce type d'application fait polémique, la possibilité pour un développeur de créer une application qui soit utilisable sur un PC comme sur un téléphone ou encore un Raspberry Pi peut être intéressante. Du reste, Microsoft fait de gros efforts pour forcer motiver les développeurs à utiliser UWP au lieu de la traditionnelle API Win32. Les outils sont les mêmes, les langages de programmation sont les mêmes et une bonne partie des fonctions de l'API Win32 est aussi disponible dans une application UWP. Hélas pour nous, l'API pour accéder aux ports USB est complètement différente. C'est justement ce qui fait que nos librairies C++ et C# ne fonctionnent pas sous Windows IoT Core.

Il nous fallait donc trouver une solution...

Une nouvelle librairie UWP


Nous avons tout d'abord essayé de modifier notre librairie C++ pour qu'elle puisse être compilée avec une application UWP, mais cette solution à rapidement été abandonnée car elle était peu pratique et difficilement maintenable.

Nous avons donc décidé de créer une nouvelle librairie prévue dès le départ pour être utilisée avec les applications UWP. Cette librairie est écrite complètement en C# et utilise uniquement les fonctions "Core" de l'API Windows Runtime qui sont disponibles sur toutes les plateformes Microsoft. Ce qui veut dire que cette librairie fonctionne sur toutes les versions de Windows 10, la XBox One et même théoriquement sur HoloLens.

L'utilisation des nouvelles API UWP n'est pas sans conséquence: l'API de Microsoft pour accéder aux ports USB est une API asynchrone, et par conséquent nous avons dû repenser notre API pour qu'elle soit complètement asynchrone. Fort heureusement, le langage C# supporte les mots-clefs async et await ce qui facilite grandement la tâche. En effet, grâce à ces mots-clefs, il est possible d'utiliser des fonctions asynchrones de la même manière que les fonctions traditionnelles pour autant que l'on respecte les deux règles suivantes :

  1. Il faut ajouter le mot-clef await lors de l'utilisation d'une fonction asynchrone
  2. La méthode qui appelle une fonction asynchrone doit être déclarée comme asynchrone à l'aide du mot-clef async


Microsoft a une page qui explique en détails comment fonctionne ce mécanisme. Concrètement, pour appeler la méthode get_currentValue() de la classe YSensor, le code est le suivant:

private YSensor _yoctopuceSensor;
...
private async void Button_Click(object sender, RoutedEventArgs e)
{
        ...
    double value = await _yoctopuceSensor.get_currentValue();
    ...
}
...



Ce mécanisme étant similaire aux "promesses" du langage EcmaScript, nous avons gardé les mêmes conventions. A savoir, toutes les méthodes de notre librairie sont asynchrones sauf:

  • la méthodes YAPI.GetTickCount()
  • les méthodes FindXXX(hwid), FirstXXX() et nextXXX()
  • toutes les méthodes des classes YMeasure, WlanRecord et CellRecord


Une autre différence avec la librairie C# est le passage par référence du message d'erreur pour la classe YAPI. Il n'est pas possible de passer une chaîne de caractères par référence à une fonction asynchrone. Nous avons décidé d'implémenter deux versions des méthodes de la classe YAPI: une version qui génère une exception et une version qui utilise un objet YRefParam pour passer le message d'erreur. Il est donc possible d'appeler la méthode YAPI.RegisterHub() de deux manières:

En utilisant les Exceptions:

try {
    await YAPI.RegisterHub("usb");
} catch (YAPI_Exception ex) {
    string message = ex.Message;
    int errorType  = ex.errorType;
}



ou en utilisant un objet YRefParam:

YRefParam errmsg = new YRefParam();
int errorType = await YAPI.RegisterHub("usb", errmsg);
if (errorType != YAPI.SUCCESS) {
        string message = errmsg.Value;
}



Voilà ce que donne l'exemple Doc-Inventory avec cette librairie:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    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;
    }
}



Le code est très similaire à la librairie traditionnelle C#, on a simplement ajouté le mot-clef await aux fonctions asynchrones, et capturé les éventuelles exceptions.

L'utilisation du port USB


Tout comme les applications Android, les applications UWP contiennent un fichier XML package.appxmanifest qui décrit l'application et décrit les ressources qui seront utilisées. Si l'on veut accéder aux ports USB, il faut d'abord montrer patte blanche et lister le type de modules qui vont être utilisés. Cependant, contrairement à Android où il est possible d’autoriser tous les périphériques d'un constructeur, Microsoft requiert que chaque périphérique soit listé.

La syntaxe est aussi plus compliquée que sous Android. Par exemple, voici ce que donne la section Capabilities du fichier pour une application qui utilise un Yocto-LatchedRelay et un Yocto-Relay.

<Capabilities>
        <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>



Accès en Bêta


Comme toutes nos autres librairies, le code source est disponible et utilisable directement dans votre projet écrit en C# ou en Visual Basic. Mais comme pour EcmaScript, nous avons décidé d'annoncer cette librairie alors qu'elle est encore en Bêta. Notre objectif est de recueillir un maximum de feedback, de manière à pouvoir adapter/modifier/corriger notre API pour qu'elle soit facilement intégrable à des projets existants.

La librairie est pour l'instant uniquement disponible sur GitHub:https://github.com/yoctopuce-examples/UWP_Preview

Il nous reste encore à fixer quelques de nombreux bugs et ajouter la documentation et des exemples pour publier officiellement cette librairie, mais les choses devraient évoluer rapidement. Si vous vous sentez brave et que vous avez envie de faire du bêta test, vous pouvez déjà jeter un coup d’œil à cette librairie. N'hésitez pas à nous faire part de votre avis sur cette nouvelle API.

Commenter aucun commentaire Retour au blog












Yoctopuce, get your stuff connected.