Added 'ethercat graph' command.
This commit is contained in:
parent
f4b6807cc9
commit
9586870ee7
2
NEWS
2
NEWS
|
|
@ -34,6 +34,8 @@ Changes since 1.4.0:
|
||||||
Burgstaller.
|
Burgstaller.
|
||||||
* Clear slave list on link down.
|
* Clear slave list on link down.
|
||||||
* Output device link state in 'ethercat master'.
|
* Output device link state in 'ethercat master'.
|
||||||
|
* Added 'ethercat graph' command which outputs the bus topology in
|
||||||
|
DOT language.
|
||||||
|
|
||||||
Changes in 1.4.0:
|
Changes in 1.4.0:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 <iostream>
|
||||||
|
#include <map>
|
||||||
|
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<ec_ioctl_slave_t> SlaveVector;
|
||||||
|
SlaveVector slaves;
|
||||||
|
ec_ioctl_slave_t slave;
|
||||||
|
SlaveVector::const_iterator si;
|
||||||
|
string font("fontname=\"Helvetica\"");
|
||||||
|
map<int, string> portMedia;
|
||||||
|
map<int, string>::const_iterator mi;
|
||||||
|
map<int, int> mediaWeights;
|
||||||
|
map<int, int>::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
@ -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
|
||||||
|
|
@ -43,6 +43,7 @@ ethercat_SOURCES = \
|
||||||
CommandDownload.cpp \
|
CommandDownload.cpp \
|
||||||
CommandFoeRead.cpp \
|
CommandFoeRead.cpp \
|
||||||
CommandFoeWrite.cpp \
|
CommandFoeWrite.cpp \
|
||||||
|
CommandGraph.cpp \
|
||||||
CommandMaster.cpp \
|
CommandMaster.cpp \
|
||||||
CommandPdos.cpp \
|
CommandPdos.cpp \
|
||||||
CommandReg.cpp \
|
CommandReg.cpp \
|
||||||
|
|
@ -72,6 +73,7 @@ noinst_HEADERS = \
|
||||||
CommandDownload.h \
|
CommandDownload.h \
|
||||||
CommandFoeRead.h \
|
CommandFoeRead.h \
|
||||||
CommandFoeWrite.h \
|
CommandFoeWrite.h \
|
||||||
|
CommandGraph.h \
|
||||||
CommandMaster.h \
|
CommandMaster.h \
|
||||||
CommandPdos.h \
|
CommandPdos.h \
|
||||||
CommandReg.h \
|
CommandReg.h \
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ using namespace std;
|
||||||
#include "CommandDownload.h"
|
#include "CommandDownload.h"
|
||||||
#include "CommandFoeRead.h"
|
#include "CommandFoeRead.h"
|
||||||
#include "CommandFoeWrite.h"
|
#include "CommandFoeWrite.h"
|
||||||
|
#include "CommandGraph.h"
|
||||||
#include "CommandMaster.h"
|
#include "CommandMaster.h"
|
||||||
#include "CommandPdos.h"
|
#include "CommandPdos.h"
|
||||||
#include "CommandRegRead.h"
|
#include "CommandRegRead.h"
|
||||||
|
|
@ -297,6 +298,7 @@ int main(int argc, char **argv)
|
||||||
commandList.push_back(new CommandDownload());
|
commandList.push_back(new CommandDownload());
|
||||||
commandList.push_back(new CommandFoeRead());
|
commandList.push_back(new CommandFoeRead());
|
||||||
commandList.push_back(new CommandFoeWrite());
|
commandList.push_back(new CommandFoeWrite());
|
||||||
|
commandList.push_back(new CommandGraph());
|
||||||
commandList.push_back(new CommandMaster());
|
commandList.push_back(new CommandMaster());
|
||||||
commandList.push_back(new CommandPdos());
|
commandList.push_back(new CommandPdos());
|
||||||
commandList.push_back(new CommandRegRead());
|
commandList.push_back(new CommandRegRead());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue