Notre expertise et la puissance des technologies open source dans Azure

Logos Microsoft + Savoir-faire Linux  

 

 

 

Nous sommes heureux de vous annoncer la sortie d’une vidéo promotionnelle produite par Microsoft eux-même ! Fruit d’une collaboration autour de la plateforme Azure, cette vidéo souligne la pertinence et l’essor des technologies open source dans l’environnement infonuagique Azure de Microsoft ainsi que notre capacité d’innovation en combinant technologies open source et solutions infonuagiques hybrides.

Premier  «partenaire Microsoft Open Source» au Canada

Savoir-faire Linux est, depuis 2015, le premier  «partenaire Microsoft Open Source» au Canada. Ce partenariat rappelle notre force : la conception et l’intégration de technologies libres et open source dans des écosystèmes complexes ou hybrides, comme la plateforme Azure. Nous aidons nos clients grâce à l’innovation des technologies ouvertes et à des alliances stratégiques pour maximiser la puissance des systèmes d’information complexes ou hétérogènes et créer des environnements spécifiques pour nos clients.

Pour Microsoft, l’open source fait désormais partie intégrante de l’approche quotidienne de l’innovation cloud. En tant qu’expert et chef de file de l’industrie du logiciel libre et  des technologies open source au Canada, Savoir-faire Linux se devait d’offrir des moyens d’améliorer l’expérience des utilisateurs et des développeurs en ajoutant à son éventail de solutions, la plateforme Azure, désormais compatible avec de nombreuses technologies open source.

Apprenez-en plus sur notre expertise et notre offre de services

 

 

Voyager en Birmanie pour enseigner Linux embarqué: un souvenir inoubliable

Savoir-faire Linux a envoyé l’un de ses experts en Birmanie pour une formation Linux auprès d’une jeune compagnie spécialisée dans l’équipement industriel. Découvrez le témoignage de Julien Grossholtz à la découverte de ce pays à la fois énigmatique et pittoresque.

Une vue aérienne du Myanmar capturée via Google Maps

Je suis allé en Birmanie pour donner une formation dans ma spécialité : Linux Embarqué au sein de la compagnie Amber Star Trading. Amber Star Trading est localisée dans la petite ville de Pyin Oo Lwin, dans la région de Mandalay, au centre du pays.

À mon arrivée, j’ai visité la ville et ses alentours. Pyin Oo Lwin a été fondée par les Britanniques pendant la colonisation et on y trouve de belles maisons d’époque. L’écrivain George Orwell y a vécu pendant les années 1920. Le jardin botanique de la ville est absolument magnifique avec son lac, ses arbres tortueux, ses bambous géants, ses fleurs, ses orchidées offrant un paysage bucolique saisissant. C’était aussi un endroit idéal pour y observer la population locale : on y croise des familles en tenues traditionnelles, des enfants et de nombreux moines.

Les jardins botaniques nationaux de Kandawgyi
Les jardins botaniques nationaux de Kandawgyi

Passé les premières journées de découverte, j’ai commencé la formation. Ma mission était de former sept ingénieurs aux systèmes embarqués fonctionnant sous Linux. Nous avons abordé de nombreux thèmes : la cross-compilation, le développement d’applications, les interactions avec le hardware, buildroot, etc. Nous avons réalisé de nombreux exercices pratiques avec une carte de notre partenaire, Technologic-System, la TS-7680.

Une carte de Technologic-System: la TS-7680

Nous avons communiqué en anglais, ça n’a pas toujours été simple, mais nous avons réussi à nous comprendre avec de nombreux dessins au tableau. Mes élèves avaient des profils variés. Certains d’entre eux avaient déjà une bonne connaissance de Linux sur PC et les autres étaient spécialisés en hardware. J’ai donc adapté mon cours, mes explications et mes exercices aux besoins de chacun.

Julien Grossholtz, consultant en logiciels libres chez Savoir-faire Linux, pendant les sessions de formation

Le bilan de la formation fut très positif. Les élèves et l’entreprise attendent maintenant leurs objectifs et sont prêts à utiliser Linux pour leurs projets de  systèmes embarqués ! Pour ma part je suis fier d’avoir partagé mes connaissances, en particulier dans un pays qui évolue et qui s’ouvre petit à petit sur le monde.

Le “Quick-Phone”, découvrez notre interphone fait maison avec écran tactile !

L’équipe Ingénierie de produits de Savoir-faire Linux, ainsi que l’équipe du projet Ring, se sont récemment installés dans les nouveaux locaux sur la rue Clark à Montréal. Mais après le bonheur de l’emménagement, un problème apparut : à l’heure du déjeuner, les livreurs devaient cogner à la porte pour rentrer. Notre équipe a donc imaginé, conçu et construit un système d’interphone surnommé « Quick-Phone » (inspiré de QTQuick) pour gérer l’accès au bureau. Et voilà comment l’histoire du « Quick-Phone » fait maison commence.

Une idée de départ
Comme la plupart des entreprises, nous disposons tous ou presque d’un téléphone de bureau qui se connecte à un réseau interne en utilisant le protocole SIP. Nous décidons d’utiliser le serveur open source Asterisk afin de simplement installer un téléphone SIP régulier sur le mur extérieur pour établir une connexion entre les invités qui se tiennent à la porte et les personnes à l’intérieur. Nous voulions allé même plus loin. Pourquoi ne pas concevoir un interphone SIP moderne, sexy avec écran tactile ? Un développement open source dans un système embarqué avec une interface utilisateur… Facile, c’est ce que nous développons tous les jours pour nos clients !

Avec Technologic Systems
Pour démarrer, nos amis de Technologic Systems nous ont généreusement fait parvenir leur nouveau système tactile TS-TPC-7990 pour les besoins de notre interphone maison. Cette carte intègre un CPU ARM Quad Core NXP i.MX6 de 1 GHz avec un puissant GPU et un ensemble de codeurs / décodeurs matériels pour prendre en charge les applications graphiques et multimédia.

Système embarqué TS-7990 de Technologic Systems complet avec écran tactile capacitifn

Nous avons défini l’objectif de valeur minimum pour que le produit ait une interface simple qui répertorie tous les utilisateurs pour appeler directement une personne du département. Pour ce faire, nous avons conçu notre interface utilisateur (UI) avec Qt QML, en profitant de l’accélération matérielle pour obtenir plus de  réactivité. QML est un outil génial pour la création d’interfaces UI complexes avec OpenGL. Avec l’aide du GPU, QML offre un fonctionnement sans accroc sur les plateformes embarquées. Puis, nous avons utilisé «Qt-cinématique expérience 3D» qui fonctionne à merveille sur TS-7990, en ne consommant qu’environ 20% de la capacité de l’UC.

De plus, en utilisant un décodeur matériel dans le pipeline GStreamer, nous avons pu décoder 720p h24 stream avec presque aucune utilisation du CPU. Même si nous avons décidé de ne pas ajouter d’appels vidéo pour cette première version, ces expériences ont montré que cette carte était déjà capable de supporter des applications multimédia. En ce qui concerne le système technologique prêt à l’emploi, il fournit déjà un support pour Qt QML dans leur couche Yocto. Nous avons profité de cette opportunité et nous avons commencé à coder dans la langue QML et par la même occasion,  contribuer à la communauté open source Yocto.

Pour alimenter le système avec des données,  nous avons récupéré dans un premier temps tous les noms d’utilisateurs, numéros de postes et photos du trombinoscope présents dans notre système de gestion intégré (la plateforme ERP open source Odoo). Nous les avons stockés dans un fichier avec un simple client REST. Une étape simple mais nécessaire pour s’assurer que l’ordinateur intégré ait accès à son propre fichier indépendant de données.

Ensuite, nous avons intégré une célèbre SIP stack, pjsip et son python wrapper pour développer un simple appelant SIP. Nous avons choisi pjsip pour trois raisons. Tout d’abord, c’est une bibliothèque de communication multimédia fiable, écrite en langage C. Nous avions auparavant déjà utilisé ses bibliothèques de bas niveau pour notre téléphone DHT / SIP : Ring, et le fonctionnement était très satisfaisant. Deuxièmement, le pjsip est très efficace. Ses bibliothèques de haut niveau supportent déjà un ensemble de codecs audio tels que les codecs Speex, iLBC, GSM, G711, G722 et L16. Enfin, nous connaissions très bien les tenants et les aboutissants. En fait, en quelques heures, nous avions développé un SIP basé sur le python pjsip pour gérer les appels depuis l’interphone.

Tout assemblé, tout connecté !
Avec la soirée d’inauguration des nouveaux bureaux, nous savions que c’était le bon moment pour installer le prototype – un petit cadeau d’ouverture pour ainsi dire ! C’était aussi l’occasion de démontrer notre expertise, plus précisément notre capacité de développement logiciel et d’assemblage avec un composant industriel pour en faire un objet connecté dernier cri  ! Restait le montage de la planche sur le mur d’entrée. Nous avions besoin d’une boîte en bois sur mesure, d’une alimentation et d’une connexion, tout en disposant d’une sortie «Ethernet».

Le processus de confection de la boîte en bois par des ingénieurs de produits

Quelques problèmes ont été rencontrés, car la carte ne prenait pas en charge ‘Power-Over-Ethernet’. Nous avions besoin jusqu’à 19W (à <28V), différent d’une configuration PoE typique. Nous avons donc manipulé un injecteur PoE passif afin d’utiliser notre propre alimentation et piraté un câble Ethernet pour diviser l’alimentation du tableau. En ce qui concerne la boîte en bois, nous avons conçu un cadre personnalisé quelques coups de bombes de peinture et le tour était joué !

Test driving the ‘PoE’ setup

Après avoir monté l’appareil, nous avons fait un peu plus de débogage afin de réduire la vitesse du lien. C’était nécessaire car notre câble Ethernet piraté n’était plus correctement blindé. Mais à la fin, deux heures avant l’arrivée des invités d’inauguration, nous étions fiers : nous pouvions établir le «premier appel» entre le couloir et notre bureau. Le lendemain, le livreur est entré avec un sourire radieux sur son visage : Il n’attendait plus à la porte !

Une petite ligne de commande pour déboguer et la magie opère.

Tout en open source
L’ensemble du projet a été construit à l’aide d’outils et de bibliothèques open source. En fait, toute personne intéressée peut suivre des étapes simples afin de créer sa propre version. Visitez le dépôt GitHub pour obtenir des instructions sur la façon de construire votre propre image pour un TS-TPC-7990. Le code source de l’application QML est également disponible sur GitHub.

Un travail d’équipe
Ce fut un projet amusant qui a le mérite de fonctionner efficacement, comme une unité clé en main. Nous avons usé de l’expertise et de l’inspiration de toute l’équipe pour ce petit défi technologique. C’est ce à quoi nous nous concentrons tous les jours. Pour ce projet interne, nous avons utilisé la même «Méthodologie de développement agile» que nous utilisons pour nos clients. Nous avons définit les acteurs du

Une fin heureuse pour l’équipe prête à accueillir le monde !

projet : deux parties prenantes, un propriétaire de produit et l’équipe de développement. Nous avons organisé de courtes réunions pour comprendre les besoins, fixer les priorités, estimer l’effort pour effectuer chaque tâche, et les diviser en itérations de courts métrages. Nous avons également fixé des délais d’itérations régulières, le premier étant la journée d’inauguration. Maintenant, nos intervenants sont satisfaits, mais bien sûr, ils ont demandé quelques améliorations supplémentaires. Nous poursuivons le travail. Histoire à suivre !

Trois défis technologiques pour adapter FFmpeg aux standards TR-03

L’industrie de la radiodiffusion aujourd’hui

« Aujourd’hui, la magie du cinéma et de la télévision, c’est une histoire de sorcellerie technique » (SMPTE, 2017). Les grands radiodiffuseurs (comme Radio Canada) dépendent en grande partie d’équipements de radiodiffusion professionnels aux standards développés par la Société des Motion Pictures et Television Engineers® (SMPTE®). En plus d’arrimer par des standards universels, les diffuseurs et les fournisseurs d’équipements, la SMPTE contribue à faire progresser l’ingénierie de l’image dans l’industrie mondiale de la radiodiffusion. Présentement, l’industrie se base sur des équipements puissants mais lourds, capables de transmettre des données brutes (c’est-à-dire des signaux vidéo numériques non compressés et non cryptés) vers des équipements (terminaux) de télédiffusion (TV, ordinateur, mobile, etc.). Récemment, notre équipe d’ingénieurs s’est lancée dans l’aventure (soutenue financièrement par Radio Canada) pour tester une hypothèse technologique : Transmettre des données brutes de 3,5 Gbps, à l’aide de la plateforme FFmpeg et d’un serveur standard, le tout, sans passer par un équipement spécialisé.

Savoir-faire Linux relève le défi
L’hiver fut froid et enneigé à Montréal. Nous nous sommes donc réchauffés en passant du temps sur l’antre de FFmpeg. Notre but était de mettre en place un pipeline TR-03/SDI pouvant traiter plusieurs flux HD sur un serveur standard, tout en fabricant des dérivés basse définition du même flux grâce à FFmpeg.
Image result
Logo de FFmpeg

Plusieurs enjeux sont apparus sur notre chemin. Tout d’abord, le format TR-03 ; celui-ci n’était pas supporté dans la version upstream de FFmpeg. Le second fut la quantité de données à traiter : on parle d’un débit d’environ 3Gb/s, ce qui, d’après les développeurs de FFmpeg, n’était probablement pas possible à traiter. Enfin, il nous fallait ajouter du transcodage dans le pipeline, ce qui impliquait une charge encore plus importante sur le CPU.

L’implémentation de TR-03 ne fut pas le plus grand défi car le format vidéo était relativement simple. Nous avons donc rapidement mis en route un émetteur en utilisant GStreamer, qui possédait déjà les capacités nécessaires à l’envoi d’un tel volume de données.

Big Buck Bunny est un court métrage d’animation animé de l’Institut Blender, publié sous la forme d’un film open source sous Creative Commons License Attribution 3.0.

Une fois le flux de données en place, les freins à la performance sont devenus plus évidents. Pour identifier clairement ces freins, nous avons écrit plusieurs scénarios de référence utilisant des tests unitaires et LTTng (le roi des traceurs système sur Linux). Cela nous a permis de mettre le doigt où nous perdions des paquets, en l’occurrence, ici au niveau de la socket dans le noyau, et au niveau des buffers de l’interface réseau. Étant donné que nous contrôlions étroitement le traitement des données, il fut relativement facile d’ajuster la taille de ces buffers tout en conservant des délais acceptables. Ensuite, nous avons remarqué que le thread de FFmpeg responsable de la collecte et de décodage des données monopolisait à lui seul tout un cœur du CPU, causant occasionnellement une perte de paquets lorsque nous n’étions pas assez rapide à récupérer les données du buffer de la socket. Pour palier à ce problème, nous avons découplé le travail de collecte des données du travail de décodage. La mise en place consciencieuse de ces étapes nous a permis d’obtenir un pipeline complet ne souffrant d’aucune perte de paquets. Nous avons donc pu célébrer notre réussite avec un bon gâteau, quelque verres et un film HD que nous pouvions enfin regarder (je ne m’attendais pas à ce que Big Buck Bunny soit si drôle à regarder).

La dernière mise à jour et les nouveaux défis

Le 5 avril dernier, les contributions développées et affinées par l’équipe ont finalement été intégrées à FFmpeg, ce qui signifie que leur preuve de concept a rencontré les normes énoncées par la communauté FFmpeg et fait désormais partie de la plateforme open source.

Pour notre équipe Ingénierie de Produits, c’est une aventure trépidante et prometteuse. En dépit de tous les risques et défis, notre équipe a empiriquement démontré la possibilité d’exécuter des pipelines de traitement SDI sur un serveur standard utilisant la plateforme FFmpeg. Cette expérience est une réussite, révélant en bout de ligne l’immense potentiel de FFmpeg dans l’industrie de la radiodiffusion. Pour continuer à adpater FFmpeg aux normes de SMPTE 2110 – en constante évolution – notre équipe fait désormais face à un autre défi de taille. FFmpeg ne supportant pas la synchronisation comme décrit dans SMTPE 2110, nos experts évaluent maintenant la possibilité d’apporter les contributions nécessaires pour relever ce nouvel enjeu !

Auteurs :

  • Damien Riegel,
  • Eloi Bail, et
  • Stepan Salenikovitch.

Analyseur logique : visualiser la latence entre deux signaux numériques en temps réel avec sigrok et matplotlib

Salae Logic AnalyzerDans mon billet précédent, je décrivais comment manipuler avec Python les données extraites d’un analyseur logique Saleae afin de visualiser la latence entre deux signaux numériques et en déduire la gigue temporelle de l’un d’entre eux. En conclusion, j’émettais l’hypothèse que le SDK de Saleae pourrait nous permettre de récupérer des informations sur les signaux en temps réel et non plus par l’intermédiaire d’un fichier CSV exporté. Mais au final, c’est un logiciel libre plus générique qui nous a fourni la meilleure solution.

La solution de Saleae et son SDK

Saleae propose aux développeurs deux solutions :

  • une API (en bêta à l’heure actuelle) qui permet uniquement de contrôler leur logiciel de visualisation depuis une socket.
  • un SDK qui permet d’étendre leur logiciel et écrire son propre analyseur de protocole.

Nous aurions pu a priori nous intéresser au SDK et écrire un analyseur qui exporte à la volée la latence entre deux signaux définis, mais cette solution est dépendante du logiciel de Saleae et de son évolution, ce qui nous garantit une très faible pérennité. De plus, le logiciel de visualisation de Saleae n’a pas pour vocation d’être utilisé avec un autre analyseur logique que ceux qu’ils produisent. Nous cherchions donc une solution plus générique et permanente.

Sigrok: une suite logicielle open-source pour les analyseurs logiques

C’est lors d’une discussion entre collègues qu’Emeric Vigier m’a mit sur la piste d’un logiciel nommé Sigrok. Ayant pour objectif de fournir une solution libre et générique pour les analyseurs logiques, Sigrok est une suite logicielle permettant d’extraire les données collectées par divers types d’analyseurs et de les afficher, voire de les traiter, à l’aide de décodeurs de protocole.

Cette suite se compose de plusieurs sous-projets :

  • libsigrok : une librairie écrite en C qui standardise l’accès aux pilotes des différents analyseurs.
  • libsigrokdecode : une librairie écrite en C qui fournit une API pour le décodage de protocole. Les décodeurs sont écrits en Python (>= 3).
  • Sigrok-cli : une interface en ligne de commande pour manipuler Sigrok.
  • PulseView : une interface graphique en Qt pour manipuler Sigrok.
  • Fx2lafw : Sigrok fournit également une implémentation open source du firmware des puces Cypress FX2 qui est la puce utilisé entre autre par Saleae dans toutes les déclinaisons de ses analyseurs logiques hormis le Logic Pro 16. Ce firmware permet de programmer le FPGA pour qu’il fonctionne comme un simple analyseur logique matériel.

Sigrok : exemple d’utilisation

Un exemple de cette suite mise bout à bout sera plus parlant qu’un long discours. Nous allons donc utiliser PulseView pour capturer et visualiser les signaux d’un analyseur logique.

À l’ouverture PulseView dans sa version 0.2.0 ressemble à ceci :
[cliquez sur les images pour les agrandir]

pulseview01

Nous allons commencer une capture en laissant le périphérique de démonstration générer des signaux aléatoires :

pulseview02

Nous allons ensuite ajouter un décodeur assez simple qui calcule le rapport cyclique d’un signal numérique :

pulseview03

Chaque décodeur dispose de ses options. Dans notre cas nous allons simplement définir le canal sur lequel nous voulons appliquer le décodeur :

pulseview04

Le calcul du rapport cyclique est appliqué sur le canal et reporté directement dans l’interface de PulseView :

pulseview05

Sigrok : écriture d’un décodeur pour le calcul de la latence entre deux signaux numériques

Ce qui suit est basé sur la libsigrok et la libsigrokdecode dans leurs version 0.3.0.
Chaque décodeur de protocole est un module Python qui possède son propre sous-répertoire dans le répertoire de décodeurs libsigrokdecode.

Un décodeur se compose de deux fichiers :

  • __init__.py : Ce fichier est requis pour l’initialisation du décodeur et contient une simple description du protocole.
  • pd.py : Ce fichier contient des métadonnées sur le décodeur, et son code, la plupart du temps implémenté dans la méthode decode()

Nous allons nous intéresser au fichier pd.py contenant le code de notre décodeur. L’API de la libsigrokdecode nous fournit toutes les informations sur les signaux capturés.

Rappelons nous que pour calculer la latence entre deux signaux numériques, notre logique est de considérer l’un des signaux comme une horloge de référence, et l’autre comme une résultante de ce premier. Les deux étant liés, à chaque transition d’état du signal d’horloge, le signal résultant changera aussi d’état avec une latence plus ou moins variable. Nous parlerons de la fluctuation de cette latence plus loin.

Les options du décodeur

La première chose à faire est donc de permettre à notre décodeur de définir quel canal correspond au signal d’horloge et quel canal correspond au signal résultant. La classe du décodeur permet justement de définir quelques attributs précisant ses options, notamment celle permettant à l’utilisateur de choisir les canaux :

class Decoder(srd.Decoder):
   # ...
   channels = (
      {'id': 'clk', 'name': 'Clock', 'desc': 'Clock reference channel'},
      {'id': 'sig', 'name': 'Resulting signal', 'desc': 'Resulting signal controlled by the clock'},
   )
   ...

La méthode decode()

La seconde étape va être d’implémenter le contenu de la méthode decode(). Cette méthode est appelé par la libsigrokdecode chaque fois qu’un nouveau bloc de données à traiter est disponible.

Chaque bloc est en fait un échantillon dépendant de la fréquence d’échantillonnage de nos signaux. Par exemple pour une valeur d’échantillonnage de 100 Hz, nous obtiendrons 100 blocs de données par seconde. Ces blocs de données contiennent le numéro de l’échantillon actuel, ainsi que l’état des différents signaux à cet instant.

À partir de ces informations, il est ainsi très facile d’implémenter une machine à état qui va noter à quel échantillon à eu lieu la transition du signal d’horloge et celle du signal résultant. Le nombre d’échantillons écoulés entre les deux, multiplié par la valeur de la fréquence d’échantillonnage, va nous donner la latence exprimée en secondes.

Dans sa version simplifiée, notre machine à état ressemble à cela :

def decode(self, ss, es, data):

    self.oldpin, (clk, sig) = pins, pins

    # State machine:
    # For each sample we can move 2 steps forward in the state machine.
    while True:
        # Clock state has the lead.
        if self.state == 'CLK':
            if self.clk_start == self.samplenum:
                # Clock transition already treated.
                # We have done everything we can with this sample.
                break
            else:
                if self.clk_edge(self.oldclk, clk) is True:
                    # Clock edge found.
                    # We note the sample and move to the next state.
                    self.clk_start = self.samplenum
                    self.state = 'SIG'

        if self.state == 'SIG':
            if self.sig_start == self.samplenum:
                # Signal transition already treated.
                # We have done everything we can with this sample.
                break
            else:
                if self.sig_edge(self.oldsig, sig) is True:
                    # Signal edge found.
                    # We note the sample, calculate the latency
                    # and move to the next state.
                    self.sig_start = self.samplenum
                    self.state = 'CLK'
                    # Calculate and report the latency.
                    self.putx((self.sig_start - self.clk_start) / self.samplerate)

    # Save current CLK/SIG values for the next round.
    self.oldclk, self.oldsig = clk, sig

Les sorties de notre décodeur

La libsigrokdecode propose différentes façons de remonter les informations de notre décodeur. Une méthode register() permet d’enregistrer les sorties que notre décodeur génère. Chaque sortie a un type défini; par exemple, le type OUTPUT_ANN est utilisé pour définir une sortie de type annotation qui sera représentée dans PulseView par les boîtes graphiques que nous avons vues précédemment avec le décodeur de rapport cyclique.

Pour notre décodeur, nous voulons principalement deux types de sorties:

  • une sortie de type annotation (OUTPUT_ANN) pour visualiser la latence mise en forme dans PulseView,
  • et une sortie de type binaire (OUTPUT_BINARY) pour sortir les valeurs de latence brute sans mise en forme afin d’être analysé.

La version finale de notre décodeur inclut également une sortie de type métadonnée (OUTPUT_META) rapportant des statistiques sur les signaux manqués, mais ce n’est pas important ici.

Nos deux sorties donc sont définies dans notre décodeur comme suit :

self.out_ann = self.register(srd.OUTPUT_ANN)
self.out_bin = self.register(srd.OUTPUT_BINARY)

Pour reporter des informations sur ces sorties nous utilisons la méthode put() qui a pour prototype :

put(debut_echantillon, fin_echantillon, type_de_sortie, donnees)

type_de_sortie est une de nos deux méthodes enregistrées au préalable (out_ann, out_bin).

Pour reporter la latence entre deux signaux en utilisant le type annotation nous pourrons par exemple écrire :

put(clk_start, sig_start, out_ann, [0, [ma_latence]])

Les résultats obtenus avec notre décodeur de latence

Voici un exemple des résultats obtenus avec notre décodeur dans PulseView :
pulseview06

Et les résultats obtenus avec sigrok-cli dans sa version 0.5.0 et la sortie binaire pour avoir les valeurs de latence brute :
sigrok-cli

Visualisation des données en temps réel pour en déduire la gigue temporelle

Comme nous venons de le voir, sigrok-cli nous permet de sortir les valeurs de latence brute sur la console en temps réel. Nous allons maintenant nous intéresser aux variations de cette latence. En effet, rien ne nous garantit que la latence entre ces deux signaux sera constante.

Considérant que le signal d’horloge est périodique et sans fluctuation, en théorie, le signal résultant devrait l’être aussi et la latence entre ces deux signaux devraient être constante. Si ce n’est pas le cas, c’est qu’il y a une fluctuation de cette latence que nous avions décrite dans le précédent article comme la gigue temporelle d’un signal, et c’est ce que nous voulons visualiser maintenant.

Nous pouvons donc imaginer récupérer ces valeurs à la volée et les mettre en forme dans un graphique. Pour cela, nous allons encore une fois écrire un script en Python.

Je me suis intéressé à la librairie matplotlib et son module d’animation, qui propose une méthode FuncAnimation() permettant de définir une fonction à appeler pour mettre à jour le graphique à chaque fois que de nouvelles données sont disponibles. Cette fonction prend en paramètre la figure sur laquelle nous travaillons, la fonction d’animation à appeler et l’ensemble de données à traiter.

anim = animation.FuncAnimation(fig, animate, frames=data_gen)

Ces données peuvent être de la forme d’un générateur Python qui va très bien de paire avec la lecture d’un flux de données (merci à Guillaume Roguez pour m’avoir présenté ce type d’objet).

Ainsi à chaque fois qu’une nouvelle latence sera écrite dans le flux, notre générateur récupérera une nouvelle donnée et la fonction d’animation sera appelée.

Voici à quoi ressemble le code du générateur :

# The data generator take its
# input from file or stdin
def data_gen():
    while True:
        line = fd.readline().strip()
        if line:
            yield line

Notre fonction d’animation va, si besoin est, mettre à jour l’abscisse pour visualiser toutes les latences, et ajouter la nouvelle valeur fournie par le générateur.

# The update graph function
def animate(data):
    global x_max, x_min, x, y

    try:
        # we must recalculate the abscissa range
        x_new = float(data)
        if x_max is None or x_new > x_max:
            x_max = x_new
        if x_min is None or x_new < x_min:
            x_min = x_new
        ax.set_xlim(x_min, x_max)

        # add the new plot coordinate
        x.append(x_new)
        y.append(0)
        line.set_data(x, y)

        return line,

    except KeyboardInterrupt:
        print("leaving...")
&#91;/code&#93;

Finalement, il nous reste plus qu'à éxécuter <code>sigrok-cli</code> avec notre décodeur de latence et à récupérer ces valeurs dans notre script de visualisation.


sigrok-cli -d fx2lafw --config samplerate=24MHz --samples 2M -C 1,2 -P jitter:clk=1:sig=2 -B jitter | rt-draw.py

Ce qui nous donne le résultat final suivant et qui nous permet de visualiser la gigue temporelle du signal résultant :

rt_draw