src/lifegrd.c
changeset 750 bfb63ff7106e
parent 669 50da44ebaf00
equal deleted inserted replaced
749:5cbb8e9ad67c 750:bfb63ff7106e
    37 #include "canfestival.h"
    37 #include "canfestival.h"
    38 #include "dcf.h"
    38 #include "dcf.h"
    39 #include "sysdep.h"
    39 #include "sysdep.h"
    40 
    40 
    41 
    41 
    42 void ConsumerHearbeatAlarm(CO_Data* d, UNS32 id);
    42 void ConsumerHeartbeatAlarm(CO_Data* d, UNS32 id);
    43 
    43 void ProducerHeartbeatAlarm(CO_Data* d, UNS32 id);
    44 
    44 UNS32 OnHearbeatProducerUpdate(CO_Data* d, const indextable * unused_indextable, UNS8 unused_bSubindex);
    45 void ProducerHearbeatAlarm(CO_Data* d, UNS32 id);
    45 
    46 
    46 void GuardTimeAlarm(CO_Data* d, UNS32 id);
    47 UNS32 OnHearbeatProducerUpdate(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex);
    47 UNS32 OnNodeGuardUpdate(CO_Data* d, const indextable * unused_indextable, UNS8 unused_bSubindex);
    48 
    48 
    49 /*!
    49 
    50 **
       
    51 **
       
    52 ** @param d
       
    53 ** @param nodeId
       
    54 **
       
    55 ** @return
       
    56 **/
       
    57 e_nodeState getNodeState (CO_Data* d, UNS8 nodeId)
    50 e_nodeState getNodeState (CO_Data* d, UNS8 nodeId)
    58 {
    51 {
    59   e_nodeState networkNodeState = Unknown_state;
    52   e_nodeState networkNodeState = Unknown_state;
    60   #if NMT_MAX_NODE_ID>0
    53   #if NMT_MAX_NODE_ID>0
    61   if(nodeId < NMT_MAX_NODE_ID)
    54   if(nodeId < NMT_MAX_NODE_ID)
    67 /*! 
    60 /*! 
    68 ** The Consumer Timer Callback
    61 ** The Consumer Timer Callback
    69 **
    62 **
    70 ** @param d
    63 ** @param d
    71 ** @param id
    64 ** @param id
       
    65  * @ingroup heartbeato
    72 **/
    66 **/
    73 void ConsumerHearbeatAlarm(CO_Data* d, UNS32 id)
    67 void ConsumerHeartbeatAlarm(CO_Data* d, UNS32 id)
    74 {
    68 {
    75   UNS8 nodeId = (UNS8)(((d->ConsumerHeartbeatEntries[id]) & (UNS32)0x00FF0000) >> (UNS8)16);
    69   UNS8 nodeId = (UNS8)(((d->ConsumerHeartbeatEntries[id]) & (UNS32)0x00FF0000) >> (UNS8)16);
    76   /*MSG_WAR(0x00, "ConsumerHearbeatAlarm", 0x00);*/
    70   /*MSG_WAR(0x00, "ConsumerHearbeatAlarm", 0x00);*/
    77 
    71 
    78   /* timer have been notified and is now free (non periodic)*/
    72   /* timer have been notified and is now free (non periodic)*/
    83   d->NMTable[nodeId] = Disconnected;
    77   d->NMTable[nodeId] = Disconnected;
    84   /*! call heartbeat error with NodeId */
    78   /*! call heartbeat error with NodeId */
    85   (*d->heartbeatError)(d, nodeId);
    79   (*d->heartbeatError)(d, nodeId);
    86 }
    80 }
    87 
    81 
    88 /*!
       
    89 **
       
    90 **
       
    91 ** @param d
       
    92 ** @param m
       
    93 **/
       
    94 void proceedNODE_GUARD(CO_Data* d, Message* m )
    82 void proceedNODE_GUARD(CO_Data* d, Message* m )
    95 {
    83 {
    96   UNS8 nodeId = (UNS8) GET_NODE_ID((*m));
    84   UNS8 nodeId = (UNS8) GET_NODE_ID((*m));
    97 
    85 
    98   if((m->rtr == 1) )
    86   if((m->rtr == 1) )
   131       /* The state is stored on 7 bit */
   119       /* The state is stored on 7 bit */
   132       e_nodeState newNodeState = (e_nodeState) ((*m).data[0] & 0x7F);
   120       e_nodeState newNodeState = (e_nodeState) ((*m).data[0] & 0x7F);
   133 
   121 
   134       MSG_WAR(0x3110, "Received NMT nodeId : ", nodeId);
   122       MSG_WAR(0x3110, "Received NMT nodeId : ", nodeId);
   135       
   123       
       
   124       /*!
       
   125       ** Record node response for node guarding service
       
   126       */
       
   127       d->nodeGuardStatus[nodeId] = *d->LifeTimeFactor;
       
   128 
   136       if (d->NMTable[nodeId] != newNodeState)
   129       if (d->NMTable[nodeId] != newNodeState)
   137       {
   130       {
   138         (*d->post_SlaveStateChange)(d, nodeId, newNodeState);
   131         (*d->post_SlaveStateChange)(d, nodeId, newNodeState);
   139         /* the slave's state receievd is stored in the NMTable */
   132         /* the slave's state receievd is stored in the NMTable */
   140         d->NMTable[nodeId] = newNodeState;
   133         d->NMTable[nodeId] = newNodeState;
   152           /* call post SlaveBootup with NodeId */
   145           /* call post SlaveBootup with NodeId */
   153 		  (*d->post_SlaveBootup)(d, nodeId);
   146 		  (*d->post_SlaveBootup)(d, nodeId);
   154       }
   147       }
   155 
   148 
   156       if( d->NMTable[nodeId] != Unknown_state ) {
   149       if( d->NMTable[nodeId] != Unknown_state ) {
   157         UNS8 index, ConsummerHeartBeat_nodeId ;
   150         UNS8 index, ConsumerHeartBeat_nodeId ;
   158         for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
   151         for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
   159           {
   152           {
   160             ConsummerHeartBeat_nodeId = (UNS8)( ((d->ConsumerHeartbeatEntries[index]) & (UNS32)0x00FF0000) >> (UNS8)16 );
   153             ConsumerHeartBeat_nodeId = (UNS8)( ((d->ConsumerHeartbeatEntries[index]) & (UNS32)0x00FF0000) >> (UNS8)16 );
   161             if ( nodeId == ConsummerHeartBeat_nodeId )
   154             if ( nodeId == ConsumerHeartBeat_nodeId )
   162               {
   155               {
   163                 TIMEVAL time = ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ;
   156                 TIMEVAL time = ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ;
   164                 /* Renew alarm for next heartbeat. */
   157                 /* Renew alarm for next heartbeat. */
   165                 DelAlarm(d->ConsumerHeartBeatTimers[index]);
   158                 DelAlarm(d->ConsumerHeartBeatTimers[index]);
   166                 d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHearbeatAlarm, MS_TO_TIMEVAL(time), 0);
   159                 d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHeartbeatAlarm, MS_TO_TIMEVAL(time), 0);
   167               }
   160               }
   168           }
   161           }
   169       }
   162       }
   170     }
   163     }
   171 }
   164 }
   172 
   165 
   173 /*! The Consumer Timer Callback
   166 /*! The Producer Timer Callback
   174 **
   167 **
   175 **
   168 **
   176 ** @param d
   169 ** @param d
   177 ** @param id
   170 ** @param id
       
   171  * @ingroup heartbeato
   178 **/
   172 **/
   179 void ProducerHearbeatAlarm(CO_Data* d, UNS32 id)
   173 void ProducerHeartbeatAlarm(CO_Data* d, UNS32 id)
   180 {
   174 {
   181   if(*d->ProducerHeartBeatTime)
   175   if(*d->ProducerHeartBeatTime)
   182     {
   176     {
   183       Message msg;
   177       Message msg;
   184       /* Time expired, the heartbeat must be sent immediately
   178       /* Time expired, the heartbeat must be sent immediately
   198     }else{
   192     }else{
   199       d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);
   193       d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);
   200     }
   194     }
   201 }
   195 }
   202 
   196 
       
   197 /**
       
   198  * @brief The guardTime - Timer Callback.
       
   199  * 
       
   200  * This function is called every GuardTime (OD 0x100C) ms <br>
       
   201  * On every call, a NodeGuard-Request is sent to all nodes which have a
       
   202  * node-state not equal to "Unknown" (according to NMTable). If the node has
       
   203  * not responded within the lifetime, the nodeguardError function is called and
       
   204  * the status of this node is set to "Disconnected"
       
   205  *
       
   206  * @param d 	Pointer on a CAN object data structure 
       
   207  * @param id
       
   208  * @ingroup nodeguardo
       
   209  */
       
   210 void GuardTimeAlarm(CO_Data* d, UNS32 id)
       
   211 {
       
   212   if (*d->GuardTime) {
       
   213     UNS8 i;
       
   214 
       
   215     MSG_WAR(0x00, "Producing nodeguard-requests: ", 0);
       
   216 
       
   217     for (i = 0; i < NMT_MAX_NODE_ID; i++) {
       
   218       /** Send node guard request to all nodes except this node, if the 
       
   219       * node state is not "Unknown_state"
       
   220       */
       
   221       if (d->NMTable[i] != Unknown_state && i != *d->bDeviceNodeId) {
       
   222 
       
   223         /** Check if the node has confirmed the guarding request within
       
   224         * the LifeTime (GuardTime x LifeTimeFactor)
       
   225         */
       
   226         if (d->nodeGuardStatus[i] <= 0) {
       
   227 
       
   228           MSG_WAR(0x00, "Node Guard alarm for nodeId : ", i);
       
   229 
       
   230           // Call error-callback function
       
   231           if (*d->nodeguardError) {
       
   232             (*d->nodeguardError)(d, i);
       
   233           }
       
   234 
       
   235           // Mark node as disconnected
       
   236           d->NMTable[i] = Disconnected;
       
   237 
       
   238         }
       
   239 
       
   240         d->nodeGuardStatus[i]--;
       
   241 
       
   242         masterSendNMTnodeguard(d, i);
       
   243 
       
   244       }
       
   245     }
       
   246   } else {
       
   247     d->GuardTimeTimer = DelAlarm(d->GuardTimeTimer);
       
   248   }
       
   249 
       
   250 
       
   251 
       
   252 }
       
   253 
       
   254 /**
       
   255  * This function is called, if index 0x100C or 0x100D is updated to
       
   256  * restart the node-guarding service with the new parameters
       
   257  *
       
   258  * @param d 	Pointer on a CAN object data structure 
       
   259  * @param unused_indextable
       
   260  * @param unused_bSubindex
       
   261  * @ingroup nodeguardo
       
   262  */
       
   263 UNS32 OnNodeGuardUpdate(CO_Data* d, const indextable * unused_indextable, UNS8 unused_bSubindex)
       
   264 {
       
   265   nodeguardStop(d);
       
   266   nodeguardInit(d);
       
   267   return 0;
       
   268 }
       
   269 
       
   270 
   203 /*! This is called when Index 0x1017 is updated.
   271 /*! This is called when Index 0x1017 is updated.
   204 **
   272 **
   205 **
   273 **
   206 ** @param d
   274 ** @param d
   207 ** @param unsused_indextable
   275 ** @param unused_indextable
   208 ** @param unsused_bSubindex
   276 ** @param unused_bSubindex
   209 **
   277 **
   210 ** @return
   278 ** @return
       
   279  * @ingroup heartbeato
   211 **/
   280 **/
   212 UNS32 OnHeartbeatProducerUpdate(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex)
   281 UNS32 OnHeartbeatProducerUpdate(CO_Data* d, const indextable * unused_indextable, UNS8 unused_bSubindex)
   213 {
   282 {
   214   heartbeatStop(d);
   283   heartbeatStop(d);
   215   heartbeatInit(d);
   284   heartbeatInit(d);
   216   return 0;
   285   return 0;
   217 }
   286 }
   218 
   287 
   219 /*!
       
   220 **
       
   221 **
       
   222 ** @param d
       
   223 **/
       
   224 void heartbeatInit(CO_Data* d)
   288 void heartbeatInit(CO_Data* d)
   225 {
   289 {
   226 
   290 
   227   UNS8 index; /* Index to scan the table of heartbeat consumers */
   291   UNS8 index; /* Index to scan the table of heartbeat consumers */
   228   RegisterSetODentryCallBack(d, 0x1017, 0x00, &OnHeartbeatProducerUpdate);
   292   RegisterSetODentryCallBack(d, 0x1017, 0x00, &OnHeartbeatProducerUpdate);
   230   d->toggle = 0;
   294   d->toggle = 0;
   231 
   295 
   232   for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
   296   for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
   233     {
   297     {
   234       TIMEVAL time = (UNS16) ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ;
   298       TIMEVAL time = (UNS16) ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ;
   235       /* MSG_WAR(0x3121, "should_time : ", should_time ) ; */
       
   236       if ( time )
   299       if ( time )
   237         {
   300         {
   238           d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHearbeatAlarm, MS_TO_TIMEVAL(time), 0);
   301           d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHeartbeatAlarm, MS_TO_TIMEVAL(time), 0);
   239         }
   302         }
   240     }
   303     }
   241 
   304 
   242   if ( *d->ProducerHeartBeatTime )
   305   if ( *d->ProducerHeartBeatTime )
   243     {
   306     {
   244       TIMEVAL time = *d->ProducerHeartBeatTime;
   307       TIMEVAL time = *d->ProducerHeartBeatTime;
   245       d->ProducerHeartBeatTimer = SetAlarm(d, 0, &ProducerHearbeatAlarm, MS_TO_TIMEVAL(time), MS_TO_TIMEVAL(time));
   308       d->ProducerHeartBeatTimer = SetAlarm(d, 0, &ProducerHeartbeatAlarm, MS_TO_TIMEVAL(time), MS_TO_TIMEVAL(time));
   246     }
   309     }
   247 }
   310 }
   248 
   311 
   249 /*!
   312 
   250 **
   313 void nodeguardInit(CO_Data* d)
   251 **
   314 {
   252 ** @param d
   315 
   253 **/
   316   RegisterSetODentryCallBack(d, 0x100C, 0x00, &OnNodeGuardUpdate);
       
   317   RegisterSetODentryCallBack(d, 0x100D, 0x00, &OnNodeGuardUpdate);
       
   318 
       
   319   if (*d->GuardTime && *d->LifeTimeFactor) {
       
   320     UNS8 i;
       
   321 
       
   322     TIMEVAL time = *d->GuardTime;
       
   323     d->GuardTimeTimer = SetAlarm(d, 0, &GuardTimeAlarm, MS_TO_TIMEVAL(time), MS_TO_TIMEVAL(time));
       
   324     MSG_WAR(0x0, "GuardTime: ", time);
       
   325 
       
   326     for (i = 0; i < NMT_MAX_NODE_ID; i++) {
       
   327       /** Set initial value for the nodes */
       
   328       if (d->NMTable[i] != Unknown_state && i != *d->bDeviceNodeId) { 
       
   329         d->nodeGuardStatus[i] = *d->LifeTimeFactor;
       
   330       }
       
   331     }
       
   332 
       
   333     MSG_WAR(0x0, "Timer for node-guarding startet", 0);
       
   334   }
       
   335 
       
   336 }
       
   337 
   254 void heartbeatStop(CO_Data* d)
   338 void heartbeatStop(CO_Data* d)
   255 {
   339 {
   256   UNS8 index;
   340   UNS8 index;
   257   for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
   341   for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
   258     {
   342     {
   260     }
   344     }
   261 
   345 
   262   d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);
   346   d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);
   263 }
   347 }
   264 
   348 
   265 /*!
   349 void nodeguardStop(CO_Data* d)
   266 **
   350 {
   267 **
   351   d->GuardTimeTimer = DelAlarm(d->GuardTimeTimer);
   268 ** @param heartbeatID
   352 }
   269 **/
   353 
       
   354 
       
   355 void lifeGuardInit(CO_Data* d)
       
   356 {
       
   357   heartbeatInit(d);
       
   358   nodeguardInit(d);
       
   359 }
       
   360 
       
   361 
       
   362 void lifeGuardStop(CO_Data* d)
       
   363 {
       
   364   heartbeatStop(d);
       
   365   nodeguardStop(d);
       
   366 }
       
   367 
       
   368 
   270 void _heartbeatError(CO_Data* d, UNS8 heartbeatID){}
   369 void _heartbeatError(CO_Data* d, UNS8 heartbeatID){}
   271 void _post_SlaveBootup(CO_Data* d, UNS8 SlaveID){}
   370 void _post_SlaveBootup(CO_Data* d, UNS8 SlaveID){}
   272 void _post_SlaveStateChange(CO_Data* d, UNS8 nodeId, e_nodeState newNodeState){}
   371 void _post_SlaveStateChange(CO_Data* d, UNS8 nodeId, e_nodeState newNodeState){}
   273 
   372 void _nodeguardError(CO_Data* d, UNS8 id){}
       
   373