w11 - cpp 0.794
Backend server for Rlink and w11
Loading...
Searching...
No Matches
RtclRlinkConnect.cpp
Go to the documentation of this file.
1// $Id: RtclRlinkConnect.cpp 1175 2019-06-30 06:13:17Z mueller $
2// SPDX-License-Identifier: GPL-3.0-or-later
3// Copyright 2011-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4//
5// Revision History:
6// Date Rev Version Comment
7// 2019-06-29 1175 1.6.12 M_log(): add missing OptValid() call
8// 2019-06-07 1160 1.6.11 use RtclStats::Exec()
9// 2019-03-10 1121 1.6.10 M_exec(): tranfer BlockDone values after rblk
10// 2019-02-23 1114 1.6.9 use std::bind instead of lambda
11// 2018-12-23 1091 1.6.8 use AddWblk(move)
12// 2018-12-18 1089 1.6.7 use c++ style casts
13// 2018-12-17 1085 1.6.6 use std::lock_guard instead of boost
14// 2018-12-15 1082 1.6.5 use lambda instead of boost::bind
15// 2018-12-08 1079 1.6.4 use HasPort(); Port() returns now ref
16// 2018-12-07 1077 1.6.3 use SetLastExpectBlock move semantics
17// 2018-11-16 1070 1.6.2 use auto; use range loop
18// 2018-09-16 1047 1.6.1 coverity fixup (uninitialized scalar)
19// 2017-04-29 888 1.6 drop M_rawio; add M_rawread,M_rawrblk,M_rawwblk
20// 2017-04-22 883 1.5.2 M_amap: -testname opt addr check; add hasrbmon get
21// 2017-04-02 865 1.5.1 M_dump: use GetArgsDump and Dump detail
22// 2017-02-20 854 1.5 use Rtime
23// 2016-04-02 758 1.4.6 add USR_ACCESS register support (UsrAcc->usracc)
24// 2016-03-20 748 1.4.5 M_get/set: add timeout
25// 2015-05-09 676 1.4.3 M_errcnt: add -increment; M_log: add -bare,-info..
26// 2015-04-19 668 1.4.2 M_wtlam: allow tout=0 for pending attn cleanup
27// 2015-04-12 666 1.4.1 add M_init
28// 2015-04-03 661 1.4 expect logic: drop estatdef, use LastExpect..
29// 2015-03-28 660 1.3.3 add stat* getter/setter; M_exec: add -estaterr ect
30// 2015-01-06 631 1.3.2 add M_get, M_set, remove M_config
31// 2014-12-20 616 1.3.1 M_exec: add -edone for BlockDone checking
32// 2014-12-06 609 1.3 new rlink v4 iface
33// 2014-08-22 584 1.2.1 use nullptr
34// 2014-08-15 583 1.2 rb_mreq addr now 16 bit
35// 2014-08-02 576 1.1.7 BUGFIX: redo estatdef logic; avoid LastExpect()
36// 2013-02-23 492 1.1.6 use RlogFile.Name(); use Context().ErrorCount()
37// 2013-02-22 491 1.1.5 use new RlogFile/RlogMsg interfaces
38// 2013-02-02 480 1.1.4 allow empty exec commands
39// 2013-01-27 478 1.1.3 use RtclRlinkPort::DoRawio on M_rawio
40// 2013-01-06 473 1.1.2 add M_rawio: rawio -write|-read
41// 2011-11-28 434 1.1.1 ConfigBase(): use uint32_t for lp64 compatibility
42// 2011-04-23 380 1.1 use boost/bind instead of RmethDsc
43// 2011-04-17 376 1.0.1 M_wtlam: now correct log levels
44// 2011-03-27 374 1.0 Initial version
45// 2011-02-11 360 0.1 First draft
46// ---------------------------------------------------------------------------
47
52#include <ctype.h>
53
54#include <iostream>
55#include <functional>
56
57#include "librtcltools/Rtcl.hpp"
62#include "librtools/RlogMsg.hpp"
64#include "RtclRlinkPort.hpp"
65
66#include "RtclRlinkConnect.hpp"
67
68using namespace std;
69using namespace std::placeholders;
70
76// all method definitions in namespace Retro
77namespace Retro {
78
79//------------------------------------------+-----------------------------------
81
82RtclRlinkConnect::RtclRlinkConnect(Tcl_Interp* interp, const char* name)
83 : RtclProxyOwned<RlinkConnect>("RlinkConnect", interp, name,
84 new RlinkConnect()),
85 fGets(),
86 fSets()
87{
88 AddMeth("open", bind(&RtclRlinkConnect::M_open, this, _1));
89 AddMeth("close", bind(&RtclRlinkConnect::M_close, this, _1));
90 AddMeth("init", bind(&RtclRlinkConnect::M_init, this, _1));
91 AddMeth("exec", bind(&RtclRlinkConnect::M_exec, this, _1));
92 AddMeth("amap", bind(&RtclRlinkConnect::M_amap, this, _1));
93 AddMeth("errcnt", bind(&RtclRlinkConnect::M_errcnt, this, _1));
94 AddMeth("wtlam", bind(&RtclRlinkConnect::M_wtlam, this, _1));
95 AddMeth("oob", bind(&RtclRlinkConnect::M_oob, this, _1));
96 AddMeth("rawread", bind(&RtclRlinkConnect::M_rawread, this, _1));
97 AddMeth("rawrblk", bind(&RtclRlinkConnect::M_rawrblk, this, _1));
98 AddMeth("rawwblk", bind(&RtclRlinkConnect::M_rawwblk, this, _1));
99 AddMeth("stats", bind(&RtclRlinkConnect::M_stats, this, _1));
100 AddMeth("log", bind(&RtclRlinkConnect::M_log, this, _1));
101 AddMeth("print", bind(&RtclRlinkConnect::M_print, this, _1));
102 AddMeth("dump", bind(&RtclRlinkConnect::M_dump, this, _1));
103 AddMeth("get", bind(&RtclRlinkConnect::M_get, this, _1));
104 AddMeth("set", bind(&RtclRlinkConnect::M_set, this, _1));
105 AddMeth("$default", bind(&RtclRlinkConnect::M_default, this, _1));
106
107 for (size_t i=0; i<8; i++) {
108 fCmdnameObj[i] = Tcl_NewStringObj(RlinkCommand::CommandName(i), -1);
109 }
110
111 // attributes of RlinkConnect
112 RlinkConnect* pobj = &Obj();
113
114 fGets.Add<uint32_t> ("baseaddr", bind(&RlinkConnect::LogBaseAddr, pobj));
115 fGets.Add<uint32_t> ("basedata", bind(&RlinkConnect::LogBaseData, pobj));
116 fGets.Add<uint32_t> ("basestat", bind(&RlinkConnect::LogBaseStat, pobj));
117 fGets.Add<uint32_t> ("printlevel", bind(&RlinkConnect::PrintLevel, pobj));
118 fGets.Add<uint32_t> ("dumplevel", bind(&RlinkConnect::DumpLevel, pobj));
119 fGets.Add<uint32_t> ("tracelevel", bind(&RlinkConnect::TraceLevel, pobj));
120 fGets.Add<const Rtime&> ("timeout", bind(&RlinkConnect::Timeout, pobj));
121 fGets.Add<const string&> ("logfile",bind(&RlinkConnect::LogFileName, pobj));
122
123 fGets.Add<uint32_t> ("initdone", bind(&RlinkConnect::LinkInitDone, pobj));
124 fGets.Add<uint32_t> ("sysid", bind(&RlinkConnect::SysId, pobj));
125 fGets.Add<uint32_t> ("usracc", bind(&RlinkConnect::UsrAcc, pobj));
126 fGets.Add<size_t> ("rbufsize", bind(&RlinkConnect::RbufSize, pobj));
127 fGets.Add<size_t> ("bsizemax", bind(&RlinkConnect::BlockSizeMax, pobj));
128 fGets.Add<size_t> ("bsizeprudent",
129 bind(&RlinkConnect::BlockSizePrudent, pobj));
130 fGets.Add<bool> ("hasrbmon", bind(&RlinkConnect::HasRbmon, pobj));
131
132 fSets.Add<uint32_t> ("baseaddr",
133 bind(&RlinkConnect::SetLogBaseAddr, pobj, _1));
134 fSets.Add<uint32_t> ("basedata",
135 bind(&RlinkConnect::SetLogBaseData, pobj, _1));
136 fSets.Add<uint32_t> ("basestat",
137 bind(&RlinkConnect::SetLogBaseStat, pobj, _1));
138 fSets.Add<uint32_t> ("printlevel",
139 bind(&RlinkConnect::SetPrintLevel, pobj, _1));
140 fSets.Add<uint32_t> ("dumplevel",
141 bind(&RlinkConnect::SetDumpLevel, pobj, _1));
142 fSets.Add<uint32_t> ("tracelevel",
143 bind(&RlinkConnect::SetTraceLevel, pobj, _1));
144 fSets.Add<const Rtime&> ("timeout",
145 bind(&RlinkConnect::SetTimeout, pobj, _1));
146 fSets.Add<const string&> ("logfile",
147 bind(&RlinkConnect::SetLogFileName, pobj, _1));
148
149 // attributes of buildin RlinkContext
150 RlinkContext* pcntx = &Obj().Context();
151 fGets.Add<bool> ("statchecked",
152 bind(&RlinkContext::StatusIsChecked, pcntx));
153 fGets.Add<uint8_t> ("statvalue",
154 bind(&RlinkContext::StatusValue, pcntx));
155 fGets.Add<uint8_t> ("statmask",
156 bind(&RlinkContext::StatusMask, pcntx));
157
158 fSets.Add<uint8_t> ("statvalue",
159 bind(&RlinkContext::SetStatusValue, pcntx, _1));
160 fSets.Add<uint8_t> ("statmask",
161 bind(&RlinkContext::SetStatusMask, pcntx, _1));
162}
163
164//------------------------------------------+-----------------------------------
166
168{}
169
170//------------------------------------------+-----------------------------------
172
174{
175 string path;
176
177 if (!args.GetArg("?path", path)) return kERR;
178 if (!args.AllDone()) return kERR;
179
180 RerrMsg emsg;
181 if (args.NOptMiss() == 0) { // open path
182 if (!Obj().Open(path, emsg)) return args.Quit(emsg);
183 } else { // open
184 string name = Obj().IsOpen() ? Obj().Port().Url().Url() : string();
185 args.SetResult(name);
186 }
187 return kOK;
188}
189
190//------------------------------------------+-----------------------------------
192
194{
195 if (!args.AllDone()) return kERR;
196 if (!Obj().IsOpen()) return args.Quit("-E: port not open");
197 Obj().Close();
198 return kOK;
199}
200
201//------------------------------------------+-----------------------------------
203
205{
206 if (!args.AllDone()) return kERR;
207 if (!Obj().IsOpen()) return args.Quit("-E: port not open");
208 if (Obj().LinkInitDone()) return args.Quit("-E: already initialized");
209 RerrMsg emsg;
210 if (!Obj().LinkInit(emsg)) return args.Quit(emsg);
211 return kOK;
212}
213
214//------------------------------------------+-----------------------------------
216
218{
219 static RtclNameSet optset("-rreg|-rblk|-wreg|-wblk|-labo|-attn|-init|"
220 "-edata|-edone|-estat|"
221 "-estaterr|-estatnak|-estattout|"
222 "-print|-dump|-rlist");
223
224 Tcl_Interp* interp = args.Interp();
225
226 RlinkCommandList clist;
227 string opt;
228 uint16_t addr=0;
229
230 vector<string> vardata;
231 vector<string> varstat;
232 string varprint;
233 string vardump;
234 string varlist;
235
236 while (args.NextOpt(opt, optset)) {
237
238 size_t lsize = clist.Size();
239 if (opt == "-rreg") { // -rreg addr ?varData ?varStat ---
240 if (!GetAddr(args, addr)) return kERR;
241 if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
242 if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
243 clist.AddRreg(addr);
244
245 } else if (opt == "-rblk") { // -rblk addr size ?varData ?varStat
246 int32_t bsize=0;
247 if (!GetAddr(args, addr)) return kERR;
248 if (!args.GetArg("bsize", bsize, 1, Obj().BlockSizeMax())) return kERR;
249 if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
250 if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
251 clist.AddRblk(addr, size_t(bsize));
252
253 } else if (opt == "-wreg") { // -wreg addr data ?varStat -------
254 uint16_t data=0;
255 if (!GetAddr(args, addr)) return kERR;
256 if (!args.GetArg("data", data)) return kERR;
257 if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
258 clist.AddWreg(addr, data);
259
260 } else if (opt == "-wblk") { // -wblk addr block ?varStat ------
261 vector<uint16_t> block;
262 if (!GetAddr(args, addr)) return kERR;
263 if (!args.GetArg("data", block, 1, Obj().BlockSizeMax())) return kERR;
264 if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
265 clist.AddWblk(addr, move(block));
266
267 } else if (opt == "-labo") { // -labo varData ?varStat ---------
268 if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
269 if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
270 clist.AddLabo();
271
272 } else if (opt == "-attn") { // -attn varData ?varStat ---------
273 if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
274 if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
275 clist.AddAttn();
276
277 } else if (opt == "-init") { // -init addr data ?varStat -------
278 uint16_t data=0;
279 if (!GetAddr(args, addr)) return kERR;
280 if (!args.GetArg("data", data)) return kERR;
281 if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
282 clist.AddInit(addr, data);
283
284 } else if (opt == "-edata") { // -edata data ?mask --------------
285 if (!ClistNonEmpty(args, clist)) return kERR;
286 if (clist[lsize-1].Command() == RlinkCommand::kCmdRblk) {
287 vector<uint16_t> data;
288 vector<uint16_t> mask;
289 size_t bsize = clist[lsize-1].BlockSize();
290 if (!args.GetArg("data", data, 0, bsize)) return kERR;
291 if (!args.GetArg("??mask", mask, 0, bsize)) return kERR;
292 clist.SetLastExpectBlock(move(data), move(mask));
293 } else {
294 uint16_t data=0;
295 uint16_t mask=0xffff;
296 if (!args.GetArg("data", data)) return kERR;
297 if (!args.GetArg("??mask", mask)) return kERR;
298 clist.SetLastExpectData(data, mask);
299 }
300
301 } else if (opt == "-edone") { // -edone done --------------------
302 if (!ClistNonEmpty(args, clist)) return kERR;
303 uint16_t done=0;
304 if (!args.GetArg("done", done)) return kERR;
305 uint8_t cmd = clist[lsize-1].Command();
306 if (cmd == RlinkCommand::kCmdRblk ||
307 cmd == RlinkCommand::kCmdWblk) {
308 clist.SetLastExpectDone(done);
309 } else {
310 return args.Quit("-E: -edone allowed only after -rblk,-wblk");
311 }
312
313 } else if (opt == "-estat") { // -estat stat ?mask --------------
314 if (!ClistNonEmpty(args, clist)) return kERR;
315 uint8_t stat=0;
316 uint8_t mask=0xff;
317 if (!args.GetArg("stat", stat)) return kERR;
318 if (!args.GetArg("??mask", mask)) return kERR;
319 clist.SetLastExpectStatus(stat, mask);
320
321 } else if (opt == "-estaterr" || // -estaterr ----------------------
322 opt == "-estatnak" || // -estatnak ----------------------
323 opt == "-estattout") { // -estattout ---------------------
324 if (!ClistNonEmpty(args, clist)) return kERR;
325 uint8_t val = 0;
326 uint8_t msk = RlinkCommand::kStat_M_RbTout |
329 if (opt == "-estaterr") val = RlinkCommand::kStat_M_RbErr;
330 if (opt == "-estatnak") val = RlinkCommand::kStat_M_RbNak;
331 if (opt == "-estattout") val = RlinkCommand::kStat_M_RbTout;
332 clist.SetLastExpectStatus(val, msk);
333
334 } else if (opt == "-print") { // -print ?varRes -----------------
335 varprint = "-";
336 if (!args.GetArg("??varRes", varprint)) return kERR;
337 } else if (opt == "-dump") { // -dump ?varRes ------------------
338 vardump = "-";
339 if (!args.GetArg("??varRes", vardump)) return kERR;
340 } else if (opt == "-rlist") { // -rlist ?varRes -----------------
341 varlist = "-";
342 if (!args.GetArg("??varRes", varlist)) return kERR;
343 }
344
345 } // while (args.NextOpt(opt, optset))
346
347 int nact = 0;
348 if (varprint == "-") nact += 1;
349 if (vardump == "-") nact += 1;
350 if (varlist == "-") nact += 1;
351 if (nact > 1)
352 return args.Quit(
353 "-E: more that one of -print,-dump,-rlist without target variable found");
354
355 if (!args.AllDone()) return kERR;
356 if (clist.Size() == 0) return kOK;
357
358 RerrMsg emsg;
359
360 if (!Obj().Exec(clist, emsg)) return args.Quit(emsg);
361
362 for (size_t icmd=0; icmd<clist.Size(); icmd++) {
363 RlinkCommand& cmd = clist[icmd];
364
365 if (icmd<vardata.size() && !vardata[icmd].empty()) {
366 RtclOPtr pres;
367 vector<uint16_t> retstat;
368 RtclOPtr pele;
369 switch (cmd.Command()) {
373 pres = Tcl_NewIntObj(int(cmd.Data()));
374 break;
376 pres = Rtcl::NewListIntObj(cmd.Block().data(), cmd.BlockDone());
377 break;
378 }
379 if(!Rtcl::SetVar(interp, vardata[icmd], pres)) return kERR;
380 }
381
382 if (icmd<varstat.size() && !varstat[icmd].empty()) {
383 RtclOPtr pres(Tcl_NewIntObj(int(cmd.Status())));
384 if (!Rtcl::SetVar(interp, varstat[icmd], pres)) return kERR;
385 }
386 }
387
388 if (!varprint.empty()) {
389 ostringstream sos;
390 clist.Print(sos, &Obj().AddrMap(), Obj().LogBaseAddr(),
391 Obj().LogBaseData(), Obj().LogBaseStat());
392 RtclOPtr pobj(Rtcl::NewLinesObj(sos));
393 if (!Rtcl::SetVarOrResult(args.Interp(), varprint, pobj)) return kERR;
394 }
395
396 if (!vardump.empty()) {
397 ostringstream sos;
398 clist.Dump(sos, 0);
399 RtclOPtr pobj(Rtcl::NewLinesObj(sos));
400 if (!Rtcl::SetVarOrResult(args.Interp(), vardump, pobj)) return kERR;
401 }
402
403 if (!varlist.empty()) {
404 RtclOPtr prlist(Tcl_NewListObj(0, nullptr));
405 for (size_t icmd=0; icmd<clist.Size(); icmd++) {
406 RlinkCommand& cmd(clist[icmd]);
407
408 RtclOPtr pres(Tcl_NewListObj(0, nullptr));
409 Tcl_ListObjAppendElement(nullptr, pres, fCmdnameObj[cmd.Command()]);
410 Tcl_ListObjAppendElement(nullptr, pres,
411 Tcl_NewIntObj(int(cmd.Request())));
412 Tcl_ListObjAppendElement(nullptr, pres, Tcl_NewIntObj(int(cmd.Flags())));
413 Tcl_ListObjAppendElement(nullptr, pres, Tcl_NewIntObj(int(cmd.Status())));
414
415 switch (cmd.Command()) {
419 Tcl_ListObjAppendElement(nullptr, pres,
420 Tcl_NewIntObj(int(cmd.Data())));
421 break;
422
424 Tcl_ListObjAppendElement(nullptr, pres,
426 break;
427 }
428 Tcl_ListObjAppendElement(nullptr, prlist, pres);
429 }
430 if (!Rtcl::SetVarOrResult(args.Interp(), varlist, prlist)) return kERR;
431 }
432
433 return kOK;
434}
435
436//------------------------------------------+-----------------------------------
438
440{
441 static RtclNameSet optset("-name|-testname|-testaddr|-insert|-erase|"
442 "-clear|-print");
443
444 const RlinkAddrMap& addrmap = Obj().AddrMap();
445
446 string opt;
447 string name;
448 uint16_t addr=0;
449
450 if (args.NextOpt(opt, optset)) {
451 if (opt == "-name") { // amap -name addr
452 if (!args.GetArg("addr", addr)) return kERR;
453 if (!args.AllDone()) return kERR;
454 string tstname;
455 if(addrmap.Find(addr, tstname)) {
456 args.SetResult(tstname);
457 } else {
458 return args.Quit(string("-E: address '") + args.PeekArgString(-1) +
459 "' not mapped");
460 }
461
462 } else if (opt == "-testname") { // amap -testname name ?addr
463 if (!args.GetArg("name", name)) return kERR;
464 if (!args.GetArg("?addr", addr)) return kERR;
465 if (!args.AllDone()) return kERR;
466 uint16_t tstaddr;
467 bool found = addrmap.Find(name, tstaddr);
468 if (found && args.NOptMiss()==0) { // if specified addr
469 if (tstaddr != addr) found = false; // verify addr
470 }
471 args.SetResult(int(found));
472
473 } else if (opt == "-testaddr") { // amap -testaddr addr
474 if (!args.GetArg("addr", addr)) return kERR;
475 if (!args.AllDone()) return kERR;
476 string tstname;
477 args.SetResult(int(addrmap.Find(addr, tstname)));
478
479 } else if (opt == "-insert") { // amap -insert name addr
480 uint16_t tstaddr=0;
481 string tstname;
482 int tstint=0;
483 if (!args.GetArg("name", name)) return kERR;
484 // enforce that the name is not a valid representation of an int
485 if (Tcl_GetIntFromObj(nullptr, args[args.NDone()-1], &tstint) == kOK)
486 return args.Quit(string("-E: name should not look like an int but '")+
487 name + "' does");
488 if (!args.GetArg("addr", addr)) return kERR;
489 if (!args.AllDone()) return kERR;
490 if (addrmap.Find(name, tstaddr))
491 return args.Quit(string("-E: mapping already defined for '")+name+"'");
492 if (addrmap.Find(addr, tstname))
493 return args.Quit(string("-E: mapping already defined for address '") +
494 args.PeekArgString(-1) + "'");
495 Obj().AddrMapInsert(name, addr);
496
497 } else if (opt == "-erase") { // amap -erase name
498 if (!args.GetArg("name", name)) return kERR;
499 if (!args.AllDone()) return kERR;
500 if (!Obj().AddrMapErase(name))
501 return args.Quit(string("-E: no mapping defined for '") + name + "'");
502
503 } else if (opt == "-clear") { // amap -clear
504 if (!args.AllDone()) return kERR;
505 Obj().AddrMapClear();
506
507 } else if (opt == "-print") { // amap -print
508 if (!args.AllDone()) return kERR;
509 ostringstream sos;
510 addrmap.Print(sos);
511 args.AppendResultLines(sos);
512 }
513
514 } else {
515 if (!args.OptValid()) return kERR;
516 if (!args.GetArg("?name", name)) return kERR;
517 if (args.NOptMiss()==0) { // amap name
518 uint16_t tstaddr=0;
519 if(addrmap.Find(name, tstaddr)) {
520 args.SetResult(int(tstaddr));
521 } else {
522 return args.Quit(string("-E: no mapping defined for '") + name + "'");
523 }
524
525 } else { // amap
526 RtclOPtr plist(Tcl_NewListObj(0, nullptr));
527 const auto amap = addrmap.Amap();
528 for (auto& o: amap) {
529 Tcl_Obj* tpair[2];
530 tpair[0] = Tcl_NewIntObj(o.first);
531 tpair[1] = Tcl_NewStringObj(o.second.c_str(),o.second.length());
532 Tcl_ListObjAppendElement(nullptr, plist, Tcl_NewListObj(2, tpair));
533 }
534 args.SetResult(plist);
535 }
536 }
537
538 return kOK;
539}
540
541//------------------------------------------+-----------------------------------
543
545{
546 static RtclNameSet optset("-clear|-increment");
547 string opt;
548 bool fclr = false;
549 bool finc = false;
550
551 while (args.NextOpt(opt, optset)) {
552 if (opt == "-clear") fclr = true;
553 if (opt == "-increment") finc = true;
554 }
555 if (!args.AllDone()) return kERR;
556
557 if (finc) Obj().Context().IncErrorCount();
558 args.SetResult(int(Obj().Context().ErrorCount()));
559 if (fclr) Obj().Context().ClearErrorCount();
560
561 return kOK;
562}
563
564//------------------------------------------+-----------------------------------
566
568{
569 double dtout;
570 string rvn_apat;
571 if (!args.GetArg("tout", dtout, 0.0)) return kERR;
572 if (!args.GetArg("??varApat", rvn_apat)) return kERR;
573 if (!args.AllDone()) return kERR;
574
575 RerrMsg emsg;
576 uint16_t apat = 0;
577 Rtime twait;
578
579 int irc = Obj().WaitAttn(Rtime(dtout), twait, apat, emsg);
580
581 if (rvn_apat.length()) {
582 if(!Rtcl::SetVar(args.Interp(), rvn_apat,
583 Tcl_NewIntObj(int(apat)))) return kERR;
584 }
585
586 if (irc == -2) { // IO error
587 return args.Quit(emsg);
588 } else if (irc == -1) { // timeout
589 if (Obj().PrintLevel() >= 1) {
590 RlogMsg lmsg(Obj().LogFile());
591 lmsg << "-- wtlam to=" << RosPrintf(dtout, "f", 0,3)
592 << " FAIL timeout" << endl;
594 args.SetResult(dtout);
595 return kOK;
596 }
597 }
598
599 if (Obj().PrintLevel() >= 3) {
600 RlogMsg lmsg(Obj().LogFile());
601 lmsg << "-- wtlam apat=" << RosPrintf(apat,"x0",4);
602 if (dtout == 0.) {
603 lmsg << " to=0 harvest only";
604 } else {
605 lmsg << " to=" << RosPrintf(dtout, "f", 0,3)
606 << " T=" << RosPrintf(double(twait), "f", 0,3);
607 }
608 lmsg << " OK" << endl;
609 }
610
611 args.SetResult(double(twait));
612 return kOK;
613}
614
615//------------------------------------------+-----------------------------------
617
619{
620 static RtclNameSet optset("-rlmon|-rlbmon|-rbmon|-sbcntl|-sbdata");
621
622 string opt;
623 uint16_t addr=0;
624 uint16_t data=0;
625 RerrMsg emsg;
626
627 if (args.NextOpt(opt, optset)) {
628 if (opt == "-rlmon") { // oob -rlmon (0|1)
629 if (!args.GetArg("val", data, 1)) return kERR;
630 if (!args.AllDone()) return kERR;
631 addr = RlinkConnect:: kSBCNTL_V_RLMON; // rlmon enable bit
632 if (!Obj().SndOob(0x00, (addr<<8)+data, emsg)) return args.Quit(emsg);
633
634 } else if (opt == "-rlbmon") { // oob -rlbmon (0|1)
635 if (!args.GetArg("val", data, 1)) return kERR;
636 if (!args.AllDone()) return kERR;
637 addr = RlinkConnect:: kSBCNTL_V_RLBMON; // rlbmon enable bit
638 if (!Obj().SndOob(0x00, (addr<<8)+data, emsg)) return args.Quit(emsg);
639
640 } else if (opt == "-rbmon") { // oob -rbmon (0|1)
641 if (!args.GetArg("val", data, 1)) return kERR;
642 if (!args.AllDone()) return kERR;
643 addr = RlinkConnect:: kSBCNTL_V_RBMON; // rbmon enable bit
644 if (!Obj().SndOob(0x00, (addr<<8)+data, emsg)) return args.Quit(emsg);
645
646 } else if (opt == "-sbcntl") { // oob -sbcntl bit (0|1)
647 if (!args.GetArg("bit", addr, 15)) return kERR;
648 if (!args.GetArg("val", data, 1)) return kERR;
649 if (!args.AllDone()) return kERR;
650 if (!Obj().SndOob(0x00, (addr<<8)+data, emsg)) return args.Quit(emsg);
651
652 } else if (opt == "-sbdata") { // oob -sbdata addr val
653 if (!args.GetArg("bit", addr, 0x0ff)) return kERR;
654 if (!args.GetArg("val", data)) return kERR;
655 if (!args.AllDone()) return kERR;
656 if (!Obj().SndOob(addr, data, emsg)) return args.Quit(emsg);
657 }
658 } else {
659 return args.Quit(
660 "-E: missing option, one of -rlmon,-rbmon,-sbcntl,-sbdata");
661 }
662
663 return kOK;
664}
665
666//------------------------------------------+-----------------------------------
668
670{
671 if (!(Obj().HasPort() &&
672 Obj().Port().IsOpen())) return args.Quit("-E: port not open");
673 return RtclRlinkPort::DoRawRead(args, Obj().Port());
674}
675
676//------------------------------------------+-----------------------------------
678
680{
681 if (!(Obj().HasPort() &&
682 Obj().Port().IsOpen())) return args.Quit("-E: port not open");
683 size_t errcnt = 0;
684 int rc = RtclRlinkPort::DoRawRblk(args, Obj().Port(), errcnt);
685 Obj().Context().IncErrorCount(errcnt);
686 return rc;
687}
688
689//------------------------------------------+-----------------------------------
691
693{
694 if (!(Obj().HasPort() &&
695 Obj().Port().IsOpen())) return args.Quit("-E: port not open");
696 return RtclRlinkPort::DoRawWblk(args, Obj().Port());
697}
698
699//------------------------------------------+-----------------------------------
701
703{
705 if (!RtclStats::GetArgs(args, cntx)) return kERR;
706 if (!RtclStats::Exec(args, cntx, Obj().Stats())) return kERR;
707 if (!RtclStats::Exec(args, cntx, Obj().SndStats())) return kERR;
708 if (!RtclStats::Exec(args, cntx, Obj().RcvStats())) return kERR;
709 if (Obj().HasPort()) {
710 if (!RtclStats::Exec(args, cntx, Obj().Port().Stats())) return kERR;
711 }
712 return kOK;
713}
714
715//------------------------------------------+-----------------------------------
717
719{
720 static RtclNameSet optset("-bare|-info|-warn|-error|-fatal");
721 string opt;
722 bool fbare = false;
723 char tag = 0;
724 while (args.NextOpt(opt, optset)) {
725 if (opt == "-bare") fbare = true;
726 if (opt == "-info") tag = 'I';
727 if (opt == "-warn") tag = 'W';
728 if (opt == "-error") tag = 'E';
729 if (opt == "-fatal") tag = 'F';
730 }
731 if (!args.OptValid()) return kERR;
732
733 string msg;
734 if (!args.GetArg("msg", msg)) return kERR;
735 if (!args.AllDone()) return kERR;
736 if (Obj().PrintLevel() != 0 ||
737 Obj().DumpLevel() != 0 ||
738 Obj().TraceLevel() != 0) {
739 if (tag || fbare) {
740 Obj().LogFile().Write(msg, tag);
741 } else {
742 Obj().LogFile().Write(string("# ") + msg);
743 }
744 }
745 return kOK;
746}
747
748//------------------------------------------+-----------------------------------
750
752{
753 if (!args.AllDone()) return kERR;
754
755 ostringstream sos;
756 Obj().Print(sos);
757 args.SetResult(sos);
758 return kOK;
759}
760
761//------------------------------------------+-----------------------------------
763
765{
766 int detail=0;
767 if (!GetArgsDump(args, detail)) return kERR;
768 if (!args.AllDone()) return kERR;
769
770 ostringstream sos;
771 Obj().Dump(sos, 0, "", detail);
772 args.SetResult(sos);
773 return kOK;
774}
775
776//------------------------------------------+-----------------------------------
778
780{
781 // synchronize with server thread (really needed ??)
782 lock_guard<RlinkConnect> lock(Obj());
783 return fGets.M_get(args);
784}
785
786//------------------------------------------+-----------------------------------
788
790{
791 // synchronize with server thread (really needed ??)
792 lock_guard<RlinkConnect> lock(Obj());
793 return fSets.M_set(args);
794}
795
796//------------------------------------------+-----------------------------------
798
800{
801 if (!args.AllDone()) return kERR;
802 ostringstream sos;
803
804 sos << "print base: " << "addr " << RosPrintf(Obj().LogBaseAddr(), "d", 2)
805 << " data " << RosPrintf(Obj().LogBaseData(), "d", 2)
806 << " stat " << RosPrintf(Obj().LogBaseStat(), "d", 2) << endl;
807 sos << "logfile: " << Obj().LogFile().Name()
808 << " printlevel " << Obj().PrintLevel()
809 << " dumplevel " << Obj().DumpLevel();
810
811 args.AppendResultLines(sos);
812 return kOK;
813}
814
815//------------------------------------------+-----------------------------------
817
818bool RtclRlinkConnect::GetAddr(RtclArgs& args, uint16_t& addr)
819{
820 Tcl_Obj* pobj=0;
821 if (!args.GetArg("addr", pobj)) return kERR;
822
823 int tstint=0;
824 // if a number is given..
825 if (Tcl_GetIntFromObj(nullptr, pobj, &tstint) == kOK) {
826 if (tstint >= 0 && tstint <= 0xffff) {
827 addr = uint16_t(tstint);
828 } else {
829 args.AppendResult("-E: value '", Tcl_GetString(pobj),
830 "' for 'addr' out of range 0...0xffff", nullptr);
831 return false;
832 }
833 // if a name is given
834 } else {
835 string name(Tcl_GetString(pobj));
836 uint16_t tstaddr=0;
837 if (Obj().AddrMap().Find(name, tstaddr)) {
838 addr = tstaddr;
839 } else {
840 args.AppendResult("-E: no address mapping known for '",
841 Tcl_GetString(pobj), "'", nullptr);
842 return false;
843 }
844 }
845
846 return true;
847}
848
849//------------------------------------------+-----------------------------------
851
852bool RtclRlinkConnect::GetVarName(RtclArgs& args, const char* argname,
853 size_t nind,
854 std::vector<std::string>& varname)
855{
856 while (varname.size() < nind+1) varname.push_back(string());
857 string name;
858 if (!args.GetArg(argname, name)) return false;
859 if (name.length()) { // if variable defined
860 char c = name[0];
861 if (isdigit(c) || c=='+' || c=='-' ) { // check for mistaken number
862 args.AppendResult("-E: invalid variable name '", name.c_str(),
863 "': looks like a number", nullptr);
864 return false;
865 }
866 }
867
868 varname[nind] = name;
869 return true;
870}
871
872//------------------------------------------+-----------------------------------
874
875bool RtclRlinkConnect::ConfigBase(RtclArgs& args, uint32_t& base)
876{
877 uint32_t tmp = base;
878 if (!args.Config("??base", tmp, 16, 2)) return false;
879 if (tmp != base && tmp != 2 && tmp !=8 && tmp != 16) {
880 args.AppendResult("-E: base must be 2, 8, or 16, found '",
881 args.PeekArgString(-1), "'", nullptr);
882 return false;
883 }
884 base = tmp;
885 return true;
886}
887
888//------------------------------------------+-----------------------------------
890
892 const RlinkCommandList& clist)
893{
894 if (clist.Size() == 0) {
895 args.AppendResult("-E: -edata, -edone, or -estat "
896 "not allowed on empty command list", nullptr);
897 return false;
898 }
899 return true;
900}
901
902} // end namespace Retro
FIXME_docs.
Definition: RerrMsg.hpp:25
const amap_t & Amap() const
FIXME_docs.
bool Find(const std::string &name, uint16_t &addr) const
FIXME_docs.
void Print(std::ostream &os, int ind=0) const
FIXME_docs.
size_t AddWreg(uint16_t addr, uint16_t data)
FIXME_docs.
size_t AddAttn()
FIXME_docs.
size_t Size() const
FIXME_docs.
size_t AddInit(uint16_t addr, uint16_t data)
FIXME_docs.
size_t AddRblk(uint16_t addr, size_t size)
FIXME_docs.
void SetLastExpectStatus(uint8_t stat, uint8_t statmsk=0xff)
FIXME_docs.
void SetLastExpectBlock(const std::vector< uint16_t > &block)
FIXME_docs.
void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
size_t AddWblk(uint16_t addr, const std::vector< uint16_t > &block)
FIXME_docs.
size_t AddRreg(uint16_t addr)
FIXME_docs.
void Print(std::ostream &os, const RlinkAddrMap *pamap=0, size_t abase=16, size_t dbase=16, size_t sbase=16) const
FIXME_docs.
void SetLastExpectDone(uint16_t done)
FIXME_docs.
void SetLastExpectData(uint16_t data, uint16_t datamsk=0xffff)
FIXME_docs.
size_t AddLabo()
FIXME_docs.
uint16_t Data() const
FIXME_docs.
uint8_t Request() const
FIXME_docs.
static const uint8_t kCmdRblk
command code read block
static const uint8_t kStat_M_RbErr
stat: rberr flag set
uint8_t Status() const
FIXME_docs.
static const char * CommandName(uint8_t cmd)
FIXME_docs.
const std::vector< uint16_t > & Block() const
FIXME_docs.
static const uint8_t kStat_M_RbNak
stat: rbnak flag set
static const uint8_t kStat_M_RbTout
stat: rbtout flag set
uint8_t Command() const
FIXME_docs.
static const uint8_t kCmdRreg
command code read register
uint32_t Flags() const
FIXME_docs.
size_t BlockDone() const
FIXME_docs.
static const uint8_t kCmdAttn
command code get attention
static const uint8_t kCmdLabo
command code list abort
static const uint8_t kCmdWblk
command code write block
void SetTimeout(const Rtime &timeout)
FIXME_docs.
void AddrMapClear()
FIXME_docs.
int WaitAttn(const Rtime &timeout, Rtime &twait, uint16_t &apat, RerrMsg &emsg)
Wait for an attention notify.
void SetLogFileName(const std::string &name)
FIXME_docs.
uint32_t LogBaseData() const
FIXME_docs.
void Close()
FIXME_docs.
void SetLogBaseAddr(uint32_t base)
FIXME_docs.
uint32_t LogBaseAddr() const
FIXME_docs.
bool AddrMapInsert(const std::string &name, uint16_t addr)
FIXME_docs.
static const uint16_t kSBCNTL_V_RLMON
SBCNTL: rlmon enable bit.
uint32_t SysId() const
FIXME_docs.
void SetLogBaseStat(uint32_t base)
FIXME_docs.
uint32_t PrintLevel() const
FIXME_docs.
size_t RbufSize() const
FIXME_docs.
const Rtime & Timeout() const
FIXME_docs.
void SetDumpLevel(uint32_t lvl)
FIXME_docs.
RlogFile & LogFile() const
FIXME_docs.
uint32_t LogBaseStat() const
FIXME_docs.
void Print(std::ostream &os) const
FIXME_docs.
RlinkContext & Context()
FIXME_docs.
static const uint16_t kSBCNTL_V_RLBMON
SBCNTL: rlbmon enable bit.
static const uint16_t kSBCNTL_V_RBMON
SBCNTL: rbmon enable bit.
size_t BlockSizeMax() const
FIXME_docs.
bool IsOpen() const
FIXME_docs.
uint32_t DumpLevel() const
FIXME_docs.
void SetLogBaseData(uint32_t base)
FIXME_docs.
uint32_t TraceLevel() const
FIXME_docs.
RlinkPort & Port()
FIXME_docs.
void SetPrintLevel(uint32_t lvl)
FIXME_docs.
void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
size_t BlockSizePrudent() const
FIXME_docs.
bool HasRbmon() const
FIXME_docs.
uint32_t UsrAcc() const
FIXME_docs.
const RlinkAddrMap & AddrMap() const
FIXME_docs.
void SetTraceLevel(uint32_t lvl)
FIXME_docs.
bool LinkInitDone() const
FIXME_docs.
const std::string & LogFileName() const
FIXME_docs.
void SetStatusMask(uint8_t statmsk)
FIXME_docs.
void IncErrorCount(size_t inc=1)
FIXME_docs.
uint8_t StatusValue() const
FIXME_docs.
bool StatusIsChecked() const
FIXME_docs.
void ClearErrorCount()
FIXME_docs.
uint8_t StatusMask() const
FIXME_docs.
void SetStatusValue(uint8_t stat)
FIXME_docs.
const RparseUrl & Url() const
FIXME_docs.
Definition: RlinkPort.ipp:35
const std::string & Name() const
FIXME_docs.
Definition: RlogFile.ipp:30
void Write(const std::string &str, char tag=0)
FIXME_docs.
Definition: RlogFile.cpp:125
FIXME_docs.
Definition: RlogMsg.hpp:24
const std::string & Url() const
FIXME_docs.
Definition: RparseUrl.ipp:29
FIXME_docs.
Definition: RtclArgs.hpp:41
bool NextOpt(std::string &val)
FIXME_docs.
Definition: RtclArgs.cpp:368
const char * PeekArgString(int rind) const
FIXME_docs.
Definition: RtclArgs.cpp:461
void AppendResultLines(const std::string &str)
FIXME_docs.
Definition: RtclArgs.cpp:484
bool GetArg(const char *name, Tcl_Obj *&pval)
FIXME_docs.
Definition: RtclArgs.cpp:114
bool Config(const char *name, std::string &val)
FIXME_docs.
Definition: RtclArgs.cpp:333
void AppendResult(const char *str,...)
FIXME_docs.
Definition: RtclArgs.cpp:471
bool OptValid() const
FIXME_docs.
Definition: RtclArgs.ipp:52
int Quit(const std::string &str)
FIXME_docs.
Definition: RtclArgs.ipp:157
void SetResult(const std::string &str)
FIXME_docs.
Definition: RtclArgs.ipp:76
size_t NOptMiss() const
FIXME_docs.
Definition: RtclArgs.ipp:68
size_t NDone() const
FIXME_docs.
Definition: RtclArgs.ipp:60
Tcl_Interp * Interp() const
FIXME_docs.
Definition: RtclArgs.ipp:28
bool AllDone()
FIXME_docs.
Definition: RtclArgs.cpp:447
void AddMeth(const std::string &name, methfo_t &&methfo)
FIXME_docs.
bool GetArgsDump(RtclArgs &args, int &detail)
FIXME_docs.
int M_get(RtclArgs &args)
FIXME_docs.
Definition: RtclGetList.cpp:73
void Add(const std::string &name, get_uptr_t &&upget)
FIXME_docs.
Definition: RtclGetList.cpp:52
Implemenation (inline) of RtclOPtr.
Definition: RtclOPtr.hpp:23
Implemenation (all inline) of class RtclProxyOwned.
RlinkConnect & Obj()
FIXME_docs.
int M_set(RtclArgs &args)
FIXME_docs.
int M_print(RtclArgs &args)
FIXME_docs.
int M_wtlam(RtclArgs &args)
FIXME_docs.
bool GetAddr(RtclArgs &args, uint16_t &addr)
FIXME_docs.
int M_close(RtclArgs &args)
FIXME_docs.
int M_open(RtclArgs &args)
FIXME_docs.
int M_rawrblk(RtclArgs &args)
FIXME_docs.
int M_exec(RtclArgs &args)
FIXME_docs.
bool ConfigBase(RtclArgs &args, uint32_t &base)
FIXME_docs.
int M_dump(RtclArgs &args)
FIXME_docs.
int M_oob(RtclArgs &args)
FIXME_docs.
RtclRlinkConnect(Tcl_Interp *interp, const char *name)
Default constructor.
bool ClistNonEmpty(RtclArgs &args, const RlinkCommandList &clist)
FIXME_docs.
int M_log(RtclArgs &args)
FIXME_docs.
bool GetVarName(RtclArgs &args, const char *argname, size_t nind, std::vector< std::string > &varname)
FIXME_docs.
int M_get(RtclArgs &args)
FIXME_docs.
int M_rawwblk(RtclArgs &args)
FIXME_docs.
int M_init(RtclArgs &args)
FIXME_docs.
int M_default(RtclArgs &args)
FIXME_docs.
int M_stats(RtclArgs &args)
FIXME_docs.
int M_rawread(RtclArgs &args)
FIXME_docs.
int M_errcnt(RtclArgs &args)
FIXME_docs.
int M_amap(RtclArgs &args)
FIXME_docs.
static int DoRawWblk(RtclArgs &args, RlinkPort &port)
FIXME_docs.
static int DoRawRblk(RtclArgs &args, RlinkPort &port, size_t &errcnt)
FIXME_docs.
static int DoRawRead(RtclArgs &args, RlinkPort &port)
FIXME_docs.
void Add(const std::string &name, set_uptr_t &&upset)
FIXME_docs.
Definition: RtclSetList.cpp:52
int M_set(RtclArgs &args)
FIXME_docs.
Definition: RtclSetList.cpp:73
static bool Exec(RtclArgs &args, const Context &cntx, Rstats &stats)
FIXME_docs.
Definition: RtclStats.cpp:75
static bool GetArgs(RtclArgs &args, Context &cntx)
FIXME_docs.
Definition: RtclStats.cpp:37
FIXME_docs.
Definition: Rtime.hpp:25
RosPrintfS< bool > RosPrintf(bool value, const char *form=0, int width=0, int prec=0)
Creates a print object for the formatted output of a bool value.
Definition: RosPrintf.ipp:38
bool SetVarOrResult(Tcl_Interp *interp, const std::string &varname, Tcl_Obj *pobj)
Tcl_Obj * NewLinesObj(const std::string &str)
bool SetVar(Tcl_Interp *interp, const std::string &varname, Tcl_Obj *pobj)
Tcl_Obj * NewListIntObj(const uint8_t *data, size_t size)
Declaration of class ReventLoop.
Definition: ReventLoop.cpp:47
static const int kERR
Definition: RtclBvi.cpp:38
static const int kOK
Definition: RtclBvi.cpp:37