# HG changeset patch # User Florian Pose # Date 1241010398 0 # Node ID d41e4537b75f29ff58f186944b5aa62ef4ba5af4 # Parent 043a518831b2f60bfa7a11ece043d51c2eb5ea9c Added 'ethercat graph' command. diff -r 043a518831b2 -r d41e4537b75f NEWS --- a/NEWS Wed Apr 29 09:43:04 2009 +0000 +++ b/NEWS Wed Apr 29 13:06:38 2009 +0000 @@ -34,6 +34,8 @@ Burgstaller. * Clear slave list on link down. * Output device link state in 'ethercat master'. +* Added 'ethercat graph' command which outputs the bus topology in + DOT language. Changes in 1.4.0: diff -r 043a518831b2 -r d41e4537b75f tool/CommandGraph.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tool/CommandGraph.cpp Wed Apr 29 13:06:38 2009 +0000 @@ -0,0 +1,162 @@ +/***************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * The IgH EtherCAT Master 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 the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * --- + * + * The license mentioned above concerns the source code only. Using the + * EtherCAT technology and brand is only permitted in compliance with the + * industrial property and similar rights of Beckhoff Automation GmbH. + * + ****************************************************************************/ + +#include +#include +using namespace std; + +#include "CommandGraph.h" + +/*****************************************************************************/ + +CommandGraph::CommandGraph(): + Command("graph", "Output the bus topology as a graph.") +{ +} + +/*****************************************************************************/ + +string CommandGraph::helpString() const +{ + stringstream str; + + str << getName() << " [OPTIONS]" << endl + << endl + << getBriefDescription() << endl + << endl + << "The bus is output in DOT language (see" << endl + << "http://www.graphviz.org/doc/info/lang.html), which can" << endl + << "be processed with the tools from the Graphviz" << endl + << "package. Example:" << endl + << endl + << " ethercat graph | dot -Tsvg > bus.svg" << endl + << endl + << "See 'man dot' for more information." << endl; + + return str.str(); +} + +/****************************************************************************/ + +void CommandGraph::execute(MasterDevice &m, const StringVector &args) +{ + ec_ioctl_master_t master; + unsigned int i; + typedef vector SlaveVector; + SlaveVector slaves; + ec_ioctl_slave_t slave; + SlaveVector::const_iterator si; + string font("fontname=\"Helvetica\""); + map portMedia; + map::const_iterator mi; + map mediaWeights; + map::const_iterator wi; + + portMedia[EC_PORT_MII] = "MII"; + mediaWeights[EC_PORT_MII] = 1; + + portMedia[EC_PORT_EBUS] = "EBUS"; + mediaWeights[EC_PORT_EBUS] = 5; + + if (args.size()) { + stringstream err; + err << "'" << getName() << "' takes no arguments!"; + throwInvalidUsageException(err); + } + + m.open(MasterDevice::Read); + m.getMaster(&master); + + for (i = 0; i < master.slave_count; i++) { + m.getSlave(&slave, i); + slaves.push_back(slave); + } + + cout << "/* EtherCAT bus graph. Generated by 'ethercat graph'. */" << endl + << endl + << "strict graph bus {" << endl + << " rankdir=\"LR\"" << endl + << endl + << " master [" << font << ",label=\"EtherCAT\\nMaster\"]" << endl; + + if (slaves.size()) { + cout << " master -- slave0 [" << font; + + mi = portMedia.find(slaves.front().port_descs[0]); + if (mi != portMedia.end()) + cout << ",label=\"" << mi->second << "\""; + + cout << "]" << endl; + } + cout << endl; + + for (si = slaves.begin(); si != slaves.end(); si++) { + cout << " slave" << si->position << " [" << font << + ",shape=\"box\",label=\"" << si->position; + if (string(si->order).size()) + cout << "\\n" << si->order; + cout << "\"]" << endl; + + for (i = 1; i < EC_MAX_PORTS; i++) { + if (si->next_slave[i] == 0xffff) + continue; + + cout << " slave" << si->position << " -- " + << "slave" << si->next_slave[i] << " [" << font << "," + << "taillabel=\"" << i << "\""; + + mi = portMedia.find(si->port_descs[i]); + if (mi == portMedia.end()) { + /* Try medium of next-hop slave. */ + unsigned int pos = si->next_slave[i]; + if (pos < slaves.size()) { + ec_ioctl_slave_t *next = &slaves[pos]; + mi = portMedia.find(next->port_descs[0]); + } else { + cerr << "Invalid next slave pointer." << endl; + } + } + + if (mi != portMedia.end()) + cout << ",label=\"" << mi->second << "\""; + + wi = mediaWeights.find(si->port_descs[i]); + if (wi != mediaWeights.end()) + cout << ",weight=\"" << wi->second << "\""; + + cout << "]" << endl; + } + + cout << endl; + } + + cout << "}" << endl; +} + +/*****************************************************************************/ diff -r 043a518831b2 -r d41e4537b75f tool/CommandGraph.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tool/CommandGraph.h Wed Apr 29 13:06:38 2009 +0000 @@ -0,0 +1,49 @@ +/***************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * The IgH EtherCAT Master 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 the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * --- + * + * The license mentioned above concerns the source code only. Using the + * EtherCAT technology and brand is only permitted in compliance with the + * industrial property and similar rights of Beckhoff Automation GmbH. + * + ****************************************************************************/ + +#ifndef __COMMANDGRAPH_H__ +#define __COMMANDGRAPH_H__ + +#include "Command.h" + +/****************************************************************************/ + +class CommandGraph: + public Command +{ + public: + CommandGraph(); + + string helpString() const; + void execute(MasterDevice &, const StringVector &); +}; + +/****************************************************************************/ + +#endif diff -r 043a518831b2 -r d41e4537b75f tool/Makefile.am --- a/tool/Makefile.am Wed Apr 29 09:43:04 2009 +0000 +++ b/tool/Makefile.am Wed Apr 29 13:06:38 2009 +0000 @@ -43,6 +43,7 @@ CommandDownload.cpp \ CommandFoeRead.cpp \ CommandFoeWrite.cpp \ + CommandGraph.cpp \ CommandMaster.cpp \ CommandPdos.cpp \ CommandReg.cpp \ @@ -72,6 +73,7 @@ CommandDownload.h \ CommandFoeRead.h \ CommandFoeWrite.h \ + CommandGraph.h \ CommandMaster.h \ CommandPdos.h \ CommandReg.h \ diff -r 043a518831b2 -r d41e4537b75f tool/main.cpp --- a/tool/main.cpp Wed Apr 29 09:43:04 2009 +0000 +++ b/tool/main.cpp Wed Apr 29 13:06:38 2009 +0000 @@ -43,6 +43,7 @@ #include "CommandDownload.h" #include "CommandFoeRead.h" #include "CommandFoeWrite.h" +#include "CommandGraph.h" #include "CommandMaster.h" #include "CommandPdos.h" #include "CommandRegRead.h" @@ -297,6 +298,7 @@ commandList.push_back(new CommandDownload()); commandList.push_back(new CommandFoeRead()); commandList.push_back(new CommandFoeWrite()); + commandList.push_back(new CommandGraph()); commandList.push_back(new CommandMaster()); commandList.push_back(new CommandPdos()); commandList.push_back(new CommandRegRead());