URL
https://opencores.org/ocsvn/w11/w11/trunk
Subversion Repositories w11
Compare Revisions
- This comparison shows the changes necessary to convert path
/w11/tags/w11a_V0.61/tools/src/librlinktpp
- from Rev 25 to Rev 26
- ↔ Reverse comparison
Rev 25 → Rev 26
/RtclRlinkConnect.cpp
0,0 → 1,815
// $Id: RtclRlinkConnect.cpp 576 2014-08-02 12:24:28Z mueller $ |
// |
// Copyright 2011-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> |
// |
// This program is free software; you may redistribute and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation, either version 2, or at your option any later version. |
// |
// This program 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 complete details. |
// |
// Revision History: |
// Date Rev Version Comment |
// 2014-08-02 576 1.1.7 bugfix: redo estatdef logic; avoid LastExpect() |
// 2013-02-23 492 1.1.6 use RlogFile.Name(); use Context().ErrorCount() |
// 2013-02-22 491 1.1.5 use new RlogFile/RlogMsg interfaces |
// 2013-02-02 480 1.1.4 allow empty exec commands |
// 2013-01-27 478 1.1.3 use RtclRlinkPort::DoRawio on M_rawio |
// 2013-01-06 473 1.1.2 add M_rawio: rawio -write|-read |
// 2011-11-28 434 1.1.1 ConfigBase(): use uint32_t for lp64 compatibility |
// 2011-04-23 380 1.1 use boost/bind instead of RmethDsc |
// 2011-04-17 376 1.0.1 M_wtlam: now correct log levels |
// 2011-03-27 374 1.0 Initial version |
// 2011-02-11 360 0.1 First draft |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclRlinkConnect.cpp 576 2014-08-02 12:24:28Z mueller $ |
\brief Implemenation of class RtclRlinkConnect. |
*/ |
|
#include <ctype.h> |
|
#include <iostream> |
|
#include "boost/bind.hpp" |
|
#include "librtcltools/Rtcl.hpp" |
#include "librtcltools/RtclOPtr.hpp" |
#include "librtcltools/RtclNameSet.hpp" |
#include "librtcltools/RtclStats.hpp" |
#include "librtools/RosPrintf.hpp" |
#include "librtools/RlogMsg.hpp" |
#include "librlink/RlinkCommandList.hpp" |
#include "RtclRlinkPort.hpp" |
|
#include "RtclRlinkConnect.hpp" |
|
using namespace std; |
|
/*! |
\class Retro::RtclRlinkConnect |
\brief FIXME_docs |
*/ |
|
// all method definitions in namespace Retro |
namespace Retro { |
|
//------------------------------------------+----------------------------------- |
//! Default constructor |
|
RtclRlinkConnect::RtclRlinkConnect(Tcl_Interp* interp, const char* name) |
: RtclProxyOwned<RlinkConnect>("RlinkConnect", interp, name, |
new RlinkConnect()) |
{ |
AddMeth("open", boost::bind(&RtclRlinkConnect::M_open, this, _1)); |
AddMeth("close", boost::bind(&RtclRlinkConnect::M_close, this, _1)); |
AddMeth("exec", boost::bind(&RtclRlinkConnect::M_exec, this, _1)); |
AddMeth("amap", boost::bind(&RtclRlinkConnect::M_amap, this, _1)); |
AddMeth("errcnt", boost::bind(&RtclRlinkConnect::M_errcnt, this, _1)); |
AddMeth("wtlam", boost::bind(&RtclRlinkConnect::M_wtlam, this, _1)); |
AddMeth("oob", boost::bind(&RtclRlinkConnect::M_oob, this, _1)); |
AddMeth("rawio", boost::bind(&RtclRlinkConnect::M_rawio, this, _1)); |
AddMeth("stats", boost::bind(&RtclRlinkConnect::M_stats, this, _1)); |
AddMeth("log", boost::bind(&RtclRlinkConnect::M_log, this, _1)); |
AddMeth("print", boost::bind(&RtclRlinkConnect::M_print, this, _1)); |
AddMeth("dump", boost::bind(&RtclRlinkConnect::M_dump, this, _1)); |
AddMeth("config", boost::bind(&RtclRlinkConnect::M_config, this, _1)); |
AddMeth("$default", boost::bind(&RtclRlinkConnect::M_default, this, _1)); |
|
for (size_t i=0; i<8; i++) { |
fCmdnameObj[i] = Tcl_NewStringObj(RlinkCommand::CommandName(i), -1); |
} |
} |
|
//------------------------------------------+----------------------------------- |
//! Destructor |
|
RtclRlinkConnect::~RtclRlinkConnect() |
{} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_open(RtclArgs& args) |
{ |
string path; |
|
if (!args.GetArg("?path", path)) return kERR; |
if (!args.AllDone()) return kERR; |
|
RerrMsg emsg; |
if (args.NOptMiss() == 0) { // open path |
if (!Obj().Open(path, emsg)) return args.Quit(emsg); |
} else { // open |
string name = Obj().IsOpen() ? Obj().Port()->Url().Url() : string(); |
args.SetResult(name); |
} |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_close(RtclArgs& args) |
{ |
if (!args.AllDone()) return kERR; |
if (!Obj().IsOpen()) return args.Quit("-E: port not open"); |
Obj().Close(); |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_exec(RtclArgs& args) |
{ |
static RtclNameSet optset("-rreg|-rblk|-wreg|-wblk|-stat|-attn|-init|" |
"-edata|-estat|-estatdef|" |
"-volatile|-print|-dump|-rlist"); |
|
Tcl_Interp* interp = args.Interp(); |
|
RlinkCommandList clist; |
string opt; |
uint16_t addr; |
|
vector<string> vardata; |
vector<string> varstat; |
string varprint; |
string vardump; |
string varlist; |
|
uint8_t estatdef_val = 0x00; |
uint8_t estatdef_msk = 0xff; |
|
while (args.NextOpt(opt, optset)) { |
|
size_t lsize = clist.Size(); |
if (opt == "-rreg") { // -rreg addr ?varData ?varStat --- |
if (!GetAddr(args, Obj(), addr)) return kERR; |
if (!GetVarName(args, "??varData", lsize, vardata)) return kERR; |
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR; |
clist.AddRreg(addr); |
|
} else if (opt == "-rblk") { // -rblk addr size ?varData ?varStat |
int32_t bsize; |
if (!GetAddr(args, Obj(), addr)) return kERR; |
if (!args.GetArg("bsize", bsize, 1, 256)) return kERR; |
if (!GetVarName(args, "??varData", lsize, vardata)) return kERR; |
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR; |
clist.AddRblk(addr, (size_t) bsize); |
|
} else if (opt == "-wreg") { // -wreg addr data ?varStat ------- |
uint16_t data; |
if (!GetAddr(args, Obj(), addr)) return kERR; |
if (!args.GetArg("data", data)) return kERR; |
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR; |
clist.AddWreg(addr, data); |
|
} else if (opt == "-wblk") { // -wblk addr block ?varStat ------ |
vector<uint16_t> block; |
if (!GetAddr(args, Obj(), addr)) return kERR; |
if (!args.GetArg("data", block, 1, 256)) return kERR; |
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR; |
clist.AddWblk(addr, block); |
|
} else if (opt == "-stat") { // -stat varData ?varStat --------- |
if (!GetVarName(args, "??varData", lsize, vardata)) return kERR; |
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR; |
clist.AddStat(); |
|
} else if (opt == "-attn") { // -attn varData ?varStat --------- |
if (!GetVarName(args, "??varData", lsize, vardata)) return kERR; |
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR; |
clist.AddAttn(); |
|
} else if (opt == "-init") { // -init addr data ?varStat ------- |
uint16_t data; |
if (!GetAddr(args, Obj(), addr)) return kERR; |
if (!args.GetArg("data", data)) return kERR; |
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR; |
clist.AddInit(addr, data); |
|
} else if (opt == "-edata") { // -edata data ?mask -------------- |
if (!ClistNonEmpty(args, clist)) return kERR; |
if (clist[lsize-1].Expect()==0) { |
clist[lsize-1].SetExpect(new RlinkCommandExpect(estatdef_val, |
estatdef_msk)); |
} |
if (clist[lsize-1].Command() == RlinkCommand::kCmdRblk) { |
vector<uint16_t> data; |
vector<uint16_t> mask; |
size_t bsize = clist[lsize-1].BlockSize(); |
if (!args.GetArg("data", data, 0, bsize)) return kERR; |
if (!args.GetArg("??mask", mask, 0, bsize)) return kERR; |
clist[lsize-1].Expect()->SetBlock(data, mask); |
} else { |
uint16_t data=0; |
uint16_t mask=0; |
if (!args.GetArg("data", data)) return kERR; |
if (!args.GetArg("??mask", mask)) return kERR; |
clist[lsize-1].Expect()->SetData(data, mask); |
} |
|
} else if (opt == "-estat") { // -estat ?stat ?mask ------------- |
if (!ClistNonEmpty(args, clist)) return kERR; |
uint8_t stat=0; |
uint8_t mask=0; |
if (!args.GetArg("??stat", stat)) return kERR; |
if (!args.GetArg("??mask", mask)) return kERR; |
if (args.NOptMiss() == 2) mask = 0xff; |
if (clist[lsize-1].Expect()==0) { |
clist[lsize-1].SetExpect(new RlinkCommandExpect()); |
} |
clist[lsize-1].Expect()->SetStatus(stat, mask); |
|
} else if (opt == "-estatdef") { // -estatdef ?stat ?mask ----------- |
uint8_t stat=0; |
uint8_t mask=0; |
if (!args.GetArg("??stat", stat)) return kERR; |
if (!args.GetArg("??mask", mask)) return kERR; |
if (args.NOptMiss() == 2) mask = 0xff; |
estatdef_val = stat; |
estatdef_msk = mask; |
|
} else if (opt == "-volatile") { // -volatile ---------------------- |
if (!ClistNonEmpty(args, clist)) return kERR; |
clist.LastVolatile(); |
|
} else if (opt == "-print") { // -print ?varRes ----------------- |
varprint = "-"; |
if (!args.GetArg("??varRes", varprint)) return kERR; |
} else if (opt == "-dump") { // -dump ?varRes ------------------ |
vardump = "-"; |
if (!args.GetArg("??varRes", vardump)) return kERR; |
} else if (opt == "-rlist") { // -rlist ?varRes ----------------- |
varlist = "-"; |
if (!args.GetArg("??varRes", varlist)) return kERR; |
} |
|
if (estatdef_msk != 0xff && // estatdef defined |
lsize != clist.Size()) { // and cmd added to clist |
for (size_t i=lsize; i<clist.Size(); i++) { // loop over new cmds |
if (clist[i].Expect()==0) { // if no stat |
clist[i].SetExpect(new RlinkCommandExpect(estatdef_val, |
estatdef_msk)); |
} |
} |
} |
|
} |
|
int nact = 0; |
if (varprint == "-") nact += 1; |
if (vardump == "-") nact += 1; |
if (varlist == "-") nact += 1; |
if (nact > 1) |
return args.Quit( |
"-E: more that one of -print,-dump,-list without target variable found"); |
|
if (!args.AllDone()) return kERR; |
if (clist.Size() == 0) return kOK; |
|
RerrMsg emsg; |
|
if (!Obj().Exec(clist, emsg)) return args.Quit(emsg); |
|
for (size_t icmd=0; icmd<clist.Size(); icmd++) { |
RlinkCommand& cmd = clist[icmd]; |
|
if (icmd<vardata.size() && !vardata[icmd].empty()) { |
RtclOPtr pres; |
vector<uint16_t> retstat; |
RtclOPtr pele; |
switch (cmd.Command()) { |
case RlinkCommand::kCmdRreg: |
case RlinkCommand::kCmdAttn: |
pres = Tcl_NewIntObj((int)cmd.Data()); |
break; |
|
case RlinkCommand::kCmdRblk: |
pres = Rtcl::NewListIntObj(cmd.Block()); |
break; |
|
case RlinkCommand::kCmdStat: |
retstat.resize(2); |
retstat[0] = cmd.StatRequest(); |
retstat[1] = cmd.Data(); |
pres = Rtcl::NewListIntObj(retstat); |
break; |
} |
if(!Rtcl::SetVar(interp, vardata[icmd], pres)) return kERR; |
} |
|
if (icmd<varstat.size() && !varstat[icmd].empty()) { |
RtclOPtr pres(Tcl_NewIntObj((int)cmd.Status())); |
if (!Rtcl::SetVar(interp, varstat[icmd], pres)) return kERR; |
} |
} |
|
if (!varprint.empty()) { |
ostringstream sos; |
const RlinkConnect::LogOpts& logopts = Obj().GetLogOpts(); |
clist.Print(sos, Obj().Context(), &Obj().AddrMap(), logopts.baseaddr, |
logopts.basedata, logopts.basestat); |
RtclOPtr pobj(Rtcl::NewLinesObj(sos)); |
if (!Rtcl::SetVarOrResult(args.Interp(), varprint, pobj)) return kERR; |
} |
|
if (!vardump.empty()) { |
ostringstream sos; |
clist.Dump(sos, 0); |
RtclOPtr pobj(Rtcl::NewLinesObj(sos)); |
if (!Rtcl::SetVarOrResult(args.Interp(), vardump, pobj)) return kERR; |
} |
|
if (!varlist.empty()) { |
RtclOPtr prlist(Tcl_NewListObj(0, NULL)); |
for (size_t icmd=0; icmd<clist.Size(); icmd++) { |
RlinkCommand& cmd(clist[icmd]); |
|
RtclOPtr pres(Tcl_NewListObj(0, NULL)); |
Tcl_ListObjAppendElement(NULL, pres, fCmdnameObj[cmd.Command()]); |
Tcl_ListObjAppendElement(NULL, pres, Tcl_NewIntObj((int)cmd.Request())); |
Tcl_ListObjAppendElement(NULL, pres, Tcl_NewIntObj((int)cmd.Flags())); |
Tcl_ListObjAppendElement(NULL, pres, Tcl_NewIntObj((int)cmd.Status())); |
|
switch (cmd.Command()) { |
case RlinkCommand::kCmdRreg: |
case RlinkCommand::kCmdAttn: |
Tcl_ListObjAppendElement(NULL, pres, Tcl_NewIntObj((int)cmd.Data())); |
break; |
|
case RlinkCommand::kCmdRblk: |
Tcl_ListObjAppendElement(NULL, pres, |
Rtcl::NewListIntObj(cmd.Block())); |
break; |
|
case RlinkCommand::kCmdStat: |
Tcl_ListObjAppendElement(NULL, pres, |
Tcl_NewIntObj((int)cmd.StatRequest())); |
Tcl_ListObjAppendElement(NULL, pres, Tcl_NewIntObj((int)cmd.Data())); |
break; |
} |
Tcl_ListObjAppendElement(NULL, prlist, pres); |
} |
if (!Rtcl::SetVarOrResult(args.Interp(), varlist, prlist)) return kERR; |
} |
|
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_amap(RtclArgs& args) |
{ |
static RtclNameSet optset("-name|-testname|-testaddr|-insert|-erase|" |
"-clear|-print"); |
|
const RlinkAddrMap& addrmap = Obj().AddrMap(); |
|
string opt; |
string name; |
uint16_t addr=0; |
|
if (args.NextOpt(opt, optset)) { |
if (opt == "-name") { // amap -name addr |
if (!args.GetArg("addr", addr, 0x00ff)) return kERR; |
if (!args.AllDone()) return kERR; |
string tstname; |
if(addrmap.Find(addr, tstname)) { |
args.SetResult(tstname); |
} else { |
return args.Quit(string("-E: address '") + args.PeekArgString(-1) + |
"' not mapped"); |
} |
|
} else if (opt == "-testname") { // amap -testname name |
if (!args.GetArg("name", name)) return kERR; |
if (!args.AllDone()) return kERR; |
uint16_t tstaddr; |
args.SetResult(int(addrmap.Find(name, tstaddr))); |
|
} else if (opt == "-testaddr") { // amap -testaddr addr |
if (!args.GetArg("addr", addr, 0x00ff)) return kERR; |
if (!args.AllDone()) return kERR; |
string tstname; |
args.SetResult(int(addrmap.Find(addr, tstname))); |
|
} else if (opt == "-insert") { // amap -insert name addr |
uint16_t tstaddr; |
string tstname; |
int tstint; |
if (!args.GetArg("name", name)) return kERR; |
// enforce that the name is not a valid representation of an int |
if (Tcl_GetIntFromObj(NULL, args[args.NDone()-1], &tstint) == kOK) |
return args.Quit(string("-E: name should not look like an int but '")+ |
name + "' does"); |
if (!args.GetArg("addr", addr, 0x00ff)) return kERR; |
if (!args.AllDone()) return kERR; |
if (addrmap.Find(name, tstaddr)) |
return args.Quit(string("-E: mapping already defined for '")+name+"'"); |
if (addrmap.Find(addr, tstname)) |
return args.Quit(string("-E: mapping already defined for address '") + |
args.PeekArgString(-1) + "'"); |
Obj().AddrMapInsert(name, addr); |
|
} else if (opt == "-erase") { // amap -erase name |
if (!args.GetArg("name", name)) return kERR; |
if (!args.AllDone()) return kERR; |
if (!Obj().AddrMapErase(name)) |
return args.Quit(string("-E: no mapping defined for '") + name + "'"); |
|
} else if (opt == "-clear") { // amap -clear |
if (!args.AllDone()) return kERR; |
Obj().AddrMapClear(); |
|
} else if (opt == "-print") { // amap -print |
if (!args.AllDone()) return kERR; |
ostringstream sos; |
addrmap.Print(sos); |
args.AppendResultLines(sos); |
} |
|
} else { |
if (!args.OptValid()) return kERR; |
if (!args.GetArg("?name", name)) return kERR; |
if (args.NOptMiss()==0) { // amap name |
uint16_t tstaddr; |
if(addrmap.Find(name, tstaddr)) { |
args.SetResult(int(tstaddr)); |
} else { |
return args.Quit(string("-E: no mapping defined for '") + name + "'"); |
} |
|
} else { // amap |
RtclOPtr plist(Tcl_NewListObj(0, NULL)); |
const RlinkAddrMap::amap_t amap = addrmap.Amap(); |
for (RlinkAddrMap::amap_cit_t it=amap.begin(); it!=amap.end(); it++) { |
Tcl_Obj* tpair[2]; |
tpair[0] = Tcl_NewIntObj(it->first); |
tpair[1] = Tcl_NewStringObj((it->second).c_str(),(it->second).length()); |
Tcl_ListObjAppendElement(NULL, plist, Tcl_NewListObj(2, tpair)); |
} |
args.SetResult(plist); |
} |
} |
|
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_errcnt(RtclArgs& args) |
{ |
static RtclNameSet optset("-clear"); |
string opt; |
bool fclear = false; |
|
while (args.NextOpt(opt, optset)) { |
if (opt == "-clear") fclear = true; |
} |
if (!args.AllDone()) return kERR; |
|
args.SetResult(int(Obj().Context().ErrorCount())); |
if (fclear) Obj().Context().ClearErrorCount(); |
|
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_wtlam(RtclArgs& args) |
{ |
double tout; |
if (!args.GetArg("tout", tout, 0.001)) return kERR; |
if (!args.AllDone()) return kERR; |
|
RerrMsg emsg; |
double twait = Obj().WaitAttn(tout, emsg); |
|
if (twait == -2.) { |
return args.Quit(emsg); |
} else if (twait == -1.) { |
if (Obj().GetLogOpts().printlevel >= 1) { |
RlogMsg lmsg(Obj().LogFile()); |
lmsg << "-- wtlam to=" << RosPrintf(tout, "f", 0,3) |
<< " FAIL timeout" << endl; |
Obj().Context().IncErrorCount(); |
args.SetResult(tout); |
return kOK; |
} |
} |
|
if (Obj().GetLogOpts().printlevel >= 3) { |
RlogMsg lmsg(Obj().LogFile()); |
lmsg << "-- wtlam to=" << RosPrintf(tout, "f", 0,3) |
<< " T=" << RosPrintf(twait, "f", 0,3) |
<< " OK" << endl; |
} |
|
args.SetResult(twait); |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_oob(RtclArgs& args) |
{ |
static RtclNameSet optset("-rlmon|-rbmon|-sbcntl|-sbdata"); |
|
string opt; |
uint16_t addr; |
uint16_t data; |
RerrMsg emsg; |
|
if (args.NextOpt(opt, optset)) { |
if (opt == "-rlmon") { // oob -rlmon (0|1) |
if (!args.GetArg("val", data, 1)) return kERR; |
if (!args.AllDone()) return kERR; |
addr = 15; // rlmon on bit 15 |
if (!Obj().SndOob(0x00, (addr<<8)+data, emsg)) return args.Quit(emsg); |
|
} else if (opt == "-rbmon") { // oob -rbmon (0|1) |
if (!args.GetArg("val", data, 1)) return kERR; |
if (!args.AllDone()) return kERR; |
addr = 14; // rbmon on bit 14 |
if (!Obj().SndOob(0x00, (addr<<8)+data, emsg)) return args.Quit(emsg); |
|
} else if (opt == "-sbcntl") { // oob -sbcntl bit (0|1) |
if (!args.GetArg("bit", addr, 15)) return kERR; |
if (!args.GetArg("val", data, 1)) return kERR; |
if (!args.AllDone()) return kERR; |
if (!Obj().SndOob(0x00, (addr<<8)+data, emsg)) return args.Quit(emsg); |
|
} else if (opt == "-sbdata") { // oob -sbdata addr val |
if (!args.GetArg("bit", addr, 0x0ff)) return kERR; |
if (!args.GetArg("val", data)) return kERR; |
if (!args.AllDone()) return kERR; |
if (!Obj().SndOob(addr, data, emsg)) return args.Quit(emsg); |
} |
} else { |
return args.Quit( |
"-E: missing option, one of -rlmon,-rbmon,-sbcntl,-sbdata"); |
} |
|
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_rawio(RtclArgs& args) |
{ |
size_t errcnt = 0; |
int rc = RtclRlinkPort::DoRawio(args, Obj().Port(), errcnt); |
Obj().Context().IncErrorCount(errcnt); |
return rc; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_stats(RtclArgs& args) |
{ |
RtclStats::Context cntx; |
if (!RtclStats::GetArgs(args, cntx)) return kERR; |
if (!RtclStats::Collect(args, cntx, Obj().Stats())) return kERR; |
if (Obj().Port()) { |
if (!RtclStats::Collect(args, cntx, Obj().Port()->Stats())) return kERR; |
} |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_log(RtclArgs& args) |
{ |
string msg; |
if (!args.GetArg("msg", msg)) return kERR; |
if (!args.AllDone()) return kERR; |
if (Obj().GetLogOpts().printlevel != 0 || |
Obj().GetLogOpts().dumplevel != 0 || |
Obj().GetLogOpts().tracelevel != 0) { |
Obj().LogFile().Write(string("# ") + msg); |
} |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_print(RtclArgs& args) |
{ |
if (!args.AllDone()) return kERR; |
|
ostringstream sos; |
Obj().Print(sos); |
args.SetResult(sos); |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_dump(RtclArgs& args) |
{ |
if (!args.AllDone()) return kERR; |
|
ostringstream sos; |
Obj().Dump(sos, 0); |
args.SetResult(sos); |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_config(RtclArgs& args) |
{ |
static RtclNameSet optset("-baseaddr|-basedata|-basestat|" |
"-logfile|-logprintlevel|-logdumplevel|" |
"-logtracelevel"); |
|
RlinkConnect::LogOpts logopts = Obj().GetLogOpts(); |
|
if (args.NDone() == (size_t)args.Objc()) { |
ostringstream sos; |
sos << "-baseaddr " << RosPrintf(logopts.baseaddr, "d") |
<< " -basedata " << RosPrintf(logopts.basedata, "d") |
<< " -basestat " << RosPrintf(logopts.basestat, "d") |
<< " -logfile {" << Obj().LogFile().Name() << "}" |
<< " -logprintlevel " << RosPrintf(logopts.printlevel, "d") |
<< " -logdumplevel " << RosPrintf(logopts.dumplevel, "d") |
<< " -logtracelevel " << RosPrintf(logopts.tracelevel, "d"); |
args.AppendResult(sos); |
return kOK; |
} |
|
string opt; |
while (args.NextOpt(opt, optset)) { |
if (opt == "-baseaddr") { // -baseaddr ?base ----------------- |
if (!ConfigBase(args, logopts.baseaddr)) return kERR; |
if (args.NOptMiss() == 0) Obj().SetLogOpts(logopts); |
|
} else if (opt == "-basedata") { // -basedata ?base ----------------- |
if (!ConfigBase(args, logopts.basedata)) return kERR; |
if (args.NOptMiss() == 0) Obj().SetLogOpts(logopts); |
|
} else if (opt == "-basestat") { // -basestat ?base ----------------- |
if (!ConfigBase(args, logopts.basestat)) return kERR; |
if (args.NOptMiss() == 0) Obj().SetLogOpts(logopts); |
|
} else if (opt == "-logfile") { // -logfile ?name ------------------ |
string name; |
if (!args.Config("??name", name)) return false; |
if (args.NOptMiss() == 0) { // new filename ? |
if (name == "-" || name == "<cout>") { |
Obj().LogUseStream(&cout, "<cout>"); |
} else { |
if (!Obj().LogOpen(name)) { |
Obj().LogUseStream(&cout, "<cout>"); |
return args.Quit(string("-E: open failed for '") + name + |
"', using stdout"); |
} |
} |
} |
|
} else if (opt == "-logprintlevel") { // -logprintlevel ?loglevel -------- |
if (!args.Config("??loglevel", logopts.printlevel, 3)) return false; |
if (args.NOptMiss() == 0) Obj().SetLogOpts(logopts); |
|
} else if (opt == "-logdumplevel") { // -logdumplevel ?loglevel --------- |
if (!args.Config("??loglevel", logopts.dumplevel, 3)) return false; |
if (args.NOptMiss() == 0) Obj().SetLogOpts(logopts); |
|
} else if (opt == "-logtracelevel") { // -logtracelevel ?loglevel -------- |
if (!args.Config("??loglevel", logopts.tracelevel, 3)) return false; |
if (args.NOptMiss() == 0) Obj().SetLogOpts(logopts); |
} |
} |
|
if (!args.AllDone()) return kERR; |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkConnect::M_default(RtclArgs& args) |
{ |
if (!args.AllDone()) return kERR; |
ostringstream sos; |
const RlinkConnect::LogOpts& logopts = Obj().GetLogOpts(); |
|
sos << "print base: " << "addr " << RosPrintf(logopts.baseaddr, "d", 2) |
<< " data " << RosPrintf(logopts.basedata, "d", 2) |
<< " stat " << RosPrintf(logopts.basestat, "d", 2) << endl; |
sos << "logfile: " << Obj().LogFile().Name() |
<< " printlevel " << logopts.printlevel |
<< " dumplevel " << logopts.dumplevel; |
|
args.AppendResultLines(sos); |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
bool RtclRlinkConnect::GetAddr(RtclArgs& args, RlinkConnect& conn, |
uint16_t& addr) |
{ |
Tcl_Obj* pobj=0; |
if (!args.GetArg("addr", pobj)) return kERR; |
|
int tstint; |
// if a number is given.. |
if (Tcl_GetIntFromObj(NULL, pobj, &tstint) == kOK) { |
if (tstint >= 0 && tstint <= 0x00ff) { |
addr = (uint16_t)tstint; |
} else { |
args.AppendResult("-E: value '", Tcl_GetString(pobj), |
"' for 'addr' out of range 0...0x00ff", NULL); |
return false; |
} |
// if a name is given |
} else { |
string name(Tcl_GetString(pobj)); |
uint16_t tstaddr; |
if (Obj().AddrMap().Find(name, tstaddr)) { |
addr = tstaddr; |
} else { |
args.AppendResult("-E: no address mapping known for '", |
Tcl_GetString(pobj), "'", NULL); |
return false; |
} |
} |
|
return true; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
bool RtclRlinkConnect::GetVarName(RtclArgs& args, const char* argname, |
size_t nind, |
std::vector<std::string>& varname) |
{ |
while (varname.size() < nind+1) varname.push_back(string()); |
string name; |
if (!args.GetArg(argname, name)) return false; |
if (name.length()) { // if variable defined |
char c = name[0]; |
if (isdigit(c) || c=='+' || c=='-' ) { // check for mistaken number |
args.AppendResult("-E: invalid variable name '", name.c_str(), |
"': looks like a number", NULL); |
return false; |
} |
} |
|
varname[nind] = name; |
return true; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
bool RtclRlinkConnect::ConfigBase(RtclArgs& args, uint32_t& base) |
{ |
uint32_t tmp = base; |
if (!args.Config("??base", tmp, 16, 2)) return false; |
if (tmp != base && tmp != 2 && tmp !=8 && tmp != 16) { |
args.AppendResult("-E: base must be 2, 8, or 16, found '", |
args.PeekArgString(-1), "'", NULL); |
return false; |
} |
base = tmp; |
return true; |
} |
|
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
bool RtclRlinkConnect::ClistNonEmpty(RtclArgs& args, |
const RlinkCommandList& clist) |
{ |
if (clist.Size() == 0) { |
args.AppendResult("-E: -edata, -estat, or -volatile " |
"not allowed on empty command list", NULL); |
return false; |
} |
return true; |
} |
|
} // end namespace Retro |
/RtclAttnShuttle.cpp
0,0 → 1,161
// $Id: RtclAttnShuttle.cpp 521 2013-05-20 22:16:45Z mueller $ |
// |
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> |
// |
// This program is free software; you may redistribute and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation, either version 2, or at your option any later version. |
// |
// This program 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 complete details. |
// |
// Revision History: |
// Date Rev Version Comment |
// 2013-05-20 521 1.0.1 Setup proper Tcl channel options |
// 2013-03-01 493 1.0 Initial version |
// 2013-01-12 475 0.5 First draft |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclAttnShuttle.cpp 521 2013-05-20 22:16:45Z mueller $ |
\brief Implemenation of class RtclAttnShuttle. |
*/ |
|
#include <errno.h> |
|
#include "boost/bind.hpp" |
|
#include "librtools/Rexception.hpp" |
|
#include "RtclAttnShuttle.hpp" |
|
using namespace std; |
|
/*! |
\class Retro::RtclAttnShuttle |
\brief FIXME_docs |
*/ |
|
// all method definitions in namespace Retro |
namespace Retro { |
|
//------------------------------------------+----------------------------------- |
//! constructor |
|
RtclAttnShuttle::RtclAttnShuttle(uint16_t mask, Tcl_Obj* pobj) |
: fpServ(0), |
fpInterp(0), |
fFdPipeRead(-1), |
fFdPipeWrite(-1), |
fShuttleChn(0), |
fMask(mask), |
fpScript(pobj) |
{ |
int pipefd[2]; |
int irc = ::pipe(pipefd); |
if (irc < 0) |
throw Rexception("RtclAttnShuttle::<ctor>", "pipe() failed: ", errno); |
fFdPipeRead = pipefd[0]; |
fFdPipeWrite = pipefd[1]; |
} |
|
//------------------------------------------+----------------------------------- |
//! Destructor |
|
RtclAttnShuttle::~RtclAttnShuttle() |
{ |
Remove(); |
::close(fFdPipeWrite); |
::close(fFdPipeRead); |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
void RtclAttnShuttle::Add(RlinkServer* pserv, Tcl_Interp* interp) |
{ |
// connect to RlinkServer |
pserv->AddAttnHandler(boost::bind(&RtclAttnShuttle::AttnHandler, this, _1), |
fMask, (void*)this); |
fpServ = pserv; |
|
// connect to Tcl |
fShuttleChn = Tcl_MakeFileChannel((ClientData)fFdPipeRead, TCL_READABLE); |
|
Tcl_SetChannelOption(NULL, fShuttleChn, "-buffersize", "64"); |
Tcl_SetChannelOption(NULL, fShuttleChn, "-encoding", "binary"); |
Tcl_SetChannelOption(NULL, fShuttleChn, "-translation", "binary"); |
|
Tcl_CreateChannelHandler(fShuttleChn, TCL_READABLE, |
(Tcl_FileProc*) ThunkTclChannelHandler, |
(ClientData) this); |
|
fpInterp = interp; |
return; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
void RtclAttnShuttle::Remove() |
{ |
// disconnect from RlinkServer |
if (fpServ) { |
fpServ->RemoveAttnHandler(fMask, (void*)this); |
fpServ = 0; |
} |
// disconnect from Tcl |
if (fpInterp) { |
Tcl_DeleteChannelHandler(fShuttleChn, |
(Tcl_FileProc*) ThunkTclChannelHandler, |
(ClientData) this); |
Tcl_Close(fpInterp, fShuttleChn); |
fpInterp = 0; |
} |
|
return; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclAttnShuttle::AttnHandler(const RlinkServer::AttnArgs& args) |
{ |
uint16_t apat = args.fAttnPatt & args.fAttnMask; |
int irc = ::write(fFdPipeWrite, (void*) &apat, sizeof(apat)); |
if (irc < 0) |
throw Rexception("RtclAttnShuttle::AttnHandler()", |
"write() failed: ", errno); |
return 0; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
void RtclAttnShuttle::TclChannelHandler(int mask) |
{ |
uint16_t apat; |
Tcl_ReadRaw(fShuttleChn, (char*) &apat, sizeof(apat)); |
// FIXME_code: handle return code |
|
Tcl_SetVar2Ex(fpInterp, "Rlink_attnbits", NULL, Tcl_NewIntObj((int)apat), 0); |
// FIXME_code: handle return code |
|
Tcl_EvalObjEx(fpInterp, fpScript, TCL_EVAL_GLOBAL); |
// FIXME_code: handle return code |
return; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
void RtclAttnShuttle::ThunkTclChannelHandler(ClientData cdata, int mask) |
{ |
((RtclAttnShuttle*) cdata)->TclChannelHandler(mask); |
return; |
} |
|
} // end namespace Retro |
/RtclRlinkPort.cpp
0,0 → 1,330
// $Id: RtclRlinkPort.cpp 521 2013-05-20 22:16:45Z mueller $ |
// |
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> |
// |
// This program is free software; you may redistribute and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation, either version 2, or at your option any later version. |
// |
// This program 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 complete details. |
// |
// Revision History: |
// Date Rev Version Comment |
// 2013-02-23 492 1.0.2 use RlogFile.Name(); |
// 2013-02-22 491 1.0.1 use new RlogFile/RlogMsg interfaces |
// 2013-01-27 478 1.0 Initial version |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclRlinkPort.cpp 521 2013-05-20 22:16:45Z mueller $ |
\brief Implemenation of class RtclRlinkPort. |
*/ |
|
#include <ctype.h> |
|
#include <iostream> |
|
#include "boost/bind.hpp" |
|
#include "librtcltools/Rtcl.hpp" |
#include "librtcltools/RtclOPtr.hpp" |
#include "librtcltools/RtclNameSet.hpp" |
#include "librtcltools/RtclStats.hpp" |
#include "librtools/RosPrintf.hpp" |
#include "librtools/RlogFile.hpp" |
#include "librlink/RlinkPortFactory.hpp" |
|
#include "RtclRlinkPort.hpp" |
|
using namespace std; |
|
/*! |
\class Retro::RtclRlinkPort |
\brief FIXME_docs |
*/ |
|
// all method definitions in namespace Retro |
namespace Retro { |
|
//------------------------------------------+----------------------------------- |
//! Default constructor |
|
RtclRlinkPort::RtclRlinkPort(Tcl_Interp* interp, const char* name) |
: RtclProxyBase("RlinkPort"), |
fpObj(0), |
fspLog(new RlogFile(&cout, "<cout>")), |
fTraceLevel(0), |
fErrCnt(0) |
{ |
CreateObjectCmd(interp, name); |
AddMeth("open", boost::bind(&RtclRlinkPort::M_open, this, _1)); |
AddMeth("close", boost::bind(&RtclRlinkPort::M_close, this, _1)); |
AddMeth("errcnt", boost::bind(&RtclRlinkPort::M_errcnt, this, _1)); |
AddMeth("rawio", boost::bind(&RtclRlinkPort::M_rawio, this, _1)); |
AddMeth("stats", boost::bind(&RtclRlinkPort::M_stats, this, _1)); |
AddMeth("log", boost::bind(&RtclRlinkPort::M_log, this, _1)); |
AddMeth("dump", boost::bind(&RtclRlinkPort::M_dump, this, _1)); |
AddMeth("config", boost::bind(&RtclRlinkPort::M_config, this, _1)); |
AddMeth("$default", boost::bind(&RtclRlinkPort::M_default, this, _1)); |
} |
|
//------------------------------------------+----------------------------------- |
//! Destructor |
|
RtclRlinkPort::~RtclRlinkPort() |
{ |
delete fpObj; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkPort::M_open(RtclArgs& args) |
{ |
string path; |
|
if (!args.GetArg("?path", path)) return kERR; |
if (!args.AllDone()) return kERR; |
|
RerrMsg emsg; |
if (args.NOptMiss() == 0) { // open path |
delete fpObj; |
fpObj = RlinkPortFactory::Open(path, emsg); |
if (!fpObj) return args.Quit(emsg); |
fpObj->SetLogFile(fspLog); |
fpObj->SetTraceLevel(fTraceLevel); |
} else { // open |
string name = (fpObj && fpObj->IsOpen()) ? fpObj->Url().Url() : string(); |
args.SetResult(name); |
} |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkPort::M_close(RtclArgs& args) |
{ |
if (!args.AllDone()) return kERR; |
if (!TestOpen(args)) return kERR; |
delete fpObj; |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkPort::M_errcnt(RtclArgs& args) |
{ |
static RtclNameSet optset("-clear"); |
string opt; |
bool fclear = false; |
|
while (args.NextOpt(opt, optset)) { |
if (opt == "-clear") fclear = true; |
} |
if (!args.AllDone()) return kERR; |
|
args.SetResult(int(fErrCnt)); |
if (fclear) fErrCnt = 0; |
|
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkPort::M_rawio(RtclArgs& args) |
{ |
return DoRawio(args, fpObj, fErrCnt); |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkPort::M_stats(RtclArgs& args) |
{ |
RtclStats::Context cntx; |
|
if (!TestOpen(args)) return kERR; |
if (!RtclStats::GetArgs(args, cntx)) return kERR; |
if (!RtclStats::Collect(args, cntx, fpObj->Stats())) return kERR; |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkPort::M_log(RtclArgs& args) |
{ |
string msg; |
if (!args.GetArg("msg", msg)) return kERR; |
if (!args.AllDone()) return kERR; |
if (fTraceLevel != 0) fspLog->Write(string("# ") + msg); |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkPort::M_dump(RtclArgs& args) |
{ |
if (!args.AllDone()) return kERR; |
if (!TestOpen(args)) return kERR; |
|
ostringstream sos; |
fpObj->Dump(sos, 0); |
args.SetResult(sos); |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkPort::M_config(RtclArgs& args) |
{ |
static RtclNameSet optset("-logfile|-logtracelevel"); |
|
if (args.NDone() == (size_t)args.Objc()) { |
ostringstream sos; |
sos << " -logfile {" << fspLog->Name() << "}" |
<< " -logtracelevel " << RosPrintf(fTraceLevel, "d"); |
args.AppendResult(sos); |
return kOK; |
} |
|
string opt; |
while (args.NextOpt(opt, optset)) { |
if (opt == "-logfile") { // -logfile ?name ------------------ |
string name; |
if (!args.Config("??name", name)) return false; |
if (args.NOptMiss() == 0) { // new filename ? |
if (name == "-" || name == "<cout>") { |
fspLog->UseStream(&cout, "<cout>"); |
} else { |
if (!fspLog->Open(name)) { |
fspLog->UseStream(&cout, "<cout>"); |
return args.Quit(string("-E: open failed for '") + name + |
"', using stdout"); |
} |
} |
} |
} else if (opt == "-logtracelevel") { // -logtracelevel ?loglevel -------- |
if (!args.Config("??loglevel", fTraceLevel, 3)) return false; |
if (fpObj) fpObj->SetTraceLevel(fTraceLevel); |
} |
} |
|
if (!args.AllDone()) return kERR; |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkPort::M_default(RtclArgs& args) |
{ |
if (!args.AllDone()) return kERR; |
ostringstream sos; |
|
sos << "logfile: " << fspLog->Name() |
<< " tracelevel " << fTraceLevel; |
|
args.AppendResultLines(sos); |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
bool RtclRlinkPort::TestOpen(RtclArgs& args) |
{ |
if (fpObj) return true; |
args.AppendResult("-E: port not open", NULL); |
return false; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkPort::DoRawio(RtclArgs& args, RlinkPort* pport, size_t& errcnt) |
{ |
static RtclNameSet optset("-rblk|-wblk|-edata|-timeout"); |
|
if (!pport || !pport->IsOpen()) args.Quit("-E: port not open"); |
|
string opt; |
char mode = 0; |
|
int32_t rsize; |
string rvname; |
vector<uint8_t> rdata; |
vector<uint8_t> wdata; |
vector<uint8_t> edata; |
vector<uint8_t> emask; |
double timeout = 1.; |
|
while (args.NextOpt(opt, optset)) { |
if (opt == "-rblk") { // -rblk size ?varData ------------ |
if (mode) return args.Quit("-E: only one -rblk or -wblk allowed"); |
mode = 'r'; |
if (!args.GetArg("bsize", rsize, 1, 256)) return kERR; |
if (!args.GetArg("??varData", rvname)) return kERR; |
|
} else if (opt == "-wblk") { // -wblk block -------------------- |
if (mode) return args.Quit("-E: only one -rblk or -wblk allowed"); |
mode = 'w'; |
if (!args.GetArg("data", wdata, 1, 256)) return kERR; |
|
} else if (opt == "-edata") { // -edata data ?mask -------------- |
if (mode != 'r') return args.Quit("-E: -edata only allowed after -rblk"); |
if (!args.GetArg("data", edata, 0, rsize)) return kERR; |
if (!args.GetArg("??mask", emask, 0, rsize)) return kERR; |
|
} else if (opt == "-timeout") { // -timeout tsec ------------------ |
if (!args.GetArg("tsec", timeout, 0.)) return kERR; |
} |
} |
|
if (!args.AllDone()) return kERR; |
|
if (!mode) return args.Quit("-E: no -rblk or -wblk given"); |
|
if (mode == 'r') { // handle -rblk ------------------ |
RerrMsg emsg; |
double tused = 0.; |
rdata.resize(rsize); |
int irc = pport->RawRead(rdata.data(), rdata.size(), true, timeout, |
tused, emsg); |
if (irc == RlinkPort::kErr) return args.Quit("-E: timeout on -rblk"); |
if (irc != (int)rdata.size()) return args.Quit(emsg); |
if (rvname.length()) { |
RtclOPtr pres(Rtcl::NewListIntObj(rdata)); |
if(!Rtcl::SetVar(args.Interp(), rvname, pres)) return kERR; |
} |
if (edata.size()) { |
size_t nerr=0; |
for (size_t i=0; i<rdata.size(); i++) { |
if (i >= edata.size()) break; |
uint8_t eval = edata[i]; |
uint8_t emsk = (i < emask.size()) ? emask[i] : 0x0000; |
if ((rdata[i]|emsk) != (eval|emsk)) nerr += 1; |
} |
if (nerr) errcnt += 1; |
} |
args.SetResult(tused); |
|
} else { // handle -wblk ------------------ |
RerrMsg emsg; |
int irc = pport->RawWrite(wdata.data(), wdata.size(), emsg); |
if (irc != (int)wdata.size()) return args.Quit(emsg); |
} |
|
return kOK; |
} |
|
} // end namespace Retro |
/Makefile
0,0 → 1,65
# $Id: Makefile 529 2013-08-02 17:15:43Z mueller $ |
# |
# Revision History: |
# Date Rev Version Comment |
# 2013-02-01 479 1.1.32 use checkpath_cpp.mk |
# 2013-01-27 478 1.1.2 add RtclRlinkPort |
# 2012-12-24 464 1.1.1 add TCLINC |
# 2011-07-31 401 1.1 rename realclean->distclean |
# 2011-07-01 386 1.0.2 add BOOSTINC |
# 2011-03-20 372 1.0.1 renamed ..tcl -> ..tpp |
# 2011-02-12 360 1.0 Initial version |
#--- |
# |
# Name of the sharable library |
# |
SONAME = rlinktpp |
SOMAJV = 1 |
SOMINV = 0 |
# |
# Compile and Link search paths |
# |
include ../checkpath_cpp.mk |
# |
INCLFLAGS = -I${RETROBASE}/tools/src -I${TCLINC} -I${BOOSTINC} |
LDLIBS = -L${RETROBASE}/tools/lib -lrtools -lrtcltools -lrlink |
# |
# Object files to be included |
# |
OBJ_all = Rlinktpp_Init.o RtclRlinkPort.o RtclRlinkConnect.o \ |
RtclRlinkServer.o RtclAttnShuttle.o |
# |
DEP_all = $(OBJ_all:.o=.dep) |
# |
#- generic part ---------------------------------------------------------------- |
# |
SOFILE = lib$(SONAME).so |
SOFILEV = lib$(SONAME).so.$(SOMAJV) |
SOFILEVV = lib$(SONAME).so.$(SOMAJV).$(SOMINV) |
# |
include $(RETROBASE)/tools/make/generic_cpp.mk |
include $(RETROBASE)/tools/make/generic_dep.mk |
include $(RETROBASE)/tools/make/generic_so.mk |
include $(RETROBASE)/tools/make/dontincdep.mk |
# |
# The magic auto-dependency include |
# |
ifndef DONTINCDEP |
include $(DEP_all) |
endif |
# |
# cleanup phonies: |
# |
.PHONY : clean cleandep distclean |
clean : |
@ rm -f $(OBJ_all) |
@ echo "Object files removed" |
# |
cleandep : |
@ rm -f $(DEP_all) |
@ echo "Dependency files removed" |
# |
distclean : clean cleandep |
@ rm -f $(SOPATH)/lib$(SONAME).a $(SOPATH)/lib$(SONAME).so* |
@ echo "Libraries removed" |
# |
/RtclRlinkServer.cpp
0,0 → 1,293
// $Id: RtclRlinkServer.cpp 513 2013-05-01 14:02:06Z mueller $ |
// |
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> |
// |
// This program is free software; you may redistribute and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation, either version 2, or at your option any later version. |
// |
// This program 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 complete details. |
// |
// Revision History: |
// Date Rev Version Comment |
// 2013-05-01 513 1.0.5 TraceLevel now uint32_t |
// 2013-04-26 510 1.0.4 change M_attn, now -info instead of -show |
// 2013-04-21 509 1.0.3 add server -resume |
// 2013-02-05 483 1.0.2 ClassCmdConfig: use RtclArgs |
// 2013-02-05 482 1.0.1 add shared_ptr to RlinkConnect object |
// 2013-01-12 474 1.0 Initial version |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclRlinkServer.cpp 513 2013-05-01 14:02:06Z mueller $ |
\brief Implemenation of class RtclRlinkServer. |
*/ |
|
#include <ctype.h> |
|
#include <stdexcept> |
#include <iostream> |
#include <vector> |
#include <string> |
#include <memory> |
|
#include "boost/bind.hpp" |
|
#include "librtools/RosPrintBvi.hpp" |
#include "librtcltools/Rtcl.hpp" |
#include "librtcltools/RtclOPtr.hpp" |
#include "librtcltools/RtclStats.hpp" |
#include "librtcltools/RtclContext.hpp" |
#include "RtclRlinkConnect.hpp" |
|
#include "RtclRlinkServer.hpp" |
|
using namespace std; |
|
/*! |
\class Retro::RtclRlinkServer |
\brief FIXME_docs |
*/ |
|
// all method definitions in namespace Retro |
namespace Retro { |
|
//------------------------------------------+----------------------------------- |
//! Default constructor |
|
RtclRlinkServer::RtclRlinkServer(Tcl_Interp* interp, const char* name) |
: RtclProxyOwned<RlinkServer>("RlinkServer", interp, name, |
new RlinkServer()), |
fspConn() |
{ |
AddMeth("server", boost::bind(&RtclRlinkServer::M_server, this, _1)); |
AddMeth("attn", boost::bind(&RtclRlinkServer::M_attn, this, _1)); |
AddMeth("stats", boost::bind(&RtclRlinkServer::M_stats, this, _1)); |
AddMeth("print", boost::bind(&RtclRlinkServer::M_print, this, _1)); |
AddMeth("dump", boost::bind(&RtclRlinkServer::M_dump, this, _1)); |
AddMeth("$default", boost::bind(&RtclRlinkServer::M_default, this, _1)); |
} |
|
//------------------------------------------+----------------------------------- |
//! Destructor |
|
RtclRlinkServer::~RtclRlinkServer() |
{ |
for (alist_it_t it = fAttnHdl.begin(); it != fAttnHdl.end(); it++) { |
delete (*it); |
} |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkServer::ClassCmdConfig(RtclArgs& args) |
{ |
string parent; |
if (!args.GetArg("parent", parent)) return kERR; |
|
// locate RlinkConnect proxy and object -> setup Server->Connect linkage |
RtclProxyBase* pprox = RtclContext::Find(args.Interp()).FindProxy( |
"RlinkConnect", parent); |
if (pprox == 0) |
return args.Quit(string("-E: object '") + parent + |
"' not found or not type RlinkConnect"); |
|
// make RtclRlinkServer object be co-owner of RlinkConnect object |
fspConn = dynamic_cast<RtclRlinkConnect*>(pprox)->ObjSPtr(); |
// set RlinkConnect in RlinkServer (make RlinkServer also co-owner) |
Obj().SetConnect(fspConn); |
|
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkServer::M_server(RtclArgs& args) |
{ |
static RtclNameSet optset("-start|-stop|-resume|-test|-trace"); |
string opt; |
if (args.NextOpt(opt, optset)) { |
if (opt == "-start") { // server -start |
if (!args.AllDone()) return kERR; |
Obj().Start(); |
} else if (opt == "-stop") { // server -stop |
if (!args.AllDone()) return kERR; |
Obj().Stop(); |
} else if (opt == "-resume") { // server -resume |
if (!args.AllDone()) return kERR; |
Obj().Resume(); |
} else if (opt == "-test") { // server -test |
if (!args.AllDone()) return kERR; |
args.SetResult(Obj().IsActive()); |
} else if (opt == "-trace") { // server -trace ... |
uint32_t level; |
if (!args.GetArg("?level", level)) return kERR; |
if (args.NOptMiss()==0) { // server -trace level |
Obj().SetTraceLevel(level); |
} else { // server -trace |
args.SetResult((int)Obj().TraceLevel()); |
} |
} |
|
} else { // server |
if (!args.OptValid()) return kERR; |
if (!args.AllDone()) return kERR; |
args.SetResult(Obj().IsActive()); |
} |
|
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkServer::M_attn(RtclArgs& args) |
{ |
static RtclNameSet optset("-add|-remove|-info|-test|-list"); |
|
Tcl_Interp* interp = args.Interp(); |
|
string opt; |
|
if (args.NextOpt(opt, optset)) { |
if (opt == "-add") { // attn -add mask script |
uint16_t mask=0; |
Tcl_Obj* script=0; |
if (!args.GetArg("mask", mask,0xff,1)) return kERR; |
if (!args.GetArg("script", script)) return kERR; |
if (!args.AllDone()) return kERR; |
|
unique_ptr<RtclAttnShuttle> p(new RtclAttnShuttle(mask, script)); |
try { |
p->Add(&Obj(), interp); |
} catch (exception& e) { |
return args.Quit(string("-E: handler rejected: ")+e.what()); |
} |
fAttnHdl.push_back(p.release()); |
return kOK; |
|
} else if (opt == "-remove") { // attn -remove mask |
uint16_t mask=0; |
if (!args.GetArg("mask", mask)) return kERR; |
if (!args.AllDone()) return kERR; |
for (alist_it_t it = fAttnHdl.end(); it != fAttnHdl.begin(); ) { |
it--; |
if ((*it)->Mask() == mask) { |
fAttnHdl.erase(it); |
delete (*it); |
return kOK; |
} |
} |
return args.Quit(string("-E: no handler defined for '") + |
args.PeekArgString(-1) + "'"); |
|
} else if (opt == "-info") { // attn -info mask |
uint16_t mask=0; |
if (!args.GetArg("mask", mask)) return kERR; |
if (!args.AllDone()) return kERR; |
RtclOPtr pres(Tcl_NewListObj(0,0)); |
for (alist_it_t it = fAttnHdl.begin(); it != fAttnHdl.end(); it++) { |
if ((*it)->Mask() & mask) { |
RtclOPtr pele(Tcl_NewListObj(0,0)); |
Tcl_ListObjAppendElement(NULL, pele, Tcl_NewIntObj((*it)->Mask()) ); |
Tcl_ListObjAppendElement(NULL, pele, (*it)->Script() ); |
Tcl_ListObjAppendElement(NULL, pres, pele); |
} |
} |
args.SetResult(pres); |
return kOK; |
|
} else if (opt == "-test") { // attn -test mask |
uint16_t mask=0; |
if (!args.GetArg("mask", mask)) return kERR; |
if (!args.AllDone()) return kERR; |
int nhdl = 0; |
for (alist_it_t it = fAttnHdl.begin(); it != fAttnHdl.end(); it++) { |
if ((*it)->Mask() & mask) { |
nhdl += 1; |
int rc = Tcl_EvalObjEx(interp, (*it)->Script(), TCL_EVAL_GLOBAL); |
if (rc != kOK) return rc; |
} |
} |
if (nhdl) return kOK; |
return args.Quit(string("-E: no handler defined for '") + |
args.PeekArgString(-1) + "'"); |
|
} else if (opt == "-list") { // attn -list |
if (!args.AllDone()) return kERR; |
vector<uint16_t> vres; |
for (alist_it_t it = fAttnHdl.begin(); it != fAttnHdl.end(); it++) { |
vres.push_back((*it)->Mask()); |
} |
args.SetResult(Rtcl::NewListIntObj(vres)); |
} |
|
} else { // attn |
if (!args.OptValid()) return kERR; |
if (!args.AllDone()) return kERR; |
uint16_t mask=0; |
for (alist_it_t it = fAttnHdl.begin(); it != fAttnHdl.end(); it++) { |
mask |= (*it)->Mask(); |
} |
args.SetResult(mask); |
} |
|
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkServer::M_stats(RtclArgs& args) |
{ |
RtclStats::Context cntx; |
if (!RtclStats::GetArgs(args, cntx)) return kERR; |
if (!RtclStats::Collect(args, cntx, Obj().Stats())) return kERR; |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkServer::M_print(RtclArgs& args) |
{ |
if (!args.AllDone()) return kERR; |
|
ostringstream sos; |
Obj().Print(sos); |
args.SetResult(sos); |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkServer::M_dump(RtclArgs& args) |
{ |
if (!args.AllDone()) return kERR; |
|
ostringstream sos; |
Obj().Dump(sos, 0); |
args.SetResult(sos); |
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclRlinkServer::M_default(RtclArgs& args) |
{ |
if (!args.AllDone()) return kERR; |
ostringstream sos; |
sos << "no default output defined yet...\n"; |
args.AppendResultLines(sos); |
return kOK; |
} |
|
} // end namespace Retro |
/RtclRlinkPort.hpp
0,0 → 1,74
// $Id: RtclRlinkPort.hpp 492 2013-02-24 22:14:47Z mueller $ |
// |
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> |
// |
// This program is free software; you may redistribute and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation, either version 2, or at your option any later version. |
// |
// This program 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 complete details. |
// |
// Revision History: |
// Date Rev Version Comment |
// 2013-02-23 492 1.0.1 use RlogFile.Name(); |
// 2013-01-27 478 1.0 Initial version |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclRlinkPort.hpp 492 2013-02-24 22:14:47Z mueller $ |
\brief Declaration of class RtclRlinkPort. |
*/ |
|
#ifndef included_Retro_RtclRlinkPort |
#define included_Retro_RtclRlinkPort 1 |
|
#include <cstddef> |
#include <string> |
|
#include "boost/shared_ptr.hpp" |
|
#include "librtcltools/RtclProxyBase.hpp" |
|
#include "librtools/RlogFile.hpp" |
#include "librlink/RlinkPort.hpp" |
|
namespace Retro { |
|
class RtclRlinkPort : public RtclProxyBase { |
public: |
RtclRlinkPort(Tcl_Interp* interp, const char* name); |
~RtclRlinkPort(); |
|
friend class RtclRlinkConnect; |
|
protected: |
int M_open(RtclArgs& args); |
int M_close(RtclArgs& args); |
int M_errcnt(RtclArgs& args); |
int M_rawio(RtclArgs& args); |
int M_stats(RtclArgs& args); |
int M_log(RtclArgs& args); |
int M_dump(RtclArgs& args); |
int M_config(RtclArgs& args); |
int M_default(RtclArgs& args); |
|
bool TestOpen(RtclArgs& args); |
|
static int DoRawio(RtclArgs& args, RlinkPort* pport, size_t& errcnt); |
|
protected: |
RlinkPort* fpObj; //!< ptr to managed object |
boost::shared_ptr<RlogFile> fspLog; //!< port log file |
uint32_t fTraceLevel; //!< 0=off,1=buf,2=char |
size_t fErrCnt; //!< error count |
}; |
|
} // end namespace Retro |
|
//#include "RtclRlinkPort.ipp" |
|
#endif |
/RtclRlinkServer.hpp
0,0 → 1,70
// $Id: RtclRlinkServer.hpp 486 2013-02-10 22:34:43Z mueller $ |
// |
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> |
// |
// This program is free software; you may redistribute and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation, either version 2, or at your option any later version. |
// |
// This program 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 complete details. |
// |
// Revision History: |
// Date Rev Version Comment |
// 2013-02-05 482 1.0.1 add shared_ptr to RlinkConnect object |
// 2013-01-12 474 1.0 Initial version |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclRlinkServer.hpp 486 2013-02-10 22:34:43Z mueller $ |
\brief Declaration of class RtclRlinkServer. |
*/ |
|
#ifndef included_Retro_RtclRlinkServer |
#define included_Retro_RtclRlinkServer 1 |
|
#include <cstddef> |
#include <list> |
|
#include "boost/shared_ptr.hpp" |
|
#include "librtcltools/RtclOPtr.hpp" |
#include "librtcltools/RtclProxyOwned.hpp" |
#include "RtclAttnShuttle.hpp" |
#include "librlink/RlinkServer.hpp" |
|
namespace Retro { |
|
class RlinkConnect; |
|
class RtclRlinkServer : public RtclProxyOwned<RlinkServer> { |
public: |
RtclRlinkServer(Tcl_Interp* interp, const char* name); |
~RtclRlinkServer(); |
|
virtual int ClassCmdConfig(RtclArgs& args); |
|
protected: |
int M_server(RtclArgs& args); |
int M_attn(RtclArgs& args); |
int M_stats(RtclArgs& args); |
int M_print(RtclArgs& args); |
int M_dump(RtclArgs& args); |
int M_default(RtclArgs& args); |
|
protected: |
typedef std::list<RtclAttnShuttle*> alist_t; |
typedef alist_t::iterator alist_it_t; |
|
boost::shared_ptr<RlinkConnect> fspConn; |
alist_t fAttnHdl; //<! list of attn handlers |
}; |
|
} // end namespace Retro |
|
//#include "RtclRlinkServer.ipp" |
|
#endif |
/RtclRlinkConnect.hpp
0,0 → 1,78
// $Id: RtclRlinkConnect.hpp 492 2013-02-24 22:14:47Z mueller $ |
// |
// Copyright 2011-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> |
// |
// This program is free software; you may redistribute and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation, either version 2, or at your option any later version. |
// |
// This program 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 complete details. |
// |
// Revision History: |
// Date Rev Version Comment |
// 2013-02-23 492 1.0.3 use RlogFile.Name(); use Context().ErrorCount() |
// 2013-01-06 473 1.0.2 add M_rawio |
// 2011-11-28 434 1.0.1 ConfigBase(): use uint32_t for lp64 compatibility |
// 2011-03-27 374 1.0 Initial version |
// 2011-02-11 360 0.1 First draft |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclRlinkConnect.hpp 492 2013-02-24 22:14:47Z mueller $ |
\brief Declaration of class RtclRlinkConnect. |
*/ |
|
#ifndef included_Retro_RtclRlinkConnect |
#define included_Retro_RtclRlinkConnect 1 |
|
#include <cstddef> |
#include <string> |
|
#include "librtcltools/RtclOPtr.hpp" |
#include "librtcltools/RtclProxyOwned.hpp" |
|
#include "librlink/RlinkConnect.hpp" |
|
namespace Retro { |
|
class RtclRlinkConnect : public RtclProxyOwned<RlinkConnect> { |
public: |
RtclRlinkConnect(Tcl_Interp* interp, const char* name); |
~RtclRlinkConnect(); |
|
protected: |
int M_open(RtclArgs& args); |
int M_close(RtclArgs& args); |
int M_exec(RtclArgs& args); |
int M_amap(RtclArgs& args); |
int M_errcnt(RtclArgs& args); |
int M_wtlam(RtclArgs& args); |
int M_oob(RtclArgs& args); |
int M_rawio(RtclArgs& args); |
int M_stats(RtclArgs& args); |
int M_log(RtclArgs& args); |
int M_print(RtclArgs& args); |
int M_dump(RtclArgs& args); |
int M_config(RtclArgs& args); |
int M_default(RtclArgs& args); |
|
bool GetAddr(RtclArgs& args, RlinkConnect& conn, uint16_t& addr); |
bool GetVarName(RtclArgs& args, const char* argname, |
size_t nind, std::vector<std::string>& varname); |
bool ConfigBase(RtclArgs& args, uint32_t& base); |
bool ClistNonEmpty(RtclArgs& args, |
const RlinkCommandList& clist); |
|
protected: |
RtclOPtr fCmdnameObj[8]; |
}; |
|
} // end namespace Retro |
|
//#include "RtclRlinkConnect.ipp" |
|
#endif |
/Rlinktpp_Init.cpp
0,0 → 1,68
// $Id: Rlinktpp_Init.cpp 504 2013-04-13 15:37:24Z mueller $ |
// |
// Copyright 2011-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> |
// |
// This program is free software; you may redistribute and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation, either version 2, or at your option any later version. |
// |
// This program 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 complete details. |
// |
// Revision History: |
// Date Rev Version Comment |
// 2013-02-10 485 1.0.5 remove Tcl_InitStubs() |
// 2013-01-27 478 1.0.4 add rlinkport |
// 2013-01-12 474 1.0.3 add rlinkserver |
// 2011-03-20 372 1.0.2 renamed ..tcl -> ..tpp |
// 2011-03-19 371 1.0.1 moved Bvi into librtoolstcl |
// 2011-03-14 370 1.0 Initial version |
// 2011-02-11 360 0.1 First draft |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: Rlinktpp_Init.cpp 504 2013-04-13 15:37:24Z mueller $ |
\brief Implemenation of Rlinktpp_Init . |
*/ |
|
#include "tcl.h" |
|
#include <stdexcept> |
|
#include "librtcltools/RtclClassOwned.hpp" |
#include "RtclRlinkPort.hpp" |
#include "RtclRlinkConnect.hpp" |
#include "RtclRlinkServer.hpp" |
|
using namespace std; |
using namespace Retro; |
|
//------------------------------------------+----------------------------------- |
extern "C" int Rlinktpp_Init(Tcl_Interp* interp) |
{ |
int irc; |
|
// declare package name and version |
irc = Tcl_PkgProvide(interp, "rlinktpp", "1.0.0"); |
if (irc != TCL_OK) return irc; |
|
try { |
// register class commands |
RtclClassOwned<RtclRlinkPort>::CreateClass(interp, "rlinkport", |
"RlinkPort"); |
RtclClassOwned<RtclRlinkConnect>::CreateClass(interp, "rlinkconnect", |
"RlinkConnect"); |
RtclClassOwned<RtclRlinkServer>::CreateClass(interp, "rlinkserver", |
"RlinkServer"); |
return TCL_OK; |
|
} catch (exception& e) { |
Tcl_AppendResult(interp, "-E: exception caught in Rlinktpp_Init: '", |
e.what(), "'", NULL); |
} |
return TCL_ERROR; |
} |
|
/RtclAttnShuttle.hpp
0,0 → 1,68
// $Id: RtclAttnShuttle.hpp 495 2013-03-06 17:13:48Z mueller $ |
// |
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> |
// |
// This program is free software; you may redistribute and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation, either version 2, or at your option any later version. |
// |
// This program 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 complete details. |
// |
// Revision History: |
// Date Rev Version Comment |
// 2013-03-01 493 1.0 Initial version |
// 2013-01-14 475 0.5 First draft |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclAttnShuttle.hpp 495 2013-03-06 17:13:48Z mueller $ |
\brief Declaration of class RtclAttnShuttle. |
*/ |
|
#ifndef included_Retro_RtclAttnShuttle |
#define included_Retro_RtclAttnShuttle 1 |
|
#include "tcl.h" |
|
#include <cstdint> |
|
#include "librtcltools/RtclOPtr.hpp" |
#include "librlink/RlinkServer.hpp" |
|
namespace Retro { |
|
class RtclAttnShuttle { |
public: |
RtclAttnShuttle(uint16_t mask, Tcl_Obj* pobj); |
~RtclAttnShuttle(); |
|
uint16_t Mask() const; |
Tcl_Obj* Script() const; |
|
void Add(RlinkServer* pserv, Tcl_Interp* interp); |
void Remove(); |
|
protected: |
int AttnHandler(const RlinkServer::AttnArgs& args); |
void TclChannelHandler(int mask); |
static void ThunkTclChannelHandler(ClientData cdata, int mask); |
|
protected: |
RlinkServer* fpServ; //!< RlinkServer used |
Tcl_Interp* fpInterp; //!< Tcl interpreter used |
int fFdPipeRead; //!< attn pipe read fd |
int fFdPipeWrite; //!< attn pipe write fd |
Tcl_Channel fShuttleChn; //!< Tcl channel |
uint16_t fMask; //!< attn mask |
RtclOPtr fpScript; //!< Tcl handler script (as Tcl_Obj) |
}; |
|
} // end namespace Retro |
|
#include "RtclAttnShuttle.ipp" |
|
#endif |
/RtclAttnShuttle.ipp
0,0 → 1,46
// $Id: RtclAttnShuttle.ipp 495 2013-03-06 17:13:48Z mueller $ |
// |
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> |
// |
// This program is free software; you may redistribute and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation, either version 2, or at your option any later version. |
// |
// This program 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 complete details. |
// |
// Revision History: |
// Date Rev Version Comment |
// 2013-03-01 493 1.0 Initial version |
// 2013-01-14 475 0.5 First draft |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclAttnShuttle.ipp 495 2013-03-06 17:13:48Z mueller $ |
\brief Implemenation (inline) of class RtclAttnShuttle. |
*/ |
|
// all method definitions in namespace Retro |
namespace Retro { |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
inline uint16_t RtclAttnShuttle::Mask() const |
{ |
return fMask; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
inline Tcl_Obj* RtclAttnShuttle::Script() const |
{ |
return fpScript; |
} |
|
} // end namespace Retro |
|
/.cvsignore
0,0 → 1,46
*.dep |
.
Property changes :
Added: svn:ignore
## -0,0 +1,34 ##
+*.dep_ghdl
+*.dep_isim
+*.dep_xst
+work-obj93.cf
+*.vcd
+*.ghw
+*.sav
+*.tmp
+*.exe
+ise
+xflow.his
+*.ngc
+*.ncd
+*.pcf
+*.bit
+*.msk
+isim
+isim.log
+isim.wdb
+fuse.log
+*_[sft]sim.vhd
+*_tsim.sdf
+*_xst.log
+*_tra.log
+*_twr.log
+*_map.log
+*_par.log
+*_tsi.log
+*_pad.log
+*_bgn.log
+*_svn.log
+*_sum.log
+*_[dsft]sim.log
+*.dep