Archives par mot-clé : PROFIBUS

A4A : Exemple d’application 6 : Modbus TCP Client / Serveur + deux canaux Hilscher

Bonjour,

Comme je l’indiquais récemment l’application « app6_gui » offre :

  • un serveur Modbus TCP pour y connecter par exemple un SCADA du marché,
  • une fonction IO Scanning avec une tâche client Modbus TCP par serveur d’E/S,
  • deux canaux cifX Hilscher, pour gérer deux cartes, par exemple une PROFIBUS DP Maitre et une EtherCAT Maitre, ou pour gérer une carte à deux canaux comme par exemple un PROFIBUS DP Maitre et un CANopen Maitre,
  • une interface graphique avec GtkAda, permettant de consulter l’état des communications et de l’application et de démarrer ou arrêter les programmes utilisateur,
  • l’intégration du « cifX TCP Server » permettant la configuration et le diagnostic des cartes par SYCON.net via une connexion TCP/IP.

Je voulais faire un article à part pour cette application, avec des images. J’ai donc monté la manipulation suivante :

Manip-2016-01-08

On a donc un PC, sous Debian Jessie et un noyau Linux 64 bit standard, avec deux cartes Hilscher PCI, une cifX 50-DP configurée en Maître PROFIBUS DP et une cifX 50-RE configurée en Maître EtherCAT :

PC+2cifX50

Comme Esclave PROFIBUS DP j’ai une carte Hilscher CB-AB32-DPS, un « piano » avec deux octets en entrée et autant en sortie qui permet de monter une manipulation en deux secondes et demie :

CB-AB32-DPS

Pour EtherCAT, j’ai également un « piano », le NXIO 500-RE, qui reçoit sa fonctionnalité en insérant la carte MMC qui convient, ici EtherCAT Esclave, avec toujours deux octets d’E/S :

NXIO-500-RE

Le client Modbus TCP qui interroge le serveur de l’application 6 est Modbus Poll dont j’ai déjà fait mention il y a longtemps.

Quant au client Modbus TCP, ce que certains appellent IO Scanning, il est configuré pour exécuter deux requêtes sur un serveur d’un genre particulier sur lequel je reviendrai plus tard.

Je vous épargne la trace laissée par l’application dans le terminal depuis lequel elle est lancée, qui est certes informative, voire même didactique, mais un peu indigeste.

La fenêtre principale s’ouvre et l’on y trouve les onglets suivants.

La vue « Identité », (remarquez la version !) :

A4A-App6-Identity

La vue « Etat général » en deux bouts :

A4A-App6-GeneralStatus1

A4A-App6-GeneralStatus2

On notera la présence des informations d’état des deux tâches « Fieldbus ».

On trouve ensuite la vue d’état du serveur Modbus TCP qui affiche les compteurs de requêtes, et bien évidemment celui qui bouge est celui de la fonction 3 configurée côté Modbus Poll :

A4A-App6-ModbusTCPServer

La vue « Client Modbus TCP » affiche les informations d’état concernant les deux requêtes configurées pour le serveur secret pour le moment, le second client étant désactivé :

A4A-App6-ModbusTCPClients

Notez que lorsque l’on rajoute des requêtes au niveau de la configuration des clients, la vue d’état est bien sûr adaptée automatiquement.

Puis viennent les deux vues d’état des canaux Hilscher cifX.

L’un est donc PROFIBUS DP Maître :

A4A-App6-ProfibusDPMaster

Et l’autre est EtherCAT Maître :

A4A-App6-EtherCATMaster

Le programme utilisateur à l’œuvre dans les trois tâches est très sensiblement identique :

   procedure Process_IO is

      Elapsed_TON_1 : Ada.Real_Time.Time_Span;

   begin

      if First_Cycle then

         Output_Byte := Pattern_Byte;

         First_Cycle := False;

      end if;

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

      if TON_1_Q then

         case Cmd_Byte is

         when 0 =>
            Output_Byte := ROR (Value => Output_Byte, Amount => 1);

         when 1 =>
            Output_Byte := ROL (Value => Output_Byte, Amount => 1);

         when others => Output_Byte := Pattern_Byte;

         end case;

      end if;

   end Process_IO;

On trouve aussi dans « Ada for Automation » une application exemple 5, « app5 », identique à « app6 » mais qui ne gère elle qu’un seul canal Hilscher cifX.

Mais quel est donc ce serveur Modbus TCP secret dont je vous entretiens depuis le début ?
La NXIO 500-RE ne pourrait-elle faire l’affaire avec une MMC ad hoc ? Sans doute, mais pour des raisons qui m’échappent ce firmware n’existe pas…

Aussi, je me suis dit que je n’avais qu’à utiliser le « kernel 0 », issu de « app1simu », et qui fournit un serveur Modbus TCP.
Oui mais, et les boutons et LEDs ? GtkAda aurait bien sûr pu convenir mais comme je jouais avec Gnoga…

Taa taan ! Voilà un « piano » piloté depuis le navigateur !

A4A-App6-A4A-Piano-Local

Comme c’est du SVG, donc du vectoriel, même depuis un mobile ça se pilote.

Et en plus l’application supporte les connexions multiples ! On peut jouer à plusieurs ! J’adore…
Promis, dès que mon code est un peu plus propre je l’envoie sur le dépôt.

Cordialement,
Stéphane

A4A : Applications et Noyaux

Bonjour,

Le framework « Ada for Automation » est fourni avec un certain nombre d’applications exemples, simple applications consoles ou avec interface graphique en GtkAda, et très bientôt je l’espère avec interface web grâce à Gnoga, un autre framework que je vous avais présenté très brièvement ici, et avec lequel je m’instruis beaucoup tout en m’amusant.

Ainsi par exemple le projet de base A4A est proposé en version console, dont le fichier projet est « a4a.gpr », et en version interface graphique avec « a4a_gui.gpr ».
Cette application est la plus simple possible et joue avec les deux octets d’entrée et sortie à sa disposition, ne mettant en œuvre que des fonctions de rotation et d’affectation.

Ce projet repose sur un noyau, partagé par les deux versions, qui gère le programme utilisateur, un serveur Modbus TCP et des clients Modbus TCP, un pour chaque serveur d’E/S.
La tâche principale collabore avec une tâche périodique annexe via la nouvelle DPM générique dont il a été question précédemment, chacune des tâches disposant d’un programme utilisateur à exécuter à l’état RUN.
Le serveur Modbus TCP comme les clients échangent leurs données avec la tâche principale également via des DPM spécifiques dont le rôle est d’assurer la cohérence des données échangées.

Via le mécanisme d’extension des projets supporté par la suite d’outils fournis par AdaCore, on peut construire des projets héritant des fichiers du projet parent et ajoutant de nouveaux fichiers ou en les substituant s’ils portent le même nom.

C’est ce mécanisme qui est utilisé par exemple avec l’application 1 présentée ici, et encore ici.

Aussi, comme cette application hérite de tout A4A, son dossier source ne contient que ce qui lui est propre, son identification, sa configuration et le programme utilisateur.

Pour cette application 1, ne disposant pas de la partie opérative on a développé une application de simulation, nommée « app1simu ».
Cette application ne nécessitant que la fonction serveur Modbus TCP on a créé un nouveau noyau issu du noyau de A4A auquel on a ôté la gestion des clients Modbus TCP.
Ce noyau logeait dans le dossier de l’application « app1simu » puisqu’il lui était spécifique.

Il en fut de même pour l’application 2 qui met en œuvre une carte Hilscher cifX en lieu et place des clients Modbus TCP.

Et encore de même avec l’application 3 qui remplace les clients Modbus TCP par un maitre Modbus RTU.

Le problème dans cette situation c’est que pour réutiliser un noyau de « app1simu », de « app2 » ou de « app3 », il eu fallut hériter de ces projets ou lister les sources que l’on souhaitait réutiliser, c’est possible, ou pire dupliquer les sources, beurk… Bref, ce n’était pas satisfaisant d’autant que je comptais multiplier les noyaux… On multiplie ce qu’on peut.

J’ai donc réorganisé le framework de sorte que les noyaux se retrouvent dans leurs propres dossiers.
Piloté par une variable externe ou un scénario depuis GPS, le dossier sélectionné est ajouté au projet en cours de traitement.

Ainsi le noyau de « app1simu » est maintenant le « kernel0 », celui de A4A est le « kernel1 », celui de « app3 » est devenu « kernel2″…

C’est beau et ça fonctionne à peu près.
La variable est définie dans un fichier de projet partagé par les autres fichiers de projets, le projet « shared.gpr », et reçoit une valeur initiale par défaut qui est « kernel1 » si elle n’est pas définie par ailleurs.
Attention cependant de laisser GPS terminer ses opérations de mise à jour des références croisées avant de changer de noyau au moyen de la liste déroulante du scénario sous peine de corruption de sa base de données, du moins avec la version Debian.
Ce n’est pas très grave puisqu’il suffit de supprimer celle-ci pour qu’elle soit reconstituée mais c’est un peu pénible.

...
   type Kernel_Type is
      ("kernel0",   --  Modbus TCP Server
       "kernel1",   --  Modbus TCP Server + Modbus TCP IO Scanning
       "kernel2",   --  Modbus TCP Server + Modbus RTU IO Scanning
       "kernel3",   --  Modbus TCP Server + one Hilscher cifX channel
       "kernel4",   --  Modbus TCP Server + Modbus TCP IO Scanning
                    --  + one Hilscher cifX channel
       "kernel5"    --  Modbus TCP Server + Modbus TCP IO Scanning
      );            --  + two Hilscher cifX channels

   Kernel : Kernel_Type := external ("Kernel", "kernel1");
...

Et l’on voit que le noyau de « app2 » est devenu le « kernel3 », que le « kernel4 » fusionne le « kernel1 » et le « kernel3 » et que le « kernel5 » ajoute un canal Hilscher au « kernel4 ».

J’ai bien sûr créé les applications exemples « app5 » qui roule avec le « kernel4 » et « app6 » motorisé par le « kernel5 », le tout en version console ou GUI.

Comme chaque canal Hilscher est susceptible de gérer un bus de terrain différent, classique ou sur Ethernet Temps réel, chaque canal est géré par une tâche indépendante qui exécute son propre programme utilisateur avec une période que l’on peut configurer.
Les tâches « fieldbus » communiquent avec la tâche principale via les DPM génériques déjà évoquées.

Ainsi l’application « app6_gui », mon top model ;-), offre :

  • un serveur Modbus TCP pour y connecter par exemple un SCADA du marché,
  • une fonction IO Scanning avec une tâche client Modbus TCP par serveur d’E/S,
  • deux canaux cifX Hilscher, pour gérer deux cartes, par exemple une PROFIBUS DP Maitre et une EtherCAT Maitre, ou pour gérer une carte à deux canaux comme par exemple un PROFIBUS DP Maitre et un CANopen Maitre,
  • une interface graphique avec GtkAda, permettant de consulter l’état des communications et de l’application et de démarrer ou arrêter les programmes utilisateur,
  • l’intégration du « cifX TCP Server » permettant la configuration et le diagnostic des cartes par SYCON.net via une connexion TCP/IP.

Je vous remercie pour votre attention et vous souhaite une très bonne et heureuse année 2016 pleine de projets, personnels comme professionnels, et de réussite.

N’hésitez pas à nous solliciter.

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