00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <algorithm>
00026 #include <fstream>
00027 #include <sstream>
00028 #include <stdlib.h>
00029 #include "helper.h"
00030 #include "traceval.h"
00031 #include "avrerror.h"
00032 #include "systemclock.h"
00033
00034 using namespace std;
00035
00036 TraceValue::TraceValue(size_t bits,
00037 const std::string &__name,
00038 const int __index,
00039 void *_shadow) :
00040 b(bits),
00041 _name(__name),
00042 _index(__index),
00043 shadow(_shadow),
00044 v(0xaffeaffe),
00045 f(0),
00046 _written(false),
00047 _enabled(false) {}
00048
00049 size_t TraceValue::bits() const { return b; }
00050
00051 std::string TraceValue::name() const {
00052 if (index()>=0)
00053 return _name+int2str(index());
00054 else return _name;
00055 }
00056
00057 std::string TraceValue::barename() const { return _name; }
00058
00059 int TraceValue::index() const { return _index; }
00060
00061 unsigned TraceValue::value() const { return v; }
00062
00063 bool TraceValue::enabled() const { return _enabled; }
00064
00065 void TraceValue::enable() { _enabled=true; }
00066
00067 void TraceValue::change(unsigned val) {
00068
00069 if ((v != val) || !_written) {
00070 f |= CHANGE;
00071 v = val;
00072 }
00073 }
00074
00075 void TraceValue::change(unsigned val, unsigned mask) {
00076
00077 if (((v & mask) != (val & mask)) || !_written) {
00078 f |= CHANGE;
00079 v = (v & ~mask) | (val & mask);
00080 }
00081 }
00082
00083 void TraceValue::write(unsigned val) {
00084 if ((v != val) || !_written) {
00085 f |= CHANGE;
00086 v = val;
00087 }
00088 f |= WRITE;
00089 _written = true;
00090 }
00091
00092 void TraceValue::read() {
00093 f |= READ;
00094 }
00095
00096 bool TraceValue::written() const { return _written; }
00097
00098 void TraceValue::set_written() {
00099 _written=true;
00100 }
00101
00102 void TraceValue::set_written(unsigned val) {
00103 _written=true;
00104 v = val;
00105 }
00106
00107 TraceValue::Atype TraceValue::flags() const { return (Atype)f; }
00108
00109 void TraceValue::cycle() {
00110 if (shadow) {
00111 unsigned nv;
00112 switch (b) {
00113 case 1:
00114 nv=*(bool*)shadow; break;
00115 case 8:
00116 nv=*(uint8_t*)shadow; break;
00117 case 16:
00118 nv=*(uint16_t*)shadow; break;
00119 case 32:
00120 nv=*(uint32_t*)shadow; break;
00121 default:
00122 avr_error("Internal error: Unsupported number of bits in TraceValue::cycle().");
00123 }
00124 if (v!=nv) {
00125 f|=CHANGE;
00126 _written=true;
00127 v=nv;
00128 }
00129 }
00130 }
00131
00132 void TraceValue::dump(Dumper &d) {
00133 if (f&READ) {
00134 d.markRead(this);
00135 if (!_written)
00136 d.markReadUnknown(this);
00137 }
00138 if (f&WRITE) {
00139 d.markWrite(this);
00140 }
00141 if (f&CHANGE) {
00142 d.markChange(this);
00143 }
00144 f=0;
00145 }
00146
00147 TraceValueRegister::~TraceValueRegister() {
00148 for (valmap_t::iterator i = _tvr_values.begin(); i != _tvr_values.end(); i++)
00149 delete i->first;
00150 _tvr_values.clear();
00151 for (regmap_t::iterator i = _tvr_registers.begin(); i != _tvr_registers.end(); i++)
00152 delete i->first;
00153 _tvr_registers.clear();
00154 }
00155
00156 void TraceValueRegister::_tvr_registerTraceValues(TraceValueRegister *r) {
00157 string n = r->GetScopeName();
00158 if(GetScopeGroupByName(n) == NULL) {
00159 string *s = new string(n);
00160 pair<string*, TraceValueRegister*> v(s, r);
00161 _tvr_registers.insert(v);
00162 } else
00163 avr_error("duplicate name '%s', another TraceValueRegister child is already registered", n.c_str());
00164 }
00165
00166 size_t TraceValueRegister::_tvr_getValuesCount(void) {
00167 size_t cnt = _tvr_values.size();
00168 for (regmap_t::iterator i = _tvr_registers.begin(); i != _tvr_registers.end(); i++)
00169 cnt += (i->second)->_tvr_getValuesCount();
00170 return cnt;
00171 }
00172
00173 void TraceValueRegister::_tvr_insertTraceValuesToSet(TraceSet &t) {
00174 for (valmap_t::iterator i = _tvr_values.begin(); i != _tvr_values.end(); i++)
00175 t.push_back(i->second);
00176 for (regmap_t::iterator i = _tvr_registers.begin(); i != _tvr_registers.end(); i++)
00177 (i->second)->_tvr_insertTraceValuesToSet(t);
00178 }
00179
00180 void TraceValueRegister::RegisterTraceValue(TraceValue *t) {
00181
00182 string p = t->name();
00183 int idx = _tvr_scopeprefix.length();
00184 if((p.length() <= idx) || (p.substr(0, idx) != _tvr_scopeprefix))
00185 avr_error("add TraceValue denied: wrong prefix: '%s', scope is '%s'",
00186 p.c_str(), _tvr_scopeprefix.c_str());
00187 string n = p.substr(idx);
00188 if(n.find('.') != -1)
00189 avr_error("add TraceValue denied: wrong name: '%s', scope is '%s'",
00190 n.c_str(), _tvr_scopeprefix.c_str());
00191
00192 if(GetTraceValueByName(n) == NULL) {
00193 string *s = new string(n);
00194 pair<string*, TraceValue*> v(s, t);
00195 _tvr_values.insert(v);
00196 } else
00197 avr_error("add TraceValue denied: name found: '%s'", n.c_str());
00198 }
00199
00200 void TraceValueRegister::UnregisterTraceValue(TraceValue *t) {
00201 int idx = _tvr_scopeprefix.length();
00202 string n = t->name().substr(idx);
00203 for (valmap_t::iterator i = _tvr_values.begin(); i != _tvr_values.end(); i++) {
00204 if(n == *(i->first)) {
00205 _tvr_values.erase(i);
00206 break;
00207 }
00208 }
00209 }
00210
00211 TraceValueRegister* TraceValueRegister::GetScopeGroupByName(const std::string &name) {
00212 for (regmap_t::iterator i = _tvr_registers.begin(); i != _tvr_registers.end(); i++) {
00213 if(name == *(i->first))
00214 return i->second;
00215 }
00216 return NULL;
00217 }
00218
00219 TraceValue* TraceValueRegister::GetTraceValueByName(const std::string &name) {
00220 for (valmap_t::iterator i = _tvr_values.begin(); i != _tvr_values.end(); i++) {
00221 if(name == *(i->first))
00222 return i->second;
00223 }
00224 return NULL;
00225 }
00226
00227 TraceValueRegister* TraceValueRegister::FindScopeGroupByName(const std::string &name) {
00228 int idx = name.find('.');
00229 if(idx > 0) {
00230 TraceValueRegister *r = GetScopeGroupByName(name.substr(0, idx));
00231 if(r == NULL)
00232 return NULL;
00233 else
00234 return r->FindScopeGroupByName(name.substr(idx + 1));
00235 } else
00236 return GetScopeGroupByName(name);
00237 }
00238
00239 TraceValue* TraceValueRegister::FindTraceValueByName(const std::string &name) {
00240 int idx = name.find('.');
00241 if(idx > 0) {
00242 TraceValueRegister *r = GetScopeGroupByName(name.substr(0, idx));
00243 if(r == NULL)
00244 return NULL;
00245 else
00246 return r->FindTraceValueByName(name.substr(idx + 1));
00247 } else
00248 return GetTraceValueByName(name);
00249 }
00250
00251 TraceSet* TraceValueRegister::GetAllTraceValues(void) {
00252 TraceSet* result = new TraceSet;
00253 result->reserve(_tvr_values.size());
00254 for (valmap_t::iterator i = _tvr_values.begin(); i != _tvr_values.end(); i++)
00255 result->push_back(i->second);
00256 return result;
00257 }
00258
00259 TraceSet* TraceValueRegister::GetAllTraceValuesRecursive(void) {
00260 TraceSet* result = new TraceSet;
00261 result->reserve(_tvr_getValuesCount());
00262 _tvr_insertTraceValuesToSet(*result);
00263 return result;
00264 }
00265
00266 TraceValueCoreRegister::TraceValueCoreRegister(TraceValueRegister *parent):
00267 TraceValueRegister(parent, "CORE") {}
00268
00269 void TraceValueCoreRegister::RegisterTraceSetValue(TraceValue *t, const std::string &name, const size_t size) {
00270
00271 TraceSet *set = NULL;
00272 for(setmap_t::iterator i = _tvr_valset.begin(); i != _tvr_valset.end(); i++) {
00273 if(name == *(i->first)) {
00274 set = i->second;
00275 break;
00276 }
00277 }
00278
00279 if(set == NULL) {
00280 set = new TraceSet(size, NULL);
00281 string *s = new string(name);
00282 pair<string*, TraceSet*> v(s, set);
00283 _tvr_valset.insert(v);
00284 }
00285
00286 (*set)[t->index()] = t;
00287 }
00288
00289 TraceValue* TraceValueCoreRegister::GetTraceValueByName(const std::string &name) {
00290 TraceValue *res = TraceValueRegister::GetTraceValueByName(name);
00291 if(res == NULL) {
00292 int idx = _tvr_numberindex(name);
00293 if(idx != -1) {
00294
00295 string n = name.substr(0, idx);
00296 int v = atoi(name.substr(idx).c_str());
00297 for(setmap_t::iterator i = _tvr_valset.begin(); i != _tvr_valset.end(); i++) {
00298 if(n == *(i->first)) {
00299 TraceSet *set = i->second;
00300 if(v < set->size())
00301 res = (*set)[v];
00302 break;
00303 }
00304 }
00305 }
00306 }
00307 return res;
00308 }
00309
00310 TraceValueCoreRegister::~TraceValueCoreRegister() {
00311 for(setmap_t::iterator i = _tvr_valset.begin(); i != _tvr_valset.end(); i++)
00312 delete i->second;
00313 }
00314
00315 size_t TraceValueCoreRegister::_tvr_getValuesCount(void) {
00316 size_t cnt = TraceValueRegister::_tvr_getValuesCount();
00317
00318 for(setmap_t::iterator i = _tvr_valset.begin(); i != _tvr_valset.end(); i++)
00319 cnt += i->second->size();
00320 return cnt;
00321 }
00322
00323 void TraceValueCoreRegister::_tvr_insertTraceValuesToSet(TraceSet &t) {
00324 TraceValueRegister::_tvr_insertTraceValuesToSet(t);
00325
00326 for(setmap_t::iterator i = _tvr_valset.begin(); i != _tvr_valset.end(); i++) {
00327 TraceSet* s = i->second;
00328 for(TraceSet::iterator j = s->begin(); j != s->end(); j++)
00329 t.push_back(*j);
00330 }
00331 }
00332
00333 int TraceValueCoreRegister::_tvr_numberindex(const std::string &str) {
00334 int l = str.size();
00335 int i = l - 1;
00336
00337 for(; i >= 0; i--) {
00338 char c = str[i];
00339
00340 if(c < '0' || c > '9') {
00341 i++;
00342 break;
00343 }
00344 }
00345 if(i == l)
00346 i = -1;
00347 return i;
00348 }
00349
00350 WarnUnknown::WarnUnknown(AvrDevice *_core) : core(_core) {}
00351
00352 void WarnUnknown::markReadUnknown(const TraceValue *t) {
00353 cerr << "READ-before-WRITE for value " << t->name()
00354 << " at time " << SystemClock::Instance().GetCurrentTime()
00355 << ", PC=0x" << hex << 2*core->PC << dec << endl;
00356 }
00357 bool WarnUnknown::enabled(const TraceValue *t) const {
00358 return true;
00359 }
00360
00361 void DumpVCD::valout(const TraceValue *v) {
00362 osbuffer << 'b';
00363 if (v->written()) {
00364 unsigned val=v->value();
00365 for (int i=v->bits()-1; i>=0; i--)
00366 osbuffer << ((val&(1<<i)) ? '1' : '0');
00367 } else {
00368 for (int i=0; i < v->bits(); i++)
00369 osbuffer << 'x';
00370 }
00371 }
00372
00373 void DumpVCD::flushbuffer(void) {
00374 if(changesWritten) {
00375 *os << osbuffer.str();
00376 changesWritten = false;
00377 }
00378 osbuffer.str("");
00379 }
00380
00381 DumpVCD::DumpVCD(ostream *_os,
00382 const std::string &_tscale,
00383 const bool rstrobes,
00384 const bool wstrobes) :
00385 os(_os),
00386 tscale(_tscale),
00387 rs(rstrobes),
00388 ws(wstrobes),
00389 changesWritten(false) {}
00390
00391 DumpVCD::DumpVCD(const std::string &_name,
00392 const std::string &_tscale,
00393 const bool rstrobes,
00394 const bool wstrobes) :
00395 os(new ofstream(_name.c_str())),
00396 tscale(_tscale),
00397 rs(rstrobes),
00398 ws(wstrobes),
00399 changesWritten(false) {}
00400
00401 void DumpVCD::setActiveSignals(const TraceSet &act) {
00402 tv=act;
00403 unsigned n=0;
00404 for (TraceSet::const_iterator i=act.begin();
00405 i!=act.end(); i++) {
00406 if (id2num.find(*i)!=id2num.end())
00407 avr_error("Trace value would be twice in VCD list.");
00408 id2num[*i]=n++;
00409 }
00410 }
00411
00412 void DumpVCD::start() {
00413 *os <<
00414 "$version\n"
00415 "\tSimulavr VCD dump file generator\n"
00416 "$end\n";
00417
00418 *os << "$timescale 1" << tscale << " $end\n";
00419 typedef TraceSet::iterator iter;
00420 unsigned n=0;
00421 for (iter i=tv.begin();
00422 i!=tv.end(); i++) {
00423 string s=(*i)->name();
00424
00425
00426
00427 int ld;
00428 for (ld=s.size()-1; ld>0; ld--)
00429 if (s[ld]=='.') break;
00430
00431 *os << "$scope module " << s.substr(0, ld) << " $end\n";
00432 *os << "$var wire " << (*i)->bits() << ' ' << n*(1+rs+ws) << ' ' << s.substr(ld+1, s.size()-1) << " $end\n";
00433 if (rs)
00434 *os << "$var wire 1 " << n*(1+rs+ws)+1 << ' ' << s.substr(ld+1, s.size()-1)+"_R" << " $end\n";
00435 if (ws)
00436 *os << "$var wire 1 " << n*(1+rs+ws)+1+rs << ' ' << s.substr(ld+1, s.size()-1)+"_W" << " $end\n";
00437 *os << "$upscope $end\n";
00438 n++;
00439 }
00440 *os << "$enddefinitions $end\n";
00441
00442
00443 changesWritten = true;
00444 osbuffer << "#0\n$dumpvars\n";
00445 n=0;
00446 for (iter i=tv.begin();
00447 i!=tv.end(); i++) {
00448 valout(*i);
00449 osbuffer << ' ' << n*(1+rs+ws) << '\n';
00450
00451 if (rs) {
00452 osbuffer << "0" << n*(1+rs+ws)+1 << "\n";
00453 }
00454 if (ws) {
00455 if (rs)
00456 osbuffer << "0" << n*(1+rs+ws)+2 << "\n";
00457 else
00458 osbuffer << "0" << n*(1+rs+ws)+1 << "\n";
00459 }
00460 n++;
00461 }
00462 osbuffer << "$end\n";
00463 flushbuffer();
00464 }
00465
00466 void DumpVCD::cycle() {
00467
00468 flushbuffer();
00469
00470
00471 SystemClockOffset clock=SystemClock::Instance().GetCurrentTime();
00472 osbuffer << "#" << clock << '\n';
00473
00474
00475 for (size_t i=0; i<marked.size(); i++)
00476 osbuffer << "0" << marked[i] << "\n";
00477 if(marked.size())
00478 changesWritten = true;
00479 marked.clear();
00480 }
00481
00482 void DumpVCD::stop() {
00483
00484 flushbuffer();
00485
00486
00487 SystemClockOffset clock=SystemClock::Instance().GetCurrentTime();
00488 *os << "#" << clock << '\n';
00489
00490 os->flush();
00491 }
00492
00493 void DumpVCD::markRead(const TraceValue *t) {
00494 if (rs) {
00495
00496 osbuffer << "1" << id2num[t]*(1+rs+ws)+1 << "\n";
00497 changesWritten = true;
00498
00499 marked.push_back(id2num[t]*(1+rs+ws)+1);
00500 }
00501 }
00502
00503 void DumpVCD::markWrite(const TraceValue *t) {
00504 if (ws) {
00505 osbuffer << "1" << id2num[t]*(1+rs+ws)+1+rs << "\n";
00506 changesWritten = true;
00507 marked.push_back(id2num[t]*(1+rs+ws)+1+rs);
00508 }
00509 }
00510
00511 void DumpVCD::markChange(const TraceValue *t) {
00512 valout(t);
00513 osbuffer << " " << id2num[t]*(1+rs+ws) << "\n";
00514 changesWritten = true;
00515 }
00516
00517 bool DumpVCD::enabled(const TraceValue *t) const {
00518 return id2num.find(t)!=id2num.end();
00519 }
00520
00521 DumpVCD::~DumpVCD() { delete os; }
00522
00523 DumpManager* DumpManager::Instance(void) {
00524 static DumpManager *f;
00525 if(f == NULL)
00526 f = new DumpManager();
00527 return f;
00528 }
00529
00530 DumpManager::DumpManager() {
00531 singleDeviceApp = false;
00532 }
00533
00534 void DumpManager::appendDeviceName(std::string &s) {
00535 static int devidx = 0;
00536 devidx++;
00537 if(singleDeviceApp && devidx > 1)
00538 avr_error("Can't create device name twice, because it's a single device application");
00539 if(!singleDeviceApp)
00540 s += "Dev" + int2str(devidx);
00541 }
00542
00543 void DumpManager::registerAvrDevice(AvrDevice* dev) {
00544 devices.push_back(dev);
00545 }
00546
00547 void DumpManager::unregisterAvrDevice(AvrDevice* dev) {
00548 vector<AvrDevice*> dl;
00549 for(vector<AvrDevice*>::iterator i = devices.begin(); i != devices.end(); i++) {
00550 AvrDevice* d = *i;
00551 if(d != dev)
00552 dl.push_back(d);
00553 }
00554 devices.swap(dl);
00555 }
00556
00557 TraceValue* DumpManager::seekValueByName(const std::string &name) {
00558 if(singleDeviceApp) {
00559 if(devices.size() == 0)
00560 return NULL;
00561 return devices[0]->FindTraceValueByName(name);
00562 } else {
00563 int idx = name.find('.');
00564 if(idx <= 0)
00565 return NULL;
00566 for(vector<AvrDevice*>::iterator i = devices.begin(); i != devices.end(); i++) {
00567 if((*i)->GetScopeName() == name.substr(0, idx)) {
00568 return (*i)->FindTraceValueByName(name.substr(idx + 1));
00569 }
00570 }
00571 return NULL;
00572 }
00573 }
00574
00575 void DumpManager::SetSingleDeviceApp(void) {
00576 if(devices.size() > 0)
00577 avr_error("method SetSingleDeviceApp have to be used before creating and adding devices to DumpManager");
00578 singleDeviceApp = true;
00579 }
00580
00581 void DumpManager::addDumper(Dumper *dump, const TraceSet &vals) {
00582
00583 for(TraceSet::const_iterator i = vals.begin(); i != vals.end(); i++) {
00584 (*i)->enable();
00585 if(find(active.begin(), active.end(), *i) == active.end())
00586 active.push_back(*i);
00587 }
00588
00589
00590 if(find(dumps.begin(), dumps.end(), dump) != dumps.end())
00591 avr_error("Internal error: Dumper already registered.");
00592
00593 dump->setActiveSignals(vals);
00594
00595 dumps.push_back(dump);
00596 }
00597
00598 const TraceSet& DumpManager::all() {
00599 TraceSet* s;
00600
00601
00602 _all.clear();
00603
00604
00605 for(vector<AvrDevice*>::const_iterator d = devices.begin(); d != devices.end(); d++) {
00606
00607 s = (*d)->GetAllTraceValuesRecursive();
00608
00609 _all.reserve(_all.size() + s->size());
00610
00611 for(TraceSet::const_iterator i = s->begin(); i != s->end(); i++)
00612 _all.push_back(*i);
00613 delete s;
00614 }
00615
00616
00617 return _all;
00618 }
00619
00620 void DumpManager::start() {
00621 for (size_t i=0; i< dumps.size(); i++)
00622 dumps[i]->start();
00623
00624 }
00625
00626 void DumpManager::cycle() {
00627
00628 for (size_t i=0; i<dumps.size(); i++)
00629 dumps[i]->cycle();
00630
00631
00632 for (TraceSet::iterator i=active.begin();
00633 i!=active.end(); i++) {
00634 (*i)->cycle();
00635 for (size_t j=0; j<dumps.size(); j++)
00636 if (dumps[j]->enabled(*i))
00637 (*i)->dump(*dumps[j]);
00638 }
00639 }
00640
00641 void DumpManager::stopApplication(void) {
00642 for(size_t i = 0; i < dumps.size(); i++) {
00643 dumps[i]->stop();
00644 delete dumps[i];
00645 }
00646 dumps.clear();
00647 }
00648
00649 void DumpManager::save(ostream &os) const {
00650 TraceSet* s;
00651 for(vector<AvrDevice*>::const_iterator d = devices.begin(); d != devices.end(); d++) {
00652 s = (*d)->GetAllTraceValuesRecursive();
00653 for(TraceSet::const_iterator i = s->begin(); i != s->end(); i++) {
00654 TraceValue& tv = *(*i);
00655 if (tv.index() >= 0) {
00656 TraceSet::const_iterator j = i;
00657 int c = tv.index();
00658
00659 while(((*i)->barename() == tv.barename()) &&
00660 (c == (*i)->index())) {
00661 i++;
00662 c++;
00663 }
00664 i--; c--;
00665
00666 if(c) {
00667 os << "| " << tv.barename() << ' '
00668 << tv.index() << " .. "
00669 << (*i)->index() << '\n';
00670 } else {
00671 os << "+ " << (*i)->name() << '\n';
00672 }
00673 } else
00674 os << "+ " << (*i)->name() << '\n';
00675 }
00676 delete s;
00677 }
00678 }
00679
00680 TraceSet DumpManager::load(istream &is) {
00681 TraceSet res;
00682
00683 while(!is.eof()) {
00684
00685 string l = readline(is);
00686 vector<string> ls = split(l);
00687
00688
00689 if(ls.size() < 2) continue;
00690
00691 if(ls[0] == "+") {
00692
00693 string n = ls[1];
00694
00695 TraceValue *t = seekValueByName(n);
00696 if(t == NULL)
00697 avr_error("TraceValue '%s' is not known.", n.c_str());
00698
00699 res.push_back(t);
00700 } else if(ls[0] == "|") {
00701
00702 if(ls[3] != "..")
00703 avr_error("'..' expected between range limits.");
00704
00705 string bn = ls[1];
00706 size_t min = atoi(ls[2].c_str());
00707 size_t max = atoi(ls[4].c_str());
00708
00709 for(size_t i = min; i <= max; i++) {
00710 string n = ls[1] + int2str(i);
00711 TraceValue *t = seekValueByName(n);
00712 if(t == NULL)
00713 avr_error("While constructing range with '%s', TraceValue is not known.", n.c_str());
00714
00715 res.push_back(t);
00716 }
00717 } else if(ls[0][0] != '#')
00718
00719 avr_error("Invalid trace value specifier '%s'.", ls[0].c_str());
00720 }
00721 return res;
00722 }
00723
00724 TraceSet DumpManager::load(const string &istr) {
00725 istringstream is(istr.c_str());
00726 return load(is);
00727 }
00728
00729 TraceValue* trace_direct(TraceValueRegister *t, const std::string &name, bool *val) {
00730 TraceValue *tv=new TraceValue(1, t->GetTraceValuePrefix() + name,
00731 -1, val);
00732 t->RegisterTraceValue(tv);
00733 return tv;
00734 }
00735
00736 TraceValue* trace_direct(TraceValueRegister *t, const std::string &name, uint8_t
00737 *val) {
00738 TraceValue* tv=new TraceValue(8, t->GetTraceValuePrefix() + name,
00739 -1, val);
00740 t->RegisterTraceValue(tv);
00741 return tv;
00742 }
00743
00744 TraceValue* trace_direct(TraceValueRegister *t, const std::string &name, uint16_t
00745 *val) {
00746 TraceValue* tv=new TraceValue(16, t->GetTraceValuePrefix() + name,
00747 -1, val);
00748 t->RegisterTraceValue(tv);
00749 return tv;
00750 }
00751
00752 TraceValue* trace_direct(TraceValueRegister *t, const std::string &name, uint32_t
00753 *val) {
00754 TraceValue* tv=new TraceValue(32, t->GetTraceValuePrefix() + name,
00755 -1, val);
00756 t->RegisterTraceValue(tv);
00757 return tv;
00758 }
00759