Changeset 1727 for trunk/MagicSoft/Cosy/candrv/nodedrv.cc
- Timestamp:
- 01/23/03 13:32:58 (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Cosy/candrv/nodedrv.cc
r1703 r1727 33 33 // virtual void StopDevice() 34 34 // virtual void HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, timeval_t *tv) 35 // virtual void HandleSDOOK(WORD_t idx, BYTE_t subidx )35 // virtual void HandleSDOOK(WORD_t idx, BYTE_t subidx, timeval_t *tv) 36 36 // virtual void HandleSDOError(LWORD_t data) 37 37 // virtual void HandlePDO1(BYTE_t *data, timeval_t *tv) … … 48 48 #include <iostream.h> 49 49 50 #include <TTimer.h> 51 52 #include "base/timer.h" 50 53 #include "network.h" 51 54 #include "MLogManip.h" … … 76 79 } 77 80 81 fTimerOn = kFALSE; 82 fTimeout = new TTimer(this, 100, kFALSE); // 100ms, asynchronous 83 78 84 lout << "- Node #" << (int)nodeid << " (" << name << ") initialized." << endl; 79 } 80 81 // -------------------------------------------------------------------------- 82 // 83 // Empty destructor 85 86 } 87 88 // -------------------------------------------------------------------------- 89 // 90 // destructor 84 91 // 85 92 NodeDrv::~NodeDrv() 86 93 { 94 fTimerOn = kFALSE; 95 delete fTimeout; 87 96 } 88 97 … … 122 131 EnableCanMsg(kSDO_RX); 123 132 EnableCanMsg(kSDO_TX); 133 EnableCanMsg(kNodeguard); 134 EnableCanMsg(kEMERGENCY); 124 135 125 136 fIsZombie = kFALSE; … … 135 146 // This output is never redirected to the GUI 136 147 // 137 void NodeDrv::HandleSDOOK(WORD_t idx, BYTE_t subidx )148 void NodeDrv::HandleSDOOK(WORD_t idx, BYTE_t subidx, timeval_t *tv) 138 149 { 139 150 const Bool_t gui = lout.IsOutputDeviceEnabled(MLog::eGui); … … 367 378 // -------------------------------------------------------------------------- 368 379 // 369 // Send a nNMT message (command) to this device380 // Send a NMT message (command) to this device 370 381 // 371 382 // The message is not send if the node has the status Zombie. … … 377 388 fNetwork->SendNMT(fId, cmd); 378 389 return !fIsZombie; 390 } 391 392 // -------------------------------------------------------------------------- 393 // 394 // Send a Nodeguard message (command) to this device 395 // 396 void NodeDrv::SendNodeguard() 397 { 398 fNetwork->SendNodeguard(fId); 379 399 } 380 400 … … 404 424 405 425 if (!rc) 426 { 427 lout << "NodeDrv::WaitForSdo: 0x" << hex << idx << "/" << dec << (int)subidx << " " << GetNodeName() << " --> ZOMBIE!" << endl; 428 SetZombie(); 429 } 430 /* 431 if (HasError()) 432 { 433 lout << "NodeDrv::WaitForSdo: HasError 0x" << hex << idx << "/" << dec << (int)subidx << " " << GetNodeName() << " --> ZOMBIE!" << endl; 406 434 fIsZombie = kTRUE; 407 435 } 436 */ 408 437 return fIsZombie ? false : rc; 409 438 } … … 453 482 } 454 483 484 // -------------------------------------------------------------------------- 485 // 486 // Start the standard CANopen guarding of the device. 487 // While ms is the guard time in millisec. This is the time between 488 // two requests for a Nodeguard message. 489 // ltf is the LifeTimeFactor. This means how often it is checked, that at 490 // least one Nodeguard message was answered. 491 // 492 void NodeDrv::StartGuarding() 493 { 494 if (fTimerOn) 495 return; 496 497 SendNodeguard(); 498 499 fTimerOn = kTRUE; 500 fTimeout->SetTime(fGuardTime); 501 fTimeout->Reset(); 502 fTimeout->TurnOn(); 503 //fTimeout->Start(fGuardTime, kTRUE); 504 505 lout << "- " << GetNodeName() << ": Guarding (" << dec; 506 lout << fLifeTimeFactor << "*" << fGuardTime << "ms) started." << endl; 507 } 508 509 void NodeDrv::StartGuarding(Int_t ms, Int_t ltf) 510 { 511 if (fTimerOn) 512 { 513 lout << "- " << GetNodeName() << ": ERROR - Guarding already started." << endl; 514 return; 515 } 516 fGuardTime = ms; 517 fLifeTimeFactor = ltf; 518 519 StartGuarding(); 520 } 521 522 void NodeDrv::StopGuarding() 523 { 524 fTimeout->TurnOff(); 525 fTimerOn = kFALSE; 526 527 lout << "- " << GetNodeName() << ": Guarding stopped." << endl; 528 } 529 530 // -------------------------------------------------------------------------- 531 // 532 // Handle the Nodeguard-Timer Event. 533 // It checks whether the node timed out. If it timed out it is set to 534 // the Zombie state. 535 // A new Nodeguard request is send and a new timer event is triggered. 536 // 537 Bool_t NodeDrv::HandleTimer(TTimer *t) 538 { 539 // 540 // WARNING: 541 // It seems, that you should never access ANY output from 542 // here. Neither the GUI, nor COUT. This can result in 543 // 'unexpected async reply' 544 // 545 546 /* 547 Fons: 548 ----- 549 550 timers never trigger at the same time or when in a TTimer::Notify. 551 Little explanation: 552 553 - there are two types of timers synchronous and a-synchronous. 554 - synchronous timers are only handled via the ROOT eventloop 555 (see TUnixSystem::DispatchOneEvent()). If there are no mouse/keyboard 556 events then the synchronous timer queue is checked. So if the processing 557 of a mouse/keyboard event takes a long time synchronous timers are not 558 called for a while. To prevent this from happening one can call in long 559 procedures gSystem->ProcessEvents(). The system schedules only the 560 next timer in the queue when the current one's Notify() has finished. 561 - a-synchronous timers are triggered via SIGALARM, i.e. the program is 562 interupted and execution jumps to the Notify() function. When the 563 notify is finished the next a-sync timer is scheduled and the system 564 resumes from the place where it was initially interrupted. One of the 565 things to remember when using a-sync timers is don't make any graphics 566 calls in them. X11 is not re-entrant and it might be that the SIGALARM 567 signal interrupted the system while being in X11. A-sync timers are best 568 used to set flags that you can test at a convenient and controlled 569 time. 570 */ 571 if (fIsZombie) 572 return kTRUE; 573 574 Timer time; 575 Double_t now = time.Now(); 576 if (now > fTimeoutTime) 577 { 578 //cout << "ERROR - " << GetNodeName() << " didn't respond in timeout window." << endl; 579 //lout << "ERROR - " << GetNodeName() << " didn't respond in timeout window." << endl; 580 //cout << dec << "+" << (int)GetId() << ": Handle: " << fmod(now, 500) << endl; 581 //cout << dec << "+" << (int)GetId() << ": Handle: " << fmod(fTimeoutTime, 500) << endl; 582 //cout << fGuardTime << endl; 583 fIsZombie = true; 584 //SetZombie(); 585 586 return kTRUE; 587 } 588 589 SendNodeguard(); 590 591 return kTRUE; 592 } 593 594 // -------------------------------------------------------------------------- 595 // 596 // Set the timeout timer to the time the event was received plus the 597 // guard time times lifetimefactor. 598 // 599 void NodeDrv::HandleNodeguard(timeval_t *tv) 600 { 601 Timer t(tv); 602 fTimeoutTime = t + (fGuardTime*fLifeTimeFactor/1000.); 603 } 604 605 void NodeDrv::SetZombie() 606 { 607 fIsZombie = true; 608 StopGuarding(); 609 }
Note:
See TracChangeset
for help on using the changeset viewer.