Archives de catégorie : comX

A4A : Nouvelles – Mai 2015

Bonjour,

Bien décidé à étendre les capacités de « Ada for Automation » pour la gestion des solutions de communication Hilscher, j’ai donc entrepris de réaliser les blocs fonctions correspondants aux requêtes disponibles avec la pile de protocole EtherCAT Maitre, particulièrement celles permettant la lecture et l’écriture d’objets via l’interface « CoE » (CANopen over EtherCAT).

Le manuel documentant cette pile de protocole, que l’on trouve sur le DVD des solutions de communication, peut être téléchargé ici :
https://kb.hilscher.com/display/ECM3V0/EtherCAT+Master

Deux requêtes sont ainsi disponibles :

  • ETHERCAT_MASTER_CMD_SDO_UPLOAD_REQ pour la lecture d’un objet,
  • et ETHERCAT_MASTER_CMD_SDO_DOWNLOAD_REQ pour l’écriture.

Cependant, tandis que je dupliquais une requête déjà réalisée, je me suis dit qu’il était plus que temps de réusiner…

En effet, j’avais jusque là focalisé mon attention sur l’infrastructure de la messagerie et les requêtes diverses avait été écrites surtout pour valider cette infrastructure et fournir quelques exemples.

Or, les requêtes sont toutes fondées sur le même modèle et on peut sans doute mutualiser celui-ci :

  • le bloc est initialisé, c’est à dire qu’on lui attribue un canal de communication, et il récupère auprès de celui-ci l’identifiant de sa queue de réception qu’il utilisera pour l’en-tête de la requête.
  • la procédure « Cyclic », appelée cycliquement donc par le programme utilisateur, gère l’obtention du paquet pour la requête depuis le pool, l’élaboration de la requête, la transmission de celle-ci, la réception de la réponse et son traitement, et le retour du paquet réponse au pool.
  • à la fin du traitement, on peut soit utiliser le résultat, soit récupérer le code de la dernière erreur survenue éventuellement.

Les requêtes dans « Ada for Automation » sont implémentées sous la forme d’un bloc fonction qui n’est autre qu’une méthode d’un objet. En créant un objet « Requête » abstrait encapsulant les attributs communs, comme le graphe d’état, et les méthodes communes, comme la procédure « Cyclic », et en dérivant les objets requêtes de ce parent commun, l’écriture en est simplifiée tout comme la maintenance.

Les objets requêtes dérivés héritent des méthodes de leur parent.
En sus, ils comportent une méthode « Fill_Request », qui est appelée par la procédure « Cyclic » après que les champs communs de l’en-tête aient été remplis, pour fournir les éléments spécifiques de la requête.
Ils comportent également une méthode « Store_Result » qui traite le résultat après que les vérifications communes aient été faites.
Ces méthodes sont déclarées dans la partie privée du paquetage parent en ayant un corps spécifiant qu’elles doivent être implémentées dans l’objet dérivé.
Enfin, ils fournissent une méthode pour récupérer le résultat depuis le programme utilisateur.

Pour pouvoir hériter de la partie privée du parent, attributs et méthodes, les objets dérivés doivent être définis dans des paquetages fils de celui du parent. Aussi, il a fallu modifier quelque peu la hiérarchie des paquetages implémentant les requêtes déjà réalisées et bien sûr en modifier le code pour les insérer dans le nouveau schéma.

L’autre classe d’interaction avec les piles de protocoles rassemble les indications qui sont à l’initiative de la pile, contrairement aux requêtes qui sont à l’initiative du programme utilisateur.

Le même raisonnement peut être tenu à leur propos et l’on a donc implémenté un objet abstrait « Indication » et dérivé les indications déjà réalisées de celui-ci.

J’ai pour l’occasion retravaillé également les tests et les applications mettant en œuvre ces requêtes et indications.

C’est beau et ça fonctionne ! 😉

Vous pouvez suivre les modifications apportées via GitLab :
https://gitlab.com/ada-for-automation/ada-for-automation

Le même genre de requêtes de lecture et écriture d’objets est disponible quelle que soit la technologie de bus de terrain utilisée. J’envisage de réaliser les blocs fonctions correspondants pour Ethernet/IP Scanner, CANopen Maitre, PROFINET IO Controller…

L’interface applicative fournie par les solutions de communication Hilscher est riche et certaines fonctions sont certainement plus utiles pour l’application que d’autres qui le seront pour un outil de configuration ou de diagnostic évolué.

Il n’est donc pas question d’être exhaustif et le choix des réalisations se fera au gré des souhaits exprimés.

N’hésitez pas à nous faire part de vos remarques et propositions éventuelles via le forum ou par email (contact).

Cordialement,
Stéphane

A4A : Nouvelles – Avril 2015

Bonjour,

Ce mois d’Avril a été propice et l’actualité « Ada for Automation » est donc plus étoffée que de coutume.

Nouvelle présentation du site

Commençons par la nouvelle la plus visible, le changement de thème de WordPress. L’aspect n’est pas tant ce qui m’a conduit à en changer bien que je le trouve assez réussi. C’est surtout le « Responsive Design » ou la faculté de s’adapter à la taille de la fenêtre du navigateur qui a motivé mon choix.

Que vous accédiez au site depuis un PC, une tablette ou un smartphone, même un pas très smart, le site devrait être lisible, même si le contenu peut être indigeste…
Même sur un PC vous pouvez expérimenter en jouant avec la taille de la fenêtre et observer comment les différents éléments se replacent magiquement.

Hormis le choix et la disposition des « Widgets », le thème est standard.

J’espère que cette nouvelle présentation vous soit agréable.

Interface Homme-Machine – Gnoga et AICWL

Tandis que j’étudiais, comme évoqué dans cet article, les technologies Web pour une utilisation avec « Ada for Automation », Monsieur David BOTTON a créé Gnoga, un framework pour développer des applications Web en Ada :
http://www.gnoga.com/

Aussi, je suis particulièrement intéressé par ce cadre applicatif et je compte bien l’utiliser pour l’IHM d’applications « Ada for Automation » comme App1.

Pouvoir piloter l’arrosage de son potager depuis son smartphone ou sa tablette est à n’en pas douter un must ! 😉

Cependant, pour un affichage plus dynamique et des composants graphiques évolués, la bibliothèque ADA INDUSTRIAL CONTROL WIDGET LIBRARY de Monsieur Dmitry A. KAZAKOV est sans conteste plus adaptée :
http://www.dmitry-kazakov.de/ada/aicwl.htm

Ces deux solutions partagent quelques composants dont le serveur web de Monsieur Kazakov.

Bien sûr, GtkAda permet également de réaliser une IHM et les trois technologies ne s’opposent pas mais se complètent à merveille.

Vérification de style et correction des avertissements

L’un des avantages les plus proéminents du « libre » c’est qu’il permet d’apprendre beaucoup en étudiant le code écrit par la communauté.

Comme les projets évoqués ci-dessus mettent en œuvre des options permettant la vérification de style et générant un maximum d’avertissements lors de la compilation, je me suis penché sur le sujet et ai intégré dans les fichiers projets ces options documentées ici et là :
https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gnat_ugn/Style-Checking.html
https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gnat_ugn/Warning-Message-Control.html
https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gnat_ugn/Compiler-Switches.html

Il a fallu évidemment corriger beaucoup de choses… ce qui a été fait pour l’essentiel.

Réorganisation des tests

Je n’avais pas encore eu l’occasion de remercier Monsieur François FABIEN pour ses conseils avisés.

Comme François me l’avait suggéré il y a quelque temps déjà j’ai réorganisé les tests afin qu’ils aient leurs propres projets et répertoires.
Ainsi, ils n’interfèrent plus avec les autres projets et cela permet de rendre les choses plus « lisibles », du moins je l’espère.

HilscherX – réusinage de la communication acyclique

Le plus gros du travail sur le code a porté sur la partie permettant l’utilisation des cartes de communication Hilscher ainsi que des modules comX et netJACK qui partagent la même interface applicative.

Le principe de cette communication acyclique a été abordé dans un certains nombre d’articles, le premier de la série étant sans doute celui-ci. La page Plan du site liste les articles concernant l’infrastructure mise en œuvre dans « Ada for Automation » pour gérer ce type de communication.

Il y est question de Paquets, de Pool de paquets, de Queues de paquets, etc… Si le principe reste inchangé, l’implémentation a été revue car le problème était le suivant :

L’en-tête des paquets contient des identifiants de source et de destination qui permettent le routage de ces paquets. La documentation Hilscher explique ce routage en indiquant que les champs Source et Source_Id doivent identifier l’application et le processus émetteurs. Le procédé de routage doit en fonction de ces champs retrouver la queue de messages correspondante.

Cependant, un raccourci employé est de renseigner ces champs avec les pointeurs de queues directement comme on peut le constater couramment dans la documentation relative aux piles de protocoles. Dans le firmware des produits, le système d’exploitation rcX utilisé est un système 32 bits et les pointeurs ont une taille de 32 bits. Indiquer la valeur du pointeur de la queue permet donc un routage très rapide puisqu’il n’y a pas lieu de rechercher ce pointeur ailleurs.

Dans ma première implémentation j’avais donc utilisé le même artifice… Mais il s’est posé un problème avec ma Debian 64 bits, le pointeur de la queue ne tenait plus dans le champs !

J’ai donc revu le routage afin de passer par une table intermédiaire, la Queue_Map, qui associe les pointeurs de queues et des indices, ces indices étant utilisés dans le champs Source_ID. Et puis, comme j’ai fait quelques progrès en Ada, j’ai également retravaillé les Pool et Queue de paquets.

HilscherX – RCX_GET_DPM_IO_INFO_REQ

Dans l’interface standard Hilscher, la fameuse Dual Port Memory, les zones réservées à l’image procédé, « les IO areas » comportent 5760 octets en entrée et autant en sortie.
Dans la plupart des cas d’utilisation c’est plutôt confortable et seule une partie de ces octets sont utilisés.

Les fonctions de l’API, xChannelIORead et xChannelIOWrite, qui permettent l’accès à ces zones prennent en paramètres un offset et une taille de données, ce qui permet de ne rafraîchir que les données effectivement configurées, avec bien sûr un gain de temps à la clef.

Il est possible avec la requête RCX_GET_DPM_IO_INFO_REQ de récupérer les informations concernant les zones IO, offset et taille, et nous avons donc implémenté un bloc fonction pour cela, le test qui va avec et modifié la tâche principale du projet « A4A_HilscherX » en conséquence.

Ainsi, les projets comme « App2 » qui héritent de « A4A_HilscherX » en profitent naturellement.

HilscherX – Diagnostic générique

Le document consacré à la Dual Port Memory mentionne, pour chaque canal de communication,

  • un « Common Status » qui permet de connaître un état de la communication commun à toutes les piles de protocoles,
  • un « Extended Status » qui permet de connaître un état de la communication relatif à chaque pile de protocole et documenté dans le manuel de la pile.

L’état étendu n’est pas utilisé par toutes les piles.

Pour certaines piles comme PROFIBUS DP Maitre, CANopen Maitre ou DeviceNet Maitre, cette zone contient la structure de diagnostic fournie par l’ancienne gamme des CIF, aujourd’hui obsolète, afin de faciliter la migration d’applications vers la nouvelle gamme cifX.

Cependant les capacités des bus de terrain basés sur Ethernet Temps Réel requièrent de repenser le principe du diagnostic. Pa exemple, PROFIBUS DP ne permet que 126 nœuds sur le réseau quand EtherCAT en prévoit en théorie jusqu’à 65535 !

Aussi, le manuel de la DPM indique que le diagnostic des protocoles maîtres se passe en deux temps.

Dans un premier temps, on utilise la requête RCX_GET_SLAVE_HANDLE_REQ pour récupérer une liste de « handles » d’esclaves, configurés, actifs ou présentant une information de diagnostic disponible, selon la liste demandée.

Dans un second temps, pour chaque « handle » de la liste retournée, la requête générique RCX_GET_SLAVE_CONN_INFO_REQ permet de récupérer les informations de connexion de l’esclave considéré.

Chaque pile de protocole maître retourne une structure documentée dans le manuel propre à la pile.

Nous avons donc créé un bloc fonction pour RCX_GET_SLAVE_HANDLE_REQ et un pour RCX_GET_SLAVE_CONN_INFO_REQ et créé les applications de test pour PROFIBUS DP Maître et EtherCAT Maître.

Et puis ?

Je lorgne du côté de la partie « Motion Control » chez PLCopen :
http://www.plcopen.org/pages/tc2_motion_control/

J’aimerais bien construire une telle bibliothèque en Ada intégrée dans « Ada for Automation ». La spécification est téléchargeable sur le site.

Bien sûr, si un tel projet vous intéresse pour vos propres réalisations, travaillons ensemble !

Pour l’instant je ne dispose pas de matériel pour tests. A minima il me faudrait un variateur communicant, avec son moteur et son codeur.
Aussi, si un tel matériel traîne dans vos placards et vous embarrasse, pensez à moi avant de le jeter à la benne.

D’ailleurs, je suis preneur de tout équipement communicant pourvu qu’il fonctionne encore et que son alimentation ou sa taille ne soient pas incongrues.
Merci d’avance pour vos contributions matérielles, qui me permettront de réaliser expériences, démonstrations et articles sur ce blog comme j’ai déjà pu le faire ici avec un radar de chez Endress + Hauser ou avec du matériel Eaton !

N’hésitez pas à nous faire part de vos remarques et propositions éventuelles via le forum ou par email (contact).

Cordialement,
Stéphane

A4A : Temps Réel sous Linux

Bonjour,

Sans être un expert du Temps Réel sous Linux, je suis avec intérêt son actualité et les progrès réalisés, notamment les projets de l’OSADL et Xenomai.

Pour pallier mon ignorance crasse du domaine je me suis offert quelques livres dont celui de Monsieur Christophe BLAESS qui explique de manière très pédagogique ce qu’est le temps réel, quelles sont les limites et les raisons de ces limites des systèmes considérés, Linux, Linux RT et Xenomai, fournit outils et moult exemples… Bref un « must have » !
Solutions temps réel sous Linux

En plus son site regorge d’informations, je le recommande :
http://www.blaess.fr/christophe/

J’ai aussi investi, le mot n’est pas trop fort, ça pique un peu, dans les publications suivantes qui sont toutes aussi passionnantes :

Je lorgne sur la version 2012 de ce dernier que je m’offrirai sans doute en version PDF car c’est un gros pavé à transporter.

Je dis ça pour qu’à mon anniversaire vous sachiez quoi m’offrir… 😉

Revenons au sujet de ce jour.

Si l’on exécute l’application exemple « app1 » de « Ada for Automation » sur un Linux standard, par exemple une Debian Wheezy on obtient la figure suivante :

A4A-App1-Linux-10_13_18

Dans le fond, Iceweasel navigue sur le site de Blender et lit une vidéo, le tout pour charger un peu le système.

J’ai donc exécuté l’application avec une tâche principale périodique de période 10 ms et les statistiques d’ordonnancement montrent que :

  • 28761 cycles ont démarré à t + [0 – 100µs]
  • 2087 cycles ont démarré à t + ]100µs – 1ms]
  • 397 cycles ont démarré à t + ]1ms – 10ms]
  • 3 cycles ont démarré à t + ]10ms – 20ms]

Cela convient pour de nombreuses applications d’automatisme mais on peut sans doute faire mieux.

Dans Synaptic, le logiciel qui va bien sous Debian pour installer les paquets, une recherche sur « linux rt » donne tout de suite le noyau qui convient à votre machine.

On l’installe prestement et on redémarre avec le nouveau noyau RT.

La commande « uname -a » permet de vérifier cela.

Si on exécute l’application en tant qu’utilisateur lambda on n’observe qu’un léger mieux :

A4A-App1-Linux RT-user 10_20_58

Par contre, si on exécute l’application en tant qu’administrateur (root) on passe dans une autre dimension :

A4A-App1-Linux-RT-root-10ms-10_26_24

Il faut avoir certains droits, root les a tous, pour exécuter une application en temps réel. C’est normal vu que votre application peut potentiellement utiliser toute la ressource processeur au détriment des autres tâches.

Mais on obtient alors des statistiques d’ordonnancement qui montrent que la périodicité est bien plus stable que ci-dessus.

Bien sûr, pour qualifier un système il faudrait réaliser des tests à plus long terme. Mais cet article n’a pour ambition que d’afficher les capacités Temps Réel de « Ada for Automation ».

La vue suivante montre le serveur Modbus TCP en service :

A4A-App1-Linux-RT-root-10ms-10_26_55

Et celle-ci les clients Modbus TCP, le client 2 ne trouve pas le serveur correspondant et pour cause, il n’y en a pas :

A4A-App1-Linux-RT-root-10ms-10_27_08

Quelques minutes plus tard :

A4A-App1-Linux-RT-root-10ms-10_27_30

Et ça donne quoi avec une période de 1ms ?

Hé bien ça fonctionne !

A4A-App1-Linux-RT-root-1ms-10_48_43

A4A-App1-Linux-RT-root-1ms-10_48_58

A4A-App1-Linux-RT-root-1ms-10_49_06

Évidemment, avec du Modbus TCP, avoir une tâche qui tourne à la milliseconde n’est pas raisonnable, ça ne sert pas à grand chose.

Par contre, avec les solutions de communication Hilscher ça prend un autre relief ! 🙂

Cordialement,
Stéphane

A4A : Diagnostic et accès distant

Bonjour,

Les connaisseurs du DVD des Solutions de Communications cifX, comX et netJACK, notamment ceux qui ont subi une formation de ma part ;-), se souviendront de la documentation estampillée « Diagnostic and Remote Access ».

Il y est question donc de l’accès distant et du diagnostic des cibles, entendez par là une machine équipée d’une ou plusieurs solutions de communication Hilscher.

Cette documentation expose les principes de cet accès distant et on y apprend que cela permet d’utiliser les messages standards rcX, déjà évoqués dans ces colonnes et dans la documentation « netX Dual-Port Memory », ou des appels de procédures distantes, aussi appelés Remote Procedure Calls (RPC), ces procédures étant les fonctions de l’API Hilscher cifX.

Il est ainsi possible, via communication sérielle, USB ou TCP/IP de discuter avec une cible pour la configuration ou le diagnostic de la communication.

Sur ce même DVD on trouve le « cifX TCP Server », une application qui va s’exécuter au-dessus du pilote cifX et permet ainsi à l’outil de configuration SYCON.net s’exécutant sur une autre machine de configurer et diagnostiquer la cible.

Toujours sur le DVD figurent les codes sources pour une implémentation côté Hôte, le code de l’application netHOST, et côté cible le code du « cifX TCP Server ».

Cette application « cifX TCP Server » ne doit pas être exécutée en même temps que l’application de contrôle-commande car ce n’est pas prévu ainsi et que ça va mettre eul brin.

Cependant si votre application de contrôle-commande intègre correctement cette fonctionnalité, en y mettant les verrous et routages nécessaires, il devient possible d’utiliser SYCON.net ou autre application de configuration et diagnostic comme FieldCare de Endress + Hauser en parallèle, ce qui est fort utile convenons-en.

C’est exactement ce qui est aujourd’hui réalisé dans « Ada for Automation »… Hé hé hé…
Oui, oui, ça marche sous Microsoft Windows® comme sous Linux.

Ainsi, votre application s’exécute normalement tandis que les merveilles exposées dans ces articles s’offrent à vos yeux ébahis :
cifX : FDT/DTM – Un exemple intéressant
cifX : FDT/DTM – Un exemple intéressant – E+H FieldCare

N’hésitez pas à nous solliciter.

Cordialement,
Stéphane

A4A : App2 avec PROFIBUS DP V1 Class 2

Bonjour,

Les derniers articles ont été consacrés à la mise en œuvre de la messagerie Hilscher dans « Ada for Automation » et un exemple autonome illustrant son utilisation pour gérer une communication PROFIBUS DP V1 Class 2 a été donné hier.

Pour terminer cette série, il nous restait à montrer l’intégration de cet exemple dans l’application exemple « App2 » déjà évoquée ici et .

Nous disposons donc maintenant d’un exemple complet montrant d’une part la communication cyclique avec la mémoire image process, commune quelle que soit la pile de protocole à l’œuvre, et d’autre part la communication acyclique avec donc des messages transportant des commandes ou des indications échangés avec le système et les piles de protocoles, chaque interface étant documentée dans un manuel propre.

Cette application « App2 » étend le projet « A4A_HilscherX » et partage ainsi entre autres le cœur, soit la tâche « A4A.Kernel.Main ». On ne présentera de celui-ci que les évolutions.

Nous avons vu qu’il nous faut une instance de l’objet « A4A.Protocols.HilscherX.Channel_Messaging » par canal de communication.

Aussi cet instance est fournie par le paquetage « A4A.HilscherX » importé par « A4A.Kernel.Main » :

with A4A.Protocols.HilscherX.Channel_Messaging;

package A4A.HilscherX is

   --------------------------------------------------------------------
   -- Hilscher cifX Channel Messaging objects
   --------------------------------------------------------------------

   Board1_Channel0_Messaging : aliased
     A4A.Protocols.HilscherX.Channel_Messaging.Instance;

end A4A.HilscherX;

On a donc dans « A4A.Kernel.Main » :

  • l’import du paquetage qui déclare l’instance,
  • après ouverture du canal, l’initialisation de l’instance,
  • l’appel d’une nouvelle procédure déclarée au niveau application, « A4A.Application.Cold_Start », qui permet de procéder à des initialisations avant de rentrer dans la boucle principale,
  • l’appel d’une nouvelle procédure déclarée au niveau application, « A4A.Application.Closing », qui permet de procéder à des dés-initialisations avant de sortir de la boucle principale,
  • et termine l’instance dûment.
with A4A.HilscherX;

...


         A4A.Log.Logger.Put (Who  => My_Ident,
                             What => "Initialising Channel Messaging...");

         A4A.HilscherX.Board1_Channel0_Messaging.Initialise
           (Channel_Handle => Channel_Handle);

...

      A4A.Log.Logger.Put
        (Who  => My_Ident,
         What => "Calling Cold_Start...");

      A4A.Application.Cold_Start;

      --------------------------------------------------------------------
      -- Main loop
      --------------------------------------------------------------------

      Main_Loop:
      loop

...

               A4A.Log.Logger.Put
                 (Who  => My_Ident,
                  What => "Calling Closing...");

               A4A.Application.Closing;

...

               A4A.Log.Logger.Put
                 (Who  => My_Ident,
                  What => "Terminating Channel Messaging...");

               A4A.HilscherX.Board1_Channel0_Messaging.Quit;

L’interface entre le programme utilisateur et le noyau est définie dans « A4A/src/a4a-application.ads » :

-----------------------------------------------------------------------
--                       Ada for Automation                          --
--                                                                   --
--              Copyright (C) 2012-2014, Stephane LOS                --
--                                                                   --
-- This library is free software; you can redistribute it and/or     --
-- modify it under the terms of the GNU General Public               --
-- License as published by the Free Software Foundation; either      --
-- version 2 of the License, or (at your option) any later version.  --
--                                                                   --
-- This library is distributed in the hope that it will be useful,   --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of    --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU --
-- General Public License for more details.                          --
--                                                                   --
-- You should have received a copy of the GNU General Public         --
-- License along with this library; if not, write to the             --
-- Free Software Foundation, Inc., 59 Temple Place - Suite 330,      --
-- Boston, MA 02111-1307, USA.                                       --
--                                                                   --
-- As a special exception, if other files instantiate generics from  --
-- this unit, or you link this unit with other files to produce an   --
-- executable, this  unit  does not  by itself cause  the resulting  --
-- executable to be covered by the GNU General Public License. This  --
-- exception does not however invalidate any other reasons why the   --
-- executable file  might be covered by the  GNU Public License.     --
-----------------------------------------------------------------------


package A4A.Application is

   --------------------------------------------------------------------
   -- User Program
   --------------------------------------------------------------------

   procedure Cold_Start;
   -- This procedure is called once during Main Task initialisation.
   -- Its purpose is to provide for first time application initialisation.

   procedure Closing;
   -- This procedure is called once during Main Task termination.
   -- It allows application to terminate cleanly.

   procedure Main_Cyclic;
   -- This is application main entry point.
   -- It is called by Main Task when in Running state.

   procedure Periodic_Run_1;
   -- This is application entry point for the periodic task 1.
   -- It is called by Periodic Task 1 when in Running state.
   
   function Program_Fault return Boolean;

private
   
   Program_Fault_Flag : Boolean := False;
   -- It is raised by exception handling in application and tested by
   -- Main Task.

end A4A.Application;

L’implémentation de ces fonctions est à la charge de l’utilisateur et pour notre programme exemple est réalisée dans « app2/src/a4a-application.adb » :

-----------------------------------------------------------------------
--                       Ada for Automation                          --
--                                                                   --
--              Copyright (C) 2012-2014, Stephane LOS                --
--                                                                   --
-- This library is free software; you can redistribute it and/or     --
-- modify it under the terms of the GNU General Public               --
-- License as published by the Free Software Foundation; either      --
-- version 2 of the License, or (at your option) any later version.  --
--                                                                   --
-- This library is distributed in the hope that it will be useful,   --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of    --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU --
-- General Public License for more details.                          --
--                                                                   --
-- You should have received a copy of the GNU General Public         --
-- License along with this library; if not, write to the             --
-- Free Software Foundation, Inc., 59 Temple Place - Suite 330,      --
-- Boston, MA 02111-1307, USA.                                       --
--                                                                   --
-- As a special exception, if other files instantiate generics from  --
-- this unit, or you link this unit with other files to produce an   --
-- executable, this  unit  does not  by itself cause  the resulting  --
-- executable to be covered by the GNU General Public License. This  --
-- exception does not however invalidate any other reasons why the   --
-- executable file  might be covered by the  GNU Public License.     --
-----------------------------------------------------------------------


with Ada.Real_Time;
with Ada.Exceptions; use Ada.Exceptions;

with A4A.Log;
with A4A.Memory; use A4A.Memory;

with A4A.User_Functions; use A4A.User_Functions;

package body A4A.Application is

   procedure Cold_Start is
   begin

      Initialise;

   end Cold_Start;

   procedure Closing is
   begin

      Close;

   end Closing;

   procedure Main_Cyclic is
      My_Ident : String := "A4A.Application.Main_Cyclic";
   begin

      Map_Inputs;

      Map_HMI_Inputs;

      EH_Level;

      PROFIBUS_DPM_DPV1C2;

      Map_Outputs;

      Map_HMI_Outputs;

   exception

      when Error: others =>
         A4A.Log.Logger.Put (Who  => My_Ident,
                             What => Exception_Information(Error));

         Program_Fault_Flag := True;

   end Main_Cyclic;

   procedure Periodic_Run_1 is
      My_Ident : String := "A4A.Application.Periodic_Run_1";
   begin

      null;

   exception

      when Error: others =>
         A4A.Log.Logger.Put (Who  => My_Ident,
                             What => Exception_Information(Error));

         Program_Fault_Flag := True;

   end Periodic_Run_1;

   function Program_Fault return Boolean is
   begin
      return Program_Fault_Flag;
   end Program_Fault;

end A4A.Application;

Cette application définit les objets nécessaires dans « app2/src/a4a-user_objects.ads » :

-----------------------------------------------------------------------
--                       Ada for Automation                          --
--                                                                   --
--              Copyright (C) 2012-2014, Stephane LOS                --
--                                                                   --
-- This library is free software; you can redistribute it and/or     --
-- modify it under the terms of the GNU General Public               --
-- License as published by the Free Software Foundation; either      --
-- version 2 of the License, or (at your option) any later version.  --
--                                                                   --
-- This library is distributed in the hope that it will be useful,   --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of    --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU --
-- General Public License for more details.                          --
--                                                                   --
-- You should have received a copy of the GNU General Public         --
-- License along with this library; if not, write to the             --
-- Free Software Foundation, Inc., 59 Temple Place - Suite 330,      --
-- Boston, MA 02111-1307, USA.                                       --
--                                                                   --
-- As a special exception, if other files instantiate generics from  --
-- this unit, or you link this unit with other files to produce an   --
-- executable, this  unit  does not  by itself cause  the resulting  --
-- executable to be covered by the GNU General Public License. This  --
-- exception does not however invalidate any other reasons why the   --
-- executable file  might be covered by the  GNU Public License.     --
-----------------------------------------------------------------------


with A4A.Library.Timers.TON; use A4A.Library.Timers;

with A4A.Protocols.HilscherX.Profibus_DPM.DPV1;

with A4A.Protocols.HilscherX.Profibus_DPM.DPV1C2.Initiate.FB;

with A4A.Protocols.HilscherX.Profibus_DPM.DPV1C2.Abort_Req.FB;

with A4A.Protocols.HilscherX.Profibus_DPM.DPV1C2.Read.FB;

with A4A.Protocols.HilscherX.Profibus_DPM.DPV1C2.Closed.FB;

use A4A.Protocols.HilscherX.Profibus_DPM;

package A4A.User_Objects is

   --------------------------------------------------------------------
   -- User Objects creation
   --------------------------------------------------------------------

   Tempo_TON_1      : TON.Instance;
   -- My Tempo TON 1

   TON_1_Q          : Boolean := False;

   --------------------------------------------------------------------
   -- Inputs from cifX PROFIBUS DPM
   --------------------------------------------------------------------

   LT_Main_Value       : Float := 0.0;
   LT_2nd_Value        : Float := 0.0;
   LT_Main_Status      : Byte  :=   0;
   LT_2nd_Status       : Byte  :=   0;

   --------------------------------------------------------------------
   -- Outputs to cifX PROFIBUS DPM
   --------------------------------------------------------------------

   LT_Display_Value    : Float := 0.0;
   LT_Display_Status   : Byte  :=   0;

   --------------------------------------------------------------------
   -- Test PROFIBUS DPM DP V1 Class 2
   --------------------------------------------------------------------

   DPV1_FB : DPV1.Instance;

   Initiate_FB : DPV1C2.Initiate.FB.Instance;

   Remote_Address : DWord := 2;

   Do_Initiate    : Boolean := False;
   Initiate_Done  : Boolean := False;
   Initiate_Error : Boolean := False;

   Initiate_Cnf_Pos_Data  : DPV1C2.Initiate.PROFIBUS_FSPMM2_INITIATE_CNF_POS_T;

   Abort_FB : DPV1C2.Abort_Req.FB.Instance;

   Do_Abort    : Boolean := False;
   Abort_Done  : Boolean := False;
   Abort_Error : Boolean := False;

   Abort_Cnf_Data  : DPV1C2.Abort_Req.PROFIBUS_FSPMM2_ABORT_CNF_T;

   Read_FB : DPV1C2.Read.FB.Instance;

   -- Software revision from E+H Level Meter
   Slot   : DWord :=  1;
   Index  : DWord := 73;
   Length : DWord := 16;

   Do_Read    : Boolean := False;
   Read_Done  : Boolean := False;
   Read_Error : Boolean := False;

   Read_Cnf_Pos_Data  : DPV1C2.Read.PROFIBUS_FSPMM2_READ_CNF_POS_T;

   Software_Revision : String (1 .. 16);

   DPV1C2_Closed_FB : aliased DPV1C2.Closed.FB.Instance;

   Closed_Indication_Got : Boolean := False;

   Closed_Indication_Data : DPV1C2.Closed.PROFIBUS_FSPMM2_CLOSED_IND_T;

   type Block_Status is
     (X00,
      -- Initial

      X01,
      -- Initiate DPV1C2 connection

      X02,
      -- Read data from slave

      X03,
      -- Abort connection

      X04,
      -- Wait for Closed Indication

      X05
      -- Terminate
     );

   Status : Block_Status := X00;

end A4A.User_Objects;

Les fonctions utilisateurs sont spécifiées dans « app2/src/a4a-user_functions.ads » :

-----------------------------------------------------------------------
--                       Ada for Automation                          --
--                                                                   --
--              Copyright (C) 2012-2014, Stephane LOS                --
--                                                                   --
-- This library is free software; you can redistribute it and/or     --
-- modify it under the terms of the GNU General Public               --
-- License as published by the Free Software Foundation; either      --
-- version 2 of the License, or (at your option) any later version.  --
--                                                                   --
-- This library is distributed in the hope that it will be useful,   --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of    --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU --
-- General Public License for more details.                          --
--                                                                   --
-- You should have received a copy of the GNU General Public         --
-- License along with this library; if not, write to the             --
-- Free Software Foundation, Inc., 59 Temple Place - Suite 330,      --
-- Boston, MA 02111-1307, USA.                                       --
--                                                                   --
-- As a special exception, if other files instantiate generics from  --
-- this unit, or you link this unit with other files to produce an   --
-- executable, this  unit  does not  by itself cause  the resulting  --
-- executable to be covered by the GNU General Public License. This  --
-- exception does not however invalidate any other reasons why the   --
-- executable file  might be covered by the  GNU Public License.     --
-----------------------------------------------------------------------


package A4A.User_Functions is

   --------------------------------------------------------------------
   -- User functions
   --------------------------------------------------------------------

   procedure Map_Inputs;

   procedure Map_Outputs;

   procedure Map_HMI_Inputs;

   procedure Map_HMI_Outputs;

   procedure Initialise;

   procedure Close;

   procedure PROFIBUS_DPM_DPV1C2;

   procedure EH_Level;

end A4A.User_Functions;

Et elles sont implémentées dans « app2/src/a4a-user_functions.adb » :

-----------------------------------------------------------------------
--                       Ada for Automation                          --
--                                                                   --
--              Copyright (C) 2012-2014, Stephane LOS                --
--                                                                   --
-- This library is free software; you can redistribute it and/or     --
-- modify it under the terms of the GNU General Public               --
-- License as published by the Free Software Foundation; either      --
-- version 2 of the License, or (at your option) any later version.  --
--                                                                   --
-- This library is distributed in the hope that it will be useful,   --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of    --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU --
-- General Public License for more details.                          --
--                                                                   --
-- You should have received a copy of the GNU General Public         --
-- License along with this library; if not, write to the             --
-- Free Software Foundation, Inc., 59 Temple Place - Suite 330,      --
-- Boston, MA 02111-1307, USA.                                       --
--                                                                   --
-- As a special exception, if other files instantiate generics from  --
-- this unit, or you link this unit with other files to produce an   --
-- executable, this  unit  does not  by itself cause  the resulting  --
-- executable to be covered by the GNU General Public License. This  --
-- exception does not however invalidate any other reasons why the   --
-- executable file  might be covered by the  GNU Public License.     --
-----------------------------------------------------------------------


with Ada.Real_Time;

with A4A.Memory; use A4A.Memory;
with A4A.Library.Conversion; use A4A.Library.Conversion;

with A4A.Log;
with A4A.HilscherX;

with A4A.User_Objects; use A4A.User_Objects;

package body A4A.User_Functions is

   --------------------------------------------------------------------
   -- User functions
   --------------------------------------------------------------------

   procedure Map_Inputs is
   begin

      null;

   end Map_Inputs;

   procedure Map_Outputs is
   begin

      null;

   end Map_Outputs;

   procedure Map_HMI_Inputs is
   begin

      null;

   end Map_HMI_Inputs;

   procedure Map_HMI_Outputs is
   begin

      Bytes_To_Word (LSB_Byte => Hilscher_cifx0_Inputs(1),
                     MSB_Byte => Hilscher_cifx0_Inputs(0),
                     Word_out => MBTCP_IOServer_Input_Registers(1));

      Bytes_To_Word (LSB_Byte => Hilscher_cifx0_Inputs(3),
                     MSB_Byte => Hilscher_cifx0_Inputs(2),
                     Word_out => MBTCP_IOServer_Input_Registers(0));

      Bytes_To_Word (LSB_Byte => Hilscher_cifx0_Inputs(4),
                     MSB_Byte => 0,
                     Word_out => MBTCP_IOServer_Input_Registers(2));

   end Map_HMI_Outputs;

   procedure Initialise is
   begin

      Initiate_FB.Initialise
        (Channel_Access => A4A.HilscherX.Board1_Channel0_Messaging'Access);

      Abort_FB.Initialise
        (Channel_Access => A4A.HilscherX.Board1_Channel0_Messaging'Access);

      Read_FB.Initialise
        (Channel_Access => A4A.HilscherX.Board1_Channel0_Messaging'Access);

      DPV1_FB.Initialise
        (Channel_Access => A4A.HilscherX.Board1_Channel0_Messaging'Access,
         DPV1C2_Closed_Access => DPV1C2_Closed_FB'Access);

   end Initialise;

   procedure Close is
   begin

      DPV1_FB.Quit;

      --Wait for completion
      loop

         exit when DPV1_FB.Is_Terminated;
         delay 1.0;

      end loop;

   end Close;

   procedure PROFIBUS_DPM_DPV1C2 is

      My_Ident : String := "PROFIBUS_DPM_DPV1C2";

   begin

      case Status is

         when X00 => -- Initial state

            if DPV1_FB.Is_Ready then

               Status := X01;

            end if;

         when X01 => -- Initiating DPV1C2 connection

            if Initiate_Done then

               if Initiate_Error  then

                  A4A.Log.Logger.Put
                    (Who  => My_Ident,
                     What => "Connection failed");

                  Status := X05;

               else

                  A4A.Log.Logger.Put
                    (Who  => My_Ident,
                     What => "Connected");

                  Initiate_Cnf_Pos_Data := Initiate_FB.Get_Data_Pos;

                  Status := X02;

               end if;
            end if;

         when X02 => -- Reading data from slave

            if Read_Done then

               if Read_Error  then

                  A4A.Log.Logger.Put
                    (Who  => My_Ident,
                     What => "Read failed");

               else

                  A4A.Log.Logger.Put
                    (Who  => My_Ident,
                     What => "Data Read");

                  Read_Cnf_Pos_Data := Read_FB.Get_Data_Pos;

                  for I in Software_Revision'Range loop
                     exit when Read_Cnf_Pos_Data.Data (I) = 0;
                     Software_Revision (I) :=
                       Character'Val (Read_Cnf_Pos_Data.Data (I));
                  end loop;

                  A4A.Log.Logger.Put
                    (Who  => My_Ident,
                     What => "Software Revision : " & Software_Revision);

               end if;

               Status := X03;

            end if;

         when X03 => -- Aborting connection

            if Abort_Done then

               if Abort_Error  then

                  A4A.Log.Logger.Put
                    (Who  => My_Ident,
                     What => "Connection Abortion failed");

                  Status := X05;

               else

                  A4A.Log.Logger.Put
                    (Who  => My_Ident,
                     What => "Connection Aborted");

                  Abort_Cnf_Data := Abort_FB.Get_Data;

                  Status := X04;

               end if;

            end if;

         when X04 => -- Waiting for Closed Indication

            if Closed_Indication_Got then

               Closed_Indication_Data := DPV1C2_Closed_FB.Get_Data;

               if Closed_Indication_Data.CRef =
                 Initiate_Cnf_Pos_Data.Com_Ref then

                  DPV1C2_Closed_FB.Answer;
                  Status := X05;

               end if;

            end if;

         when X05 => -- Terminating

            null;

      end case;

      Do_Initiate := (Status = X01);

      Initiate_FB.Cyclic
        (Do_Command     => Do_Initiate,
         Remote_Address => Remote_Address,
         Done           => Initiate_Done,
         Error          => Initiate_Error);

      Do_Read := (Status = X02);

      Read_FB.Cyclic
        (Do_Command     => Do_Read,
         Com_Ref        => Initiate_Cnf_Pos_Data.Com_Ref,
         Slot           => Slot,
         Index          => Index,
         Length         => Length,
         Done           => Read_Done,
         Error          => Read_Error);

      Do_Abort := (Status = X03);

      Abort_FB.Cyclic
        (Do_Command     => Do_Abort,
         Com_Ref        => Initiate_Cnf_Pos_Data.Com_Ref,
         Done           => Abort_Done,
         Error          => Abort_Error);

      DPV1C2_Closed_FB.Cyclic
        (Got_Indication => Closed_Indication_Got);


   end PROFIBUS_DPM_DPV1C2;

   procedure EH_Level is

      My_Ident : String := "EH_Level";

      Word_0 : Word := 0;
      Word_1 : Word := 0;

      DWord_0 : DWord := 0;

      Elapsed_TON_1 : Ada.Real_Time.Time_Span;
   begin

      Bytes_To_Word
        (LSB_Byte => Hilscher_cifx0_Inputs(1),
         MSB_Byte => Hilscher_cifx0_Inputs(0),
         Word_out => Word_0);

      Bytes_To_Word
        (LSB_Byte => Hilscher_cifx0_Inputs(3),
         MSB_Byte => Hilscher_cifx0_Inputs(2),
         Word_out => Word_1);

      Words_To_DWord
        (LSW_Word  => Word_1,
         MSW_Word  => Word_0,
         DWord_out => DWord_0);

      LT_Main_Value := DWord_To_Float (DWord_0);

      Tempo_TON_1.Cyclic (Start   => not TON_1_Q,
                          Preset  => Ada.Real_Time.Milliseconds (10000),
                          Elapsed => Elapsed_TON_1,
                          Q       => TON_1_Q);

      if TON_1_Q then

         A4A.Log.Logger.Put
           (Who  => My_Ident,
            What => "LT_Main_Value = " & LT_Main_Value'Img & "%");

      end if;

   end EH_Level;

end A4A.User_Functions;

On remarquera particulèrement les procédures « Initialise » et « Close », appelées respectivement par les procédures « Cold_Start » et « Closing ».

Il n’y a plus de boucle comme dans l’exemple autonome car elle est implicite, c’est la boucle principale du noyau.

En fait, une partie de ce qui se trouve dans la procédure « EH_Level » pourrait figurer dans « Map_Inputs ». Il ne s’agit que d’un exemple et l’utilisateur a toute latitude pour organiser son code comme il l’entend.

La seule interface définie avec le noyau est celle spécifiée par « A4A.Application ». Au dessus, c’est ouvert. Et bien sûr, si cela ne convient pas, le code source est également ouvert ! 😉

Ci-dessous la trace correspondante :

2014-06-18 10:28:47.51 => A4A_Console_Main : started as : C:\GNAT\Projects\A4A\app2\exe\App2_CLI.exe
2014-06-18 10:28:47.51 => A4A_Console_Main :

***********************************************

          Application Identification

Name :

    Hilscher cifX Test Application (app2)

Version :

    2014/06/17

Description :

    This is the test application 2.



The purpose of this application is to demonstrate the following capabilities :

 * Command Line or Graphical User Interface,

 * Modbus TCP Server to connect a SCADA system,

 * Hilscher cifX binding,

 * some of the functions and objects of the library.



It is supposed to be run in conjunction with a SCADA system and slave devices on a supported field bus system.

***********************************************


2014-06-18 10:28:47.51 => A4A.Kernel.Sig_Handler : Waiting Signal Interrupt... Use Ctrl+C to exit
2014-06-18 10:28:47.51 => A4A.Kernel.Main_Task : Main_Task's ID is the_main_task_01ECD318

Started at 2014-06-18 10:28:47.51
2014-06-18 10:28:47.51 => A4A.Generic_Periodic_Task : started !
2014-06-18 10:28:47.51 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000000000  0.000000000
2014-06-18 10:28:47.51 => A4A_Console_Main : DPM (COS, State, Err) :                16#0#,                16#0#,                16#0#
2014-06-18 10:28:47.51 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000000000  0.000000000
2014-06-18 10:28:47.51 => A4A.MBTCP_Server.Periodic_Task 127.0.0.1: 1504 : started !
2014-06-18 10:28:47.51 => A4A.MBTCP_Server.Run : TCP_Listen... Server_Socket =  260
2014-06-18 10:28:47.51 => A4A.Kernel.Main_Task : Modbus TCP Server created...
2014-06-18 10:28:47.51 => A4A.Kernel.Main_Task : Initializing cifX Driver...
2014-06-18 10:28:47.51 => A4A.Kernel.Main_Task : Opening cifX Driver...
2014-06-18 10:28:47.51 => A4A.Kernel.Main_Task :

***********************************************

          Driver Information

Version     : cifXDriver V1.2.3.0

Board Count :  3

***********************************************


2014-06-18 10:28:47.51 => A4A.Kernel.Main_Task : Opening cifX Channel...
2014-06-18 10:28:47.51 => A4A.Kernel.Main_Task :

***********************************************

          Channel Information

Board_Name    : cifX1

Board Alias   : DPM

Device Number :  1250410

Serial Number :  20276



Firmware : PROFIBUS DP Master

Version  :  2. 6. 0(Build  13)

Date     :  2013- 11- 13

***********************************************


2014-06-18 10:28:47.51 => A4A.Kernel.Main_Task : Initialising Channel Messaging...
2014-06-18 10:28:47.51 => A4A.Kernel.Main_Task : Setting Flag Host Ready...
2014-06-18 10:28:47.51 => A4A.Kernel.Main_Task : Setting Flag Bus On...
2014-06-18 10:28:47.52 => A4A.Kernel.Main_Task : COM-flag not set
2014-06-18 10:28:47.52 => A4A.Kernel.Main_Task : Calling Cold_Start...
2014-06-18 10:28:47.52 => A4A.Protocols.HilscherX.Profibus_DPM.DPV1.DPV1_Task : Initialised !
2014-06-18 10:28:47.52 => A4A.Protocols.HilscherX.rcX_Public.rcX_Register_App.FB.Cyclic : Request Sent
2014-06-18 10:28:47.52 => A4A.Kernel.Main_Task : COM-flag not set
2014-06-18 10:28:48.52 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : Got a message :

Dest    :               16#20#

Src     :                16#1#

Dest_Id :                16#0#

Src_Id  :           16#487164#

Cmd     :             16#2F11#
2014-06-18 10:28:48.52 => A4A.Protocols.HilscherX.Profibus_DPM.DPV1.DPV1_Task : Got a message :             16#2F11#
2014-06-18 10:28:48.52 => A4A.Protocols.HilscherX.rcX_Public.rcX_Register_App.FB.Cyclic : Confirmation received fine
2014-06-18 10:28:48.52 => A4A.Protocols.HilscherX.Profibus_DPM.DPV1.DPV1_Task : App Registered !
2014-06-18 10:28:48.56 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000209061  0.000876352
2014-06-18 10:28:48.56 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:28:48.56 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001707  0.000002133
2014-06-18 10:28:48.80 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : Got a message :

Dest    :               16#20#

Src     :                16#0#

Dest_Id :                16#0#

Src_Id  :           16#487248#

Cmd     :             16#4405#
2014-06-18 10:28:48.86 => PROFIBUS_DPM_DPV1C2 : Connected
2014-06-18 10:28:49.09 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : Got a message :

Dest    :               16#20#

Src     :                16#0#

Dest_Id :                16#0#

Src_Id  :           16#4875C8#

Cmd     :             16#4407#
2014-06-18 10:28:49.17 => PROFIBUS_DPM_DPV1C2 : Data Read
2014-06-18 10:28:49.17 => PROFIBUS_DPM_DPV1C2 : Software Revision : 01.05.00        
2014-06-18 10:28:49.31 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : Got a message :

Dest    :               16#20#

Src     :                16#0#

Dest_Id :                16#0#

Src_Id  :           16#487504#

Cmd     :             16#440D#
2014-06-18 10:28:49.36 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : Got a message :

Dest    :                16#1#

Src     :         16#8017E710#

Dest_Id :           16#487164#

Src_Id  :                16#0#

Cmd     :             16#4428#
2014-06-18 10:28:49.36 => A4A.Protocols.HilscherX.Profibus_DPM.DPV1.DPV1_Task : Got a message :             16#4428#
2014-06-18 10:28:49.36 => A4A.Protocols.HilscherX.Profibus_DPM.DPV1C2.Closed.FB.Handle_Indication : Indication received
2014-06-18 10:28:49.42 => PROFIBUS_DPM_DPV1C2 : Connection Aborted
2014-06-18 10:28:49.47 => A4A.Protocols.HilscherX.Profibus_DPM.DPV1C2.Closed.FB.Cyclic : Answer Got
2014-06-18 10:28:49.52 => A4A.Protocols.HilscherX.Profibus_DPM.DPV1C2.Closed.FB.Cyclic : Response Sent
2014-06-18 10:28:49.64 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000209061  0.000876352
2014-06-18 10:28:49.64 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:28:49.64 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001706  0.000002133
2014-06-18 10:28:50.36 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : No packet pending.
2014-06-18 10:28:50.73 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000209061  0.000876352
2014-06-18 10:28:50.73 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:28:50.73 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001706  0.000002134
2014-06-18 10:28:51.36 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : No packet pending.
2014-06-18 10:28:51.82 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000209061  0.000876352
2014-06-18 10:28:51.82 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:28:51.82 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001706  0.000002134
2014-06-18 10:28:52.36 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : No packet pending.
2014-06-18 10:28:52.92 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000208634  0.001293195
2014-06-18 10:28:52.92 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:28:52.92 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001706  0.000002134
2014-06-18 10:28:53.36 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : No packet pending.
2014-06-18 10:28:53.99 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000208634  0.001293195
2014-06-18 10:28:53.99 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:28:53.99 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001280  0.000002134
2014-06-18 10:28:54.36 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : No packet pending.
2014-06-18 10:28:55.08 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000208209  0.001293195
2014-06-18 10:28:55.08 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:28:55.08 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001280  0.000002134
2014-06-18 10:28:55.36 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : No packet pending.
2014-06-18 10:28:56.15 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000208209  0.001293195
2014-06-18 10:28:56.15 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:28:56.15 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001280  0.000002134
2014-06-18 10:28:56.36 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : No packet pending.
2014-06-18 10:28:57.19 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000208209  0.001313674
2014-06-18 10:28:57.19 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:28:57.19 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001280  0.000002134
2014-06-18 10:28:57.36 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : No packet pending.
2014-06-18 10:28:57.57 => EH_Level : LT_Main_Value =  7.19014E+01%
2014-06-18 10:28:58.24 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000208209  0.001313674
2014-06-18 10:28:58.24 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:28:58.24 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001280  0.000002134
2014-06-18 10:28:58.36 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : No packet pending.
2014-06-18 10:28:58.49 => A4A.Kernel.Sig_Handler : Signal Interrupt caught !
2014-06-18 10:28:59.31 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000208209  0.001313674
2014-06-18 10:28:59.31 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:28:59.31 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001280  0.000002986
2014-06-18 10:28:59.36 => A4A.Kernel.Main_Task : Stopping Watchdog...
2014-06-18 10:28:59.36 => A4A.Kernel.Main_Task : Resetting Flag Bus On...
2014-06-18 10:28:59.36 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : No packet pending.
2014-06-18 10:28:59.48 => A4A.Kernel.Main_Task : Calling Closing...
2014-06-18 10:28:59.48 => A4A.Protocols.HilscherX.rcX_Public.rcX_Unregister_App.FB.Cyclic : Request Sent
2014-06-18 10:28:59.48 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : Got a message :

Dest    :               16#20#

Src     :                16#1#

Dest_Id :                16#0#

Src_Id  :           16#487164#

Cmd     :             16#2F13#
2014-06-18 10:28:59.48 => A4A.Protocols.HilscherX.Profibus_DPM.DPV1.DPV1_Task : Got a message :             16#2F13#
2014-06-18 10:28:59.48 => A4A.Protocols.HilscherX.rcX_Public.rcX_Unregister_App.FB.Cyclic : Confirmation received fine
2014-06-18 10:28:59.48 => A4A.Protocols.HilscherX.Profibus_DPM.DPV1.DPV1_Task : App Unregistered !
2014-06-18 10:28:59.48 => A4A.Protocols.HilscherX.Profibus_DPM.DPV1.DPV1_Task : Terminated !
2014-06-18 10:28:59.51 => A4A.Generic_Periodic_Task : finished !
2014-06-18 10:28:59.67 => A4A.MBTCP_Server.Run.Close : Closing gracefully.
2014-06-18 10:28:59.67 => A4A.MBTCP_Server.Periodic_Task 127.0.0.1: 1504 : finished !
2014-06-18 10:29:00.33 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000208209  0.001313674
2014-06-18 10:29:00.33 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:29:00.33 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001280  0.000002986
2014-06-18 10:29:00.48 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : No packet pending.
2014-06-18 10:29:00.50 => A4A.Kernel.Main_Task : Resetting Flag Host Ready...
2014-06-18 10:29:00.50 => A4A.Kernel.Main_Task : Terminating Channel Messaging...
2014-06-18 10:29:01.34 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000208209  0.001313674
2014-06-18 10:29:01.34 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:29:01.34 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001280  0.000002986
2014-06-18 10:29:01.48 => A4A.Protocols.HilscherX.Channel_Messaging.Receive_Msg_Task_Type : No packet pending.
2014-06-18 10:29:02.35 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000208209  0.001313674
2014-06-18 10:29:02.35 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:29:02.35 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001280  0.000002986
2014-06-18 10:29:02.53 => A4A.Kernel.Main_Task : Closing cifX Channel...
2014-06-18 10:29:02.53 => A4A.Kernel.Main_Task : Closing cifX Driver...
2014-06-18 10:29:02.53 => A4A.Kernel.Main_Task : Deinitializing cifX Driver...
2014-06-18 10:29:03.37 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000208209  0.001313674
2014-06-18 10:29:03.37 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:29:03.37 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001280  0.000002986
2014-06-18 10:29:03.54 => A4A.Kernel.Main_Task : finished !
2014-06-18 10:29:04.38 => A4A_Console_Main : Main Task (Status, Min, Max) : WD OK  0.000208209  0.001313674
2014-06-18 10:29:04.38 => A4A_Console_Main : DPM (COS, State, Err) :                16#7#,                16#4#,                16#0#
2014-06-18 10:29:04.38 => A4A_Console_Main : Periodic Task 1 (Status, Min, Max) : WD OK  0.000001280  0.000002986
2014-06-18 10:29:04.38 => A4A_Console_Main : finished !
Logging_Task terminated...

N’hésitez pas à nous solliciter pour toute question ou projet, présentation et démonstration ou formation !

A bientôt sur le forum, par email ou au téléphone.

Cordialement,
Stéphane