Ignore:
Timestamp:
11/17/03 13:50:48 (21 years ago)
Author:
tbretz
Message:
*** empty log message ***
Location:
trunk/MagicSoft/Cosy/candrv
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Cosy/candrv/canopen.cc

    r1727 r2518  
    3232#include "canopen.h"
    3333
    34 #include <iostream.h> // cout
    35 #include <iomanip.h>  // setw, setfill
     34#include <iostream> // cout
     35#include <iomanip>  // setw, setfill
    3636
    3737ClassImp(CanOpen);
     38
     39using namespace std;
    3840
    3941// --------------------------------------------------------------------------
     
    4446CanOpen::CanOpen(const char *dev, const int baud, MLog &out) : VmodIcan(dev, baud, out)
    4547{
    46     for (int i=0; i<32; i++)
    47         for (int j=0; j<4; j++)
    48         {
    49             pthread_cond_init(&fPdoCond[i][j], NULL);
    50             pthread_mutex_init(&fPdoMux[i][j], NULL);
    51             pthread_mutex_lock(&fPdoMux[i][j]);
    52         }
    53 
    5448    lout << "- CanOpen initialized." << endl;
    5549}
     
    6155CanOpen::~CanOpen()
    6256{
    63     for (int i=0; i<32; i++)
    64         for (int j=0; j<4; j++)
    65         {
    66             pthread_cond_destroy(&fPdoCond[i][j]);
    67             pthread_mutex_destroy(&fPdoMux[i][j]);
    68         }
    6957    lout << "- CanOpen destroyed." << endl;
    7058}
     
    126114        {
    127115            HandlePDO1(node, data, tv);
    128             pthread_cond_broadcast(&fPdoCond[node-1][0]);
     116            fPdoCond[node-1][0].Broadcast();
    129117        }
    130118        return;
     
    133121        {
    134122            HandlePDO2(node, data, tv);
    135             pthread_cond_broadcast(&fPdoCond[node-1][1]);
     123            fPdoCond[node-1][1].Broadcast();
    136124        }
    137125        return;
     
    140128        {
    141129            HandlePDO3(node, data, tv);
    142             pthread_cond_broadcast(&fPdoCond[node-1][2]);
     130            fPdoCond[node-1][2].Broadcast();
    143131        }
    144132        return;
     
    147135        {
    148136            HandlePDO4(node, data, tv);
    149             pthread_cond_broadcast(&fPdoCond[node-1][3]);
     137            fPdoCond[node-1][3].Broadcast();
    150138        }
    151139        return;
  • trunk/MagicSoft/Cosy/candrv/network.cc

    r2278 r2518  
    269269        if (fNodes[i] && fNodeInitialized[i])
    270270        {
    271             lout << "- Stopping Node #" << dec << i << endl;
     271            lout << "- Stopping Node #" << dec << i;
     272            lout << " (" << fNodes[i]->GetNodeName() << ")" << endl;
    272273            fNodes[i]->StopDevice();
    273274        }
  • trunk/MagicSoft/Cosy/candrv/nodedrv.cc

    r2278 r2518  
    6161// and the node name. The name is a name for debug output.
    6262//
    63 NodeDrv::NodeDrv(BYTE_t nodeid, const char *name, MLog &out) : Log(out), fNetwork(NULL), fId(32), fError(0), fIsZombie(kTRUE)
     63NodeDrv::NodeDrv(BYTE_t nodeid, const char *name, MLog &out) : Log(out), fNetwork(NULL), fId(32), fError(0), fIsZombie(kTRUE), fGuard(NULL)
    6464{
    6565    if (nodeid>0x1f)
     
    7979    }
    8080
    81     fTimerOn = kFALSE;
    82     fTimeout = new TTimer(this, 100, kFALSE); // 100ms, asynchronous
    83 
    8481    lout << "- Node #" << (int)nodeid << " (" << name << ") initialized." << endl;
    8582
     
    9289NodeDrv::~NodeDrv()
    9390{
    94     fTimerOn = kFALSE;
    95     delete fTimeout;
    9691}
    9792
     
    492487// least one Nodeguard message was answered.
    493488//
     489class NodeGuard : public MThread
     490{
     491    Double_t fTimeoutTime;
     492    Double_t fGuardTime;
     493    Int_t    fLifeTimeFactor;
     494
     495    Bool_t   fIsCanOpen;
     496
     497    NodeDrv *fDrv;
     498
     499public:
     500    NodeGuard(NodeDrv *drv, Int_t guard, Int_t ltf, Bool_t canopen)
     501        : MThread(false), fGuardTime(guard/1000.), fLifeTimeFactor(ltf), fIsCanOpen(canopen), fDrv(drv) { }
     502
     503    void Reset(timeval_t *tv=NULL)
     504    {
     505        Timer t;
     506        if (tv)
     507            t.SetTimer(tv);
     508        else
     509            t.Now();
     510
     511        fTimeoutTime = t + (fGuardTime*fLifeTimeFactor);
     512    }
     513
     514    void *Thread()
     515    {
     516        Reset();
     517
     518        while (!HasStopFlag())
     519        {
     520            // Sending nodeguards seems to result in
     521            // loosing CANbus messages or CANbus answers...
     522            // strange. Also protecting VmodIcan::SendCanFrame
     523            // by a Mutex doesn't help.
     524            if (fIsCanOpen)
     525                fDrv->SendNodeguard();
     526
     527            Timer t;
     528            t.Now();
     529
     530            const Timer t0 = t+fGuardTime;
     531
     532            while (!HasStopFlag() && t<t0 && t<fTimeoutTime)
     533            {
     534                usleep(5);
     535                t.Now();
     536            }
     537
     538            //cout << "-d-> " << (Long_t)((fTimeoutTime-t)*1000) << endl;
     539            //cout << "-o-> " << (ULong_t)((fTimeoutTime)*1000)<< " " << (ULong_t)((t)*1000) << endl;
     540            //cout << "-g-> " << (Long_t)((t-t0)*1000)<< endl;
     541
     542            if (t<fTimeoutTime)
     543                continue;
     544
     545            fDrv->SetZombie(false);
     546            return 0;
     547        }
     548        return 0;
     549    }
     550};
     551
    494552void NodeDrv::StartGuarding(Bool_t real=kTRUE)
    495553{
    496     if (fTimerOn)
     554    if (fGuard)
    497555        return;
    498556
    499     if (!real)
    500         SendNodeguard();
    501 
    502     fTimerOn = kTRUE;
    503     fTimeout->SetTime(fGuardTime);
    504     fTimeout->Reset();
    505 
    506     Timer t;
    507     fTimeoutTime = t.Now() + (fGuardTime*fLifeTimeFactor/1000.);
    508     //cout << GetNodeName() << ": " << fmod(fTimeoutTime*10000, 10000)/10 << endl;
    509 
    510     fTimeout->TurnOn();
    511     //fTimeout->Start(fGuardTime, kTRUE);
     557    fGuard = new NodeGuard(this, fGuardTime, fLifeTimeFactor, real);
     558    fGuard->Start();
    512559
    513560    lout << "- " << GetNodeName() << ": Guarding (" << dec;
     
    517564void NodeDrv::StartGuarding(Int_t ms, Int_t ltf, Bool_t real)
    518565{
    519     if (fTimerOn)
     566    if (fGuard)
    520567    {
    521568        lout << "- " << GetNodeName() << ": ERROR - Guarding already started." << endl;
    522569        return;
    523570    }
     571
    524572    fGuardTime      = ms;
    525573    fLifeTimeFactor = ltf;
     
    530578void NodeDrv::StopGuarding()
    531579{
    532     if (!fTimerOn)
     580    if (!fGuard)
    533581        return;
    534582
    535     fTimeout->TurnOff();
    536     fTimerOn = kFALSE;
     583    delete fGuard;
     584    fGuard=NULL;
    537585
    538586    lout << "- " << GetNodeName() << ": Guarding stopped." << endl;
    539 }
    540 
    541 // --------------------------------------------------------------------------
    542 //
    543 // Handle the Nodeguard-Timer Event.
    544 // It checks whether the node timed out. If it timed out it is set to
    545 // the Zombie state.
    546 // A new Nodeguard request is send and a new timer event is triggered.
    547 //
    548 Bool_t NodeDrv::HandleTimer(TTimer *t)
    549 {
    550     //
    551     // WARNING:
    552     //           It seems, that you should never access ANY output from
    553     //           here. Neither the GUI, nor COUT. This can result in
    554     //           'unexpected async reply'
    555     //
    556 
    557    /*
    558      Fons:
    559      -----
    560 
    561      timers never trigger at the same time or when in a TTimer::Notify.
    562      Little explanation:
    563 
    564      - there are two types of timers synchronous and a-synchronous.
    565      - synchronous timers are only handled via the ROOT eventloop
    566        (see TUnixSystem::DispatchOneEvent()). If there are no mouse/keyboard
    567        events then the synchronous timer queue is checked. So if the processing
    568        of a mouse/keyboard event takes a long time synchronous timers are not
    569        called for a while. To prevent this from happening one can call in long
    570        procedures gSystem->ProcessEvents(). The system schedules only the
    571        next timer in the queue when the current one's Notify() has finished.
    572      - a-synchronous timers are triggered via SIGALARM, i.e. the program is
    573        interupted and execution jumps to the Notify() function. When the
    574        notify is finished the next a-sync timer is scheduled and the system
    575        resumes from the place where it was initially interrupted. One of the
    576        things to remember when using a-sync timers is don't make any graphics
    577        calls in them. X11 is not re-entrant and it might be that the SIGALARM
    578        signal interrupted the system while being in X11. A-sync timers are best
    579        used to set flags that you can test at a convenient and controlled
    580        time.
    581        */
    582     if (fIsZombie)
    583         return kTRUE;
    584 
    585     Timer time;
    586     Double_t now = time.Now();
    587     if (now > fTimeoutTime)
    588     {
    589         cout << GetNodeName() << ": " << "==out==> " << fmod(now*1000, 10000)/10 << " > " << fmod(fTimeoutTime*10000, 10000)/10 << endl;
    590         //cout << "ERROR - " << GetNodeName() << " didn't respond in timeout window." << endl;
    591         //lout << "ERROR - " << GetNodeName() << " didn't respond in timeout window." << endl;
    592         //cout << dec << "+" << (int)GetId() << ": Handle: " << fmod(now, 500) << endl;
    593         //cout << dec << "+" << (int)GetId() << ": Handle: " << fmod(fTimeoutTime, 500) << endl;
    594         //cout << fGuardTime << endl;
    595         fIsZombie = true;
    596         //SetZombie();
    597 
    598         return kTRUE;
    599     }
    600 
    601     SendNodeguard();
    602 
    603     return kTRUE;
    604587}
    605588
     
    611594void NodeDrv::HandleNodeguard(timeval_t *tv)
    612595{
    613     Timer t(tv);
    614     fTimeoutTime = t + (fGuardTime*fLifeTimeFactor/1000.);
    615     //cout << GetNodeName() << ": " << fmod(fTimeoutTime*10000, 10000)/10 << endl;
    616 }
    617 
    618 void NodeDrv::SetZombie()
     596    if (fGuard)
     597        fGuard->Reset(tv);
     598}
     599
     600void NodeDrv::SetZombie(bool stopguard)
    619601{
    620602    fIsZombie = true;
    621     StopGuarding();
    622 }
     603    if (stopguard)
     604        StopGuarding();
     605    else
     606        lout << " - " << GetNodeName() << ": Zombie set due to timeout." << endl;
     607}
  • trunk/MagicSoft/Cosy/candrv/nodedrv.h

    r2278 r2518  
    1919
    2020class Network;
     21class NodeGuard;
    2122
    22 class NodeDrv : public Log, public TObject
     23class NodeDrv : public Log
    2324{
    2425private:
     
    3031    int fError;
    3132
    32     Bool_t fIsZombie; // A Zombie node is a node which doesn't answer...
     33    Bool_t  fIsZombie; // A Zombie node is a node which doesn't answer...
    3334
    34     TTimer  *fTimeout;
    35     Int_t    fGuardTime;      // Guardtime [ms]
    36     Int_t    fLifeTimeFactor;
    37     Double_t fTimeoutTime;
    38     Bool_t   fTimerOn;
     35    NodeGuard *fGuard;
    3936
    40     Bool_t HandleTimer(TTimer *t);
     37    Int_t   fGuardTime;      // Guardtime [ms]
     38    Int_t   fLifeTimeFactor;
    4139
    4240protected:
     
    4644    Int_t GetLifeTimeFactor() const { return fLifeTimeFactor; }
    4745    Int_t GetGuardTime() const      { return fGuardTime; }
    48 
    49     virtual void SetZombie();
    5046
    5147public:
     
    6763
    6864    bool IsZombieNode() const { return fIsZombie; }
     65    void SetZombie(bool stopguard=true);
    6966
    7067    virtual void HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, timeval_t *tv);
  • trunk/MagicSoft/Cosy/candrv/sdolist.cc

    r1109 r2518  
    1010    fFirst = new PendingSDO;
    1111    fLast  = fFirst;
    12 
    13     pthread_mutex_init(&fMux, NULL);
    1412}
    1513
    1614PendingSDOList::~PendingSDOList()
    1715{
    18     // pthread_mutex_lock(&fMux);
    19 
    2016    DelAll();
    2117    delete fFirst;
    22 
    23     pthread_mutex_destroy(&fMux);
    2418}
    2519
    2620void PendingSDOList::DelAll()
    2721{
    28     pthread_mutex_lock(&fMux);
     22    fMux.Lock();
    2923
    3024    PendingSDO *prev = fFirst;
     
    4135    fLast  = fFirst;
    4236
    43     pthread_mutex_unlock(&fMux);
     37    fMux.UnLock();
    4438}
    4539
     
    4842    PendingSDO *sdo = fFirst;
    4943
    50     pthread_mutex_lock(&fMux);
     44    fMux.Lock();
    5145    while ((sdo=sdo->Next))
    5246        if (sdo->Node==node && sdo->Idx==idx && sdo->Subidx==subidx)
     
    6054    fLast->Next = new PendingSDO(node, idx, subidx);
    6155    fLast = fLast->Next;
    62     pthread_mutex_unlock(&fMux);
     56    fMux.UnLock();
    6357}
    6458
     
    6862    PendingSDO *sdo;
    6963
    70     pthread_mutex_lock(&fMux);
     64    fMux.Lock();
    7165    while ((sdo=prev->Next))
    7266    {
     
    8680        break;
    8781    }
    88     pthread_mutex_unlock(&fMux);
     82    fMux.UnLock();
    8983}
    9084
     
    9993    PendingSDO *sdo = fFirst;
    10094
    101     pthread_mutex_lock(&fMux);
     95    fMux.Lock();
    10296    while ((sdo=sdo->Next))
    10397        if (sdo->Node==node)
     
    106100            break;
    107101        }
    108     pthread_mutex_unlock(&fMux);
     102    fMux.UnLock();
    109103
    110104    return rc;
     
    116110    PendingSDO *sdo = fFirst;
    117111
    118     pthread_mutex_lock(&fMux);
     112    fMux.Lock();
    119113    while ((sdo=sdo->Next))
    120114        if (sdo->Node==node && sdo->Idx==idx && sdo->Subidx==subidx)
     
    123117            break;
    124118        }
    125     pthread_mutex_unlock(&fMux);
     119    fMux.UnLock();
    126120
    127121    return rc;
  • trunk/MagicSoft/Cosy/candrv/sdolist.h

    r1109 r2518  
    1 #ifndef SDOLIST_H
    2 #define SDOLIST_H
    3 
    4 #ifdef __CINT__
    5 struct pthread_mutex_t;
    6 #else
    7 #include <pthread.h>
    8 #endif
     1#ifndef COSY_SdoList
     2#define COSY_SdoList
    93
    104#ifdef __CINT__
     
    148#include <TROOT.h>
    159#include "gendef.h"
     10#endif
     11
     12#ifndef ROOT_TMutex
     13#include <TMutex.h>
    1614#endif
    1715
     
    3634    PendingSDO *fLast;
    3735
    38     pthread_mutex_t fMux;
     36    TMutex fMux;
    3937
    4038public:
  • trunk/MagicSoft/Cosy/candrv/vmodican.cc

    r2407 r2518  
    783783    arg.pm = pm;
    784784
    785     if (!Ioctl(DPM_WRITE_MBOX, &arg))
    786         return FALSE;
    787 
    788     return arg.rval;
     785    return Ioctl(DPM_WRITE_MBOX, &arg) ? arg.rval : 0;
    789786}
    790787
Note: See TracChangeset for help on using the changeset viewer.