Changeset 1727 for trunk/MagicSoft/Cosy/candrv
- Timestamp:
- 01/23/03 13:32:58 (22 years ago)
- Location:
- trunk/MagicSoft/Cosy/candrv
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Cosy/candrv/canopen.cc
r1275 r1727 16 16 ! 17 17 ! 18 ! Author(s): Thomas Bretz <mailto:tbretz@ uni-sw.gwdg.de>, 200119 ! 20 ! Copyright: MAGIC Software Development, 2000-200 118 ! Author(s): Thomas Bretz <mailto:tbretz@astro.uni-wuerzburg.de>, 2003 19 ! 20 ! Copyright: MAGIC Software Development, 2000-2003 21 21 ! 22 22 ! … … 84 84 { 85 85 const WORD_t fcode = cobid >> 7; 86 const BYTE_t node = cobid & 0x1f; 86 87 87 88 switch (fcode) … … 94 95 return; 95 96 96 case kSYNC: 97 cout << "Sync" << endl; 97 case kEMERGENCY: // also case kSYNC: 98 if (cobid==0) 99 cout << "Sync" << endl; 100 else 101 { 102 cout << "EMERGENCY Node #" << dec << (int)data[1] << endl; 103 HandleEmergency(node, tv); 104 } 105 return; 106 107 case kNodeguard: 108 //cout << "Nodeguard Node #" << dec << (int)node << endl; 109 HandleNodeguard(node, tv); 98 110 return; 99 111 100 112 case kSDO_RX: 101 113 { 102 const BYTE_t node = cobid & 0x1f;103 114 const BYTE_t cmd = data[0]; 104 115 const LWORD_t dat = data[4] | (data[5]<<8) | (data[6]<<16) | (data[7]<<24); … … 114 125 case kPDO1_TX: 115 126 { 116 const BYTE_t node = cobid & 0x1f;117 127 HandlePDO1(node, data, tv); 118 128 pthread_cond_broadcast(&fPdoCond[node-1][0]); … … 122 132 case kPDO2_TX: 123 133 { 124 const BYTE_t node = cobid & 0x1f;125 134 HandlePDO2(node, data, tv); 126 135 pthread_cond_broadcast(&fPdoCond[node-1][1]); … … 130 139 case kPDO3_TX: 131 140 { 132 const BYTE_t node = cobid & 0x1f;133 141 HandlePDO3(node, data, tv); 134 142 pthread_cond_broadcast(&fPdoCond[node-1][2]); … … 138 146 case kPDO4_TX: 139 147 { 140 const BYTE_t node = cobid & 0x1f;141 148 HandlePDO4(node, data, tv); 142 149 pthread_cond_broadcast(&fPdoCond[node-1][3]); … … 145 152 } 146 153 147 const BYTE_t node = cobid & 0x1f; 148 cout << "Function Code: 0x" << hex << fcode << " Node: " << dec << (int)node << endl; 154 cout << "CanOpen::HandleCanMessage - Unhandled Message: Function Code=0x" << hex << fcode << " Node #" << dec << (int)node << endl; 149 155 } 150 156 … … 168 174 { 169 175 EnableCanMsg(node, kEMERGENCY); 176 } 177 178 // -------------------------------------------------------------------------- 179 // 180 // Enables Nodeguard messages for a given node 181 // 182 void CanOpen::EnableNodeguard(BYTE_t node) 183 { 184 EnableCanMsg(node, kNodeguard); 170 185 } 171 186 … … 372 387 // -------------------------------------------------------------------------- 373 388 // 374 // Send a nNMT Message to the given node with command cmd389 // Send a NMT Message to the given node with command cmd 375 390 // 376 391 void CanOpen::SendNMT(BYTE_t node, BYTE_t cmd) … … 381 396 // -------------------------------------------------------------------------- 382 397 // 398 // Send a Nodeguard Message to the given node with command cmd 399 // 400 void CanOpen::SendNodeguard(BYTE_t node) 401 { 402 BYTE_t msg[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 403 SendCanFrame(CobId(node, kNodeguard), msg, 1); 404 } 405 406 // -------------------------------------------------------------------------- 407 // 383 408 // Decodes node and function code into a CobId 384 409 // -
trunk/MagicSoft/Cosy/candrv/network.cc
r1703 r1727 89 89 void Network::HandleSDO(BYTE_t node, BYTE_t cmd, WORD_t idx, BYTE_t subidx, LWORD_t data, timeval_t *tv) 90 90 { 91 switch (cmd) 92 { 93 case kSDO_TX4: // answer to 0x40 with 4 bytes of data 94 if (fNodes[node]) 91 if (fNodes[node]) 92 switch (cmd) 95 93 { 94 case kSDO_TX4: // answer to 0x40 with 4 bytes of data 96 95 fNodes[node]->HandleSDO(idx, subidx, data, tv); 97 96 return; 97 98 case kSDO_TX3: // answer to 0x40 with 2 bytes of data 99 fNodes[node]->HandleSDO(idx, subidx, data>>16, tv); 100 return; 101 102 case kSDO_TX1: // answer to 0x40 with 1 byte of data 103 fNodes[node]->HandleSDO(idx, subidx, data>>24, tv); 104 return; 105 106 case kSDO_TX_OK: // answer to a SDO_TX message 107 fNodes[node]->HandleSDOOK(idx, subidx, tv); 108 return; 109 110 case kSDO_TX_ERROR: // error message (instead of 0x60) 111 fNodes[node]->HandleSDOError(data); 112 return; 98 113 } 99 break; 100 101 case kSDO_TX3: // answer to 0x40 with 2 bytes of data 102 if (fNodes[node]) 103 { 104 fNodes[node]->HandleSDO(idx, subidx, data>>16, tv); 105 return; 106 } 107 break; 108 109 case kSDO_TX1: // answer to 0x40 with 1 byte of data 110 if (fNodes[node]) 111 { 112 fNodes[node]->HandleSDO(idx, subidx, data>>24, tv); 113 return; 114 } 115 break; 116 117 case kSDO_TX_OK: // answer to a SDO_TX message 118 if (fNodes[node]) 119 { 120 fNodes[node]->HandleSDOOK(idx, subidx); 121 return; 122 } 123 break; 124 125 case kSDO_TX_ERROR: // error message (instead of 0x60) 126 if (fNodes[node]) 127 { 128 fNodes[node]->HandleSDOError(data); 129 return; 130 } 131 break; 132 } 114 133 115 cout << dec << setfill('0'); 134 cout << "N ode=" << (int)node << " Cmd=0x" << hex << (int)cmd << ": ";116 cout << "Network::HandleSDO: Node=" << (int)node << " Cmd=0x" << hex << (int)cmd << ": "; 135 117 cout << "Sdo=" << idx << "/" << (int)subidx << ": 0x" << setw(8) << data; 136 118 cout << endl; … … 145 127 if (!fNodes[node]) 146 128 { 147 cout << "N ode " << dec << (int)node << ",PDO1: " << hex;129 cout << "Network::HandlePDO1: Node #" << dec << (int)node << " not found - PDO1: " << hex; 148 130 for (int i=0; i<8; i++) 149 131 cout << " 0x" << (int)data[i]; … … 163 145 if (!fNodes[node]) 164 146 { 165 cout << "N ode " << dec << (int)node << ",PDO2: " << hex;147 cout << "Network::HandlePDO2: Node #" << dec << (int)node << " not found - PDO2: " << hex; 166 148 for (int i=0; i<8; i++) 167 149 cout << " 0x" << (int)data[i]; … … 181 163 if (!fNodes[node]) 182 164 { 183 cout << "N ode " << dec << (int)node << ",PDO3: " << hex;165 cout << "Network::HandlePDO3: Node #" << dec << (int)node << " not found - PDO3: " << hex; 184 166 for (int i=0; i<8; i++) 185 167 cout << " 0x" << (int)data[i]; … … 199 181 if (!fNodes[node]) 200 182 { 201 cout << "N ode " << dec << (int)node << ",PDO4: " << hex;183 cout << "Network::HandlePDO4: Node #" << dec << (int)node << " not found - PDO4: " << hex; 202 184 for (int i=0; i<8; i++) 203 185 cout << " 0x" << (int)data[i]; … … 208 190 fNodes[node]->HandlePDO4(data, tv); 209 191 } 192 193 // -------------------------------------------------------------------------- 194 // 195 // Distributes Nodeguard messages to the correspoding node calling 196 // HandleNodeguard 197 // 198 void Network::HandleNodeguard(BYTE_t node, timeval_t *tv) 199 { 200 if (!fNodes[node]) 201 { 202 cout << "Network::HandleNodeguard: Node #" << dec << (int)node << " not found: Nodeguard." << endl; 203 return; 204 } 205 206 fNodes[node]->HandleNodeguard(tv); 207 } 208 209 // -------------------------------------------------------------------------- 210 // 211 // Distributes Emergency messages to the correspoding node calling 212 // HandleEmergency 213 // 214 void Network::HandleEmergency(BYTE_t node, timeval_t *tv) 215 { 216 if (!fNodes[node]) 217 { 218 cout << "Network::HandleEmergency: Node #" << dec << (int)node << " not found: Emergency." << endl; 219 return; 220 } 221 222 fNodes[node]->HandleEmergency(tv); 223 } 224 210 225 211 226 // -------------------------------------------------------------------------- … … 281 296 continue; 282 297 283 lout << "- Node #" << dec << i << " '" << fNodes[i]->GetNodeName();284 lout << "' has error #" << fNodes[i]->GetError() << endl;298 //lout << "- Node #" << dec << i << " '" << fNodes[i]->GetNodeName(); 299 //lout << "' has error #" << fNodes[i]->GetError() << endl; 285 300 } 286 301 -
trunk/MagicSoft/Cosy/candrv/network.h
r1703 r1727 16 16 void HandlePDO3(BYTE_t node, BYTE_t *data, timeval_t *tv); 17 17 void HandlePDO4(BYTE_t node, BYTE_t *data, timeval_t *tv); 18 void HandleNodeguard(BYTE_t node, timeval_t *tv); 19 void HandleEmergency(BYTE_t node, timeval_t *tv); 18 20 19 21 void InitNodes(); -
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 } -
trunk/MagicSoft/Cosy/candrv/nodedrv.h
r1703 r1727 20 20 class Network; 21 21 22 class NodeDrv : public Log 22 class NodeDrv : public Log, public TObject 23 23 { 24 24 private: … … 30 30 int fError; 31 31 32 Bool_t fIsZombie; // A Zombie node is a node which doesn't answer... 33 34 TTimer *fTimeout; 35 Int_t fGuardTime; // Guardtime [ms] 36 Int_t fLifeTimeFactor; 37 Double_t fTimeoutTime; 38 Bool_t fTimerOn; 39 40 Bool_t HandleTimer(TTimer *t); 41 32 42 protected: 33 43 void SetError(int err) { fError = err; } 34 44 void DelError() { fError = 0; } 35 45 36 Bool_t fIsZombie; // A Zombie node is a node which doesn't answer... 46 Int_t GetLifeTimeFactor() const { return fLifeTimeFactor; } 47 Int_t GetGuardTime() const { return fGuardTime; } 48 49 virtual void SetZombie(); 37 50 38 51 public: … … 56 69 57 70 virtual void HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, timeval_t *tv); 58 virtual void HandleSDOOK(WORD_t idx, BYTE_t subidx );71 virtual void HandleSDOOK(WORD_t idx, BYTE_t subidx, timeval_t *tv); 59 72 virtual void HandleSDOError(LWORD_t data); 60 73 61 virtual void HandlePDO1(BYTE_t *data, timeval_t *tv) {}; 62 virtual void HandlePDO2(BYTE_t *data, timeval_t *tv) {}; 63 virtual void HandlePDO3(BYTE_t *data, timeval_t *tv) {}; 64 virtual void HandlePDO4(BYTE_t *data, timeval_t *tv) {}; 74 virtual void HandlePDO1(BYTE_t *data, timeval_t *tv) {} 75 virtual void HandlePDO2(BYTE_t *data, timeval_t *tv) {} 76 virtual void HandlePDO3(BYTE_t *data, timeval_t *tv) {} 77 virtual void HandlePDO4(BYTE_t *data, timeval_t *tv) {} 78 virtual void HandleNodeguard(timeval_t *tv); 79 virtual void HandleEmergency(timeval_t *tv) {} 65 80 66 81 bool SendPDO1(BYTE_t data[8]); … … 80 95 81 96 bool SendNMT(BYTE_t cmd); 97 virtual void SendNodeguard(); 82 98 83 99 bool RequestSDO(WORD_t idx, BYTE_t subidx=0); … … 93 109 void EnableCanMsg(BYTE_t fcode); 94 110 111 void StartGuarding(); 112 void StartGuarding(Int_t ms, Int_t ltf); 113 void StopGuarding(); 114 95 115 ClassDef(NodeDrv, 0) // base class for an object describing hardware 96 116 }; -
trunk/MagicSoft/Cosy/candrv/vmodican.cc
r1703 r1727 409 409 while (!Send(&msg)); /* transmitt to module */ 410 410 411 lout << "- Baudrate set to " << rate << " bps" << endl;411 lout << "- Baudrate set to " << rate << "kbps" << endl; 412 412 } 413 413 … … 904 904 // */ 905 905 // 906 void VmodIcan::SendCanFrame(WORD_t cobid, BYTE_t m[8] )907 { 908 const WORD_t desc = MsgDescr(cobid, 8 );906 void VmodIcan::SendCanFrame(WORD_t cobid, BYTE_t m[8], BYTE_t rtr) 907 { 908 const WORD_t desc = MsgDescr(cobid, 8, rtr); 909 909 910 910 Message msg; -
trunk/MagicSoft/Cosy/candrv/vmodican.h
r1140 r1727 73 73 void EnableCobId(WORD_t cobid, int flag=TRUE); 74 74 75 void SendCanFrame(WORD_t cobid, BYTE_t m[8] );75 void SendCanFrame(WORD_t cobid, BYTE_t m[8], BYTE_t rtr=0); 76 76 void SendCanFrame(WORD_t cobid, 77 77 BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
Note:
See TracChangeset
for help on using the changeset viewer.