Le support de Yoctopuce reçoit assez régulièrement des appels à l'aide de la part de clients un peu désemparés face au message d'erreur "Another process is already using yAPI". Ce problème est traité dans la documentation des produits Yoctopuce, mais cette semaine on va prendre le temps de bien comprendre d'où sort ce message d'erreur, et comment l'éviter.
L'API Yoctopuce
Dans presque tous les langages de programmation supportés par l'API Yoctopuce, il existe deux manières d'accéder aux modules Yoctopuce:
Accès natif
Dans ce mode, l'API accède aux modules USB en discutant directement avec la partie du système d'exploitation chargé de la gestion de l'USB. L'exemple typique est un logiciel qui gère des modules Yoctopuce connectés directement aux ports USB de la machine sur laquelle ce logiciel tourne. C'est le cas de figure le plus courant et le plus intuitif.
Accès Réseau
En mode réseau, l'API utilise Ethernet pour contacter un intermédiaire, qui lui se chargera de discuter directement avec les modules Yoctopuce. Cet intermédiaire peut être un hub Yoctopuce, tel que le YoctoHub-Ethernet, ou encore un VirtualHub.
Du point de vue programmation, la seule différence entre un code qui fonctionne en accès natif et ce même code en mode réseau est l'appel à RegisterHub. Si le premier paramètre est "usb", l'accès se fera en mode natif si au contraire c'est une adresse IP, l'accès de se fera en mode réseau.
YAPI.RegisterHub("192.168.1.3",errmsg); // utilisation en mode réseau
Vous pouvez donc très facilement convertir un programme qui fonctionne en mode natif en un programme qui fonctionne en mode réseau.
Limitation de l'API Yoctopuce
L'API Yoctopuce souffre d'une petite limitation: sur une même machine il ne peut y avoir qu'une seule application à la fois qui accède aux modules Yoctopuce en mode natif. Cette limitation est liée au fait que deux processus différents ne peuvent pas parler en même temps à un périphérique USB. En général, ce type de problème est réglé par un driver qui se charge de faire la police pour éviter que plusieurs processus ne se battent pour le même périphérique. Mais comme vous l'avez probablement remarqué, les produits Yoctopuce n'utilisent pas de drivers. Par conséquent, le premier processus qui arrive à accéder au mode natif le garde pour lui jusqu'à ce que UnregisterHub ou FreeApi soit appelé.
Assez logiquement, le VirtualHub est une application qui accède aux modules en mode natif, ce qui explique que lorsque le VirtualHub tourne, vous ne pouvez pas lancer une application qui fonctionne en mode natif sous peine d'obtenir le fameux message "Another process is already using yAPI". Notez que dans les dernières versions de l'API, le message d'erreur vous donne aussi le numéro du processus qui accaparé l'API, ce qui permet de retrouver le coupable assez facilement.
Comment contourner cette limitation
Évidement, cela pose un problème lorsqu'on veut faire fonctionner plusieurs applications Yoctopuce sur la même machine, même si elles sont complètement indépendantes et accèdent à des modules différents. Heureusement, il est assez facile de contourner cette limitation, il y a même plusieurs solutions:
- Si votre application n'a pas besoin d'accéder aux modules en permanence, vous pouvez vous contenter de faire un RegisterHub("usb"), quitte à réessayer plusieurs fois, et une fois l'accès natif obtenu, faire ce que vous avez à faire avec les modules, puis libérer l'API au plus vite. Mais rien ne vous garantit que les autres applications feront preuve du même savoir-vivre.
- On a vu que le VirtualHub sert, entre autres, à donner accès à des modules Yoctopuce à travers le réseau. Il se trouve que rien ne vous empêche de lancer un VirtualHub sur votre machine et de l'utiliser pour accéder à vos modules: l'adresse réseau locale de votre propre machine est toujours 127.0.0.1. Ainsi un simple RegisterHub("127.0.0.1") résoudra votre problème. Comme il n'y a pas de limitation sur le mode réseau, vous pouvez avoir plusieurs applications qui accèdent à vos modules Yoctopuce en même temps, pour autant qu'elles passent par un VirtualHub, qui se comporte alors plus ou moins comme un driver.
- Vous pouvez aussi utiliser une approche un peu plus subtile: essayer de détecter si un VirtualHub est disponible à l'aide de TestHub("127.0.0.1") et l'utiliser. Si aucun VirtualHub n'est détecté, vous pouvez alors vous rabattre sur l'API native:
string errmsg ="";
if (YAPI.TestHub("127.0.0.1",100, ref errmsg) == YAPI.SUCCESS) {
YAPI.RegisterHub("127.0.0.1", ref errmsg)
} else if (YAPI.RegisterHub("usb", ref errmsg) != YAPI.SUCCESS) {
MessageBox.Show(errmsg);
}
Notez qu'il est possible d'installer le VirtualHub en mode service/deamon, ce qui lui permet de démarrer en même temps que la machine et d'être disponible en permanence.
Le cas de l'API en ligne de commande
Sans précaution particulière, l'API en ligne de commande fonctionne en mode natif. Ainsi si vous voulez connaitre la liste de vos modules vous allez taper:
c:\>ymodule inventory
Si un VirtualHub tourne déjà, cela ne marchera pas. Mais vous pouvez alors demander à l'API d'utiliser le mode réseau à l'aide du flag -r.
c:\>ymodule -r 127.0.0.1 inventory
Conclusion
Il n'est pas possible de faire tourner en même deux processus qui utilise des modules Yoctopuce en mode natif, mais il est possible de contourner cette limitation en utilisant le VirtualHub et le mode réseau: c'est l'affaire d'une seule ligne de code. Si vous écrivez des applications qui travaillent avec des modules Yoctopuce, on vous recommande donc de faire en sorte qu'elles puissent fonctionner dans les deux modes, cela représente un effort négligeable et vos utilisateurs vous en remercieront.