Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
lifegrd.c
00001 /* 00002 This file is part of CanFestival, a library implementing CanOpen 00003 Stack. 00004 00005 Copyright (C): Edouard TISSERANT and Francis DUPIN 00006 00007 See COPYING file for copyrights details. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public 00020 License along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00022 USA 00023 */ 00024 00025 /*! 00026 ** @file lifegrd.c 00027 ** @author Edouard TISSERANT 00028 ** @date Mon Jun 4 17:19:24 2007 00029 ** 00030 ** @brief 00031 ** 00032 ** 00033 */ 00034 00035 #include <data.h> 00036 #include "lifegrd.h" 00037 #include "canfestival.h" 00038 #include "dcf.h" 00039 #include "sysdep.h" 00040 00041 00042 void ConsumerHearbeatAlarm (CO_Data* d, UNS32 id); 00043 00044 00045 void ProducerHearbeatAlarm (CO_Data* d, UNS32 id); 00046 00047 UNS32 OnHearbeatProducerUpdate(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex); 00048 00049 /*! 00050 ** 00051 ** 00052 ** @param d 00053 ** @param nodeId 00054 ** 00055 ** @return 00056 **/ 00057 e_nodeState getNodeState (CO_Data* d, UNS8 nodeId) 00058 { 00059 e_nodeState networkNodeState = d->NMTable[nodeId]; 00060 return networkNodeState; 00061 } 00062 00063 /*! 00064 ** The Consumer Timer Callback 00065 ** 00066 ** @param d 00067 ** @param id 00068 **/ 00069 void ConsumerHearbeatAlarm (CO_Data* d, UNS32 id) 00070 { 00071 UNS8 nodeId = (UNS8)(((d->ConsumerHeartbeatEntries[id]) & (UNS32)0x00FF0000) >> (UNS8)16); 00072 /*MSG_WAR(0x00, "ConsumerHearbeatAlarm", 0x00);*/ 00073 00074 /* timer have been notified and is now free (non periodic)*/ 00075 /* -> avoid deleting re-assigned timer if message is received too late*/ 00076 d->ConsumerHeartBeatTimers[id]=TIMER_NONE; 00077 00078 /* set node state */ 00079 d->NMTable[nodeId] = Disconnected; 00080 /*! call heartbeat error with NodeId */ 00081 (*d->heartbeatError)(d, nodeId); 00082 } 00083 00084 /*! 00085 ** 00086 ** 00087 ** @param d 00088 ** @param m 00089 **/ 00090 void proceedNODE_GUARD(CO_Data* d, Message* m ) 00091 { 00092 UNS8 nodeId = (UNS8) GET_NODE_ID((*m)); 00093 00094 if((m->rtr == 1) ) 00095 /*! 00096 ** Notice that only the master can have sent this 00097 ** node guarding request 00098 */ 00099 { 00100 /*! 00101 ** Receiving a NMT NodeGuarding (request of the state by the 00102 ** master) 00103 ** Only answer to the NMT NodeGuarding request, the master is 00104 ** not checked (not implemented) 00105 */ 00106 if (nodeId == *d->bDeviceNodeId ) 00107 { 00108 Message msg; 00109 UNS16 tmp = *d->bDeviceNodeId + 0x700; 00110 msg.cob_id = UNS16_LE(tmp); 00111 msg.len = (UNS8)0x01; 00112 msg.rtr = 0; 00113 msg.data[0] = d->nodeState; 00114 if (d->toggle) 00115 { 00116 msg.data[0] |= 0x80 ; 00117 d->toggle = 0 ; 00118 } 00119 else 00120 d->toggle = 1 ; 00121 /* send the nodeguard response. */ 00122 MSG_WAR(0x3130, "Sending NMT Nodeguard to master, state: ", d->nodeState); 00123 canSend(d->canHandle,&msg ); 00124 } 00125 00126 }else{ /* Not a request CAN */ 00127 /* The state is stored on 7 bit */ 00128 e_nodeState newNodeState = (e_nodeState) ((*m).data[0] & 0x7F); 00129 00130 MSG_WAR(0x3110, "Received NMT nodeId : ", nodeId); 00131 00132 if (d->NMTable[nodeId] != newNodeState) 00133 { 00134 (*d->post_SlaveStateChange)(d, nodeId, newNodeState); 00135 /* the slave's state receievd is stored in the NMTable */ 00136 d->NMTable[nodeId] = newNodeState; 00137 } 00138 00139 /* Boot-Up frame reception */ 00140 if ( d->NMTable[nodeId] == Initialisation) 00141 { 00142 /* 00143 ** The device send the boot-up message (Initialisation) 00144 ** to indicate the master that it is entered in 00145 ** pre_operational mode 00146 ** Because the device enter automaticaly in pre_operational 00147 ** mode, 00148 ** the pre_operational mode is stored 00149 ** NMTable[bus_id][nodeId] = Pre_operational 00150 */ 00151 MSG_WAR(0x3100, "The NMT is a bootup from node : ", nodeId); 00152 00153 if(!send_consise_dcf(d,nodeId)){ 00154 /* call post SlaveBootup with NodeId */ 00155 (*d->post_SlaveBootup)(d, nodeId); 00156 } 00157 } 00158 00159 if( d->NMTable[nodeId] != Unknown_state ) { 00160 UNS8 index, ConsummerHeartBeat_nodeId ; 00161 for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ ) 00162 { 00163 ConsummerHeartBeat_nodeId = (UNS8)( ((d->ConsumerHeartbeatEntries[index]) & (UNS32)0x00FF0000) >> (UNS8)16 ); 00164 if ( nodeId == ConsummerHeartBeat_nodeId ) 00165 { 00166 TIMEVAL time = ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ; 00167 /* Renew alarm for next heartbeat. */ 00168 DelAlarm(d->ConsumerHeartBeatTimers[index]); 00169 d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHearbeatAlarm , MS_TO_TIMEVAL(time), 0); 00170 } 00171 } 00172 } 00173 } 00174 } 00175 00176 /*! The Consumer Timer Callback 00177 ** 00178 ** 00179 ** @param d 00180 ** @param id 00181 **/ 00182 void ProducerHearbeatAlarm (CO_Data* d, UNS32 id) 00183 { 00184 if(*d->ProducerHeartBeatTime) 00185 { 00186 Message msg; 00187 /* Time expired, the heartbeat must be sent immediately 00188 ** generate the correct node-id: this is done by the offset 1792 00189 ** (decimal) and additionaly 00190 ** the node-id of this device. 00191 */ 00192 UNS16 tmp = *d->bDeviceNodeId + 0x700; 00193 msg.cob_id = UNS16_LE(tmp); 00194 msg.len = (UNS8)0x01; 00195 msg.rtr = 0; 00196 msg.data[0] = d->nodeState; /* No toggle for heartbeat !*/ 00197 /* send the heartbeat */ 00198 MSG_WAR(0x3130, "Producing heartbeat: ", d->nodeState); 00199 canSend(d->canHandle,&msg ); 00200 00201 }else{ 00202 d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer); 00203 } 00204 } 00205 00206 /*! This is called when Index 0x1017 is updated. 00207 ** 00208 ** 00209 ** @param d 00210 ** @param unsused_indextable 00211 ** @param unsused_bSubindex 00212 ** 00213 ** @return 00214 **/ 00215 UNS32 OnHeartbeatProducerUpdate (CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex) 00216 { 00217 heartbeatStop(d); 00218 heartbeatInit(d); 00219 return 0; 00220 } 00221 00222 /*! 00223 ** 00224 ** 00225 ** @param d 00226 **/ 00227 void heartbeatInit(CO_Data* d) 00228 { 00229 00230 UNS8 index; /* Index to scan the table of heartbeat consumers */ 00231 RegisterSetODentryCallBack(d, 0x1017, 0x00, &OnHeartbeatProducerUpdate ); 00232 00233 d->toggle = 0; 00234 00235 for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ ) 00236 { 00237 TIMEVAL time = (UNS16) ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ; 00238 /* MSG_WAR(0x3121, "should_time : ", should_time ) ; */ 00239 if ( time ) 00240 { 00241 d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHearbeatAlarm , MS_TO_TIMEVAL(time), 0); 00242 } 00243 } 00244 00245 if ( *d->ProducerHeartBeatTime ) 00246 { 00247 TIMEVAL time = *d->ProducerHeartBeatTime; 00248 d->ProducerHeartBeatTimer = SetAlarm(d, 0, &ProducerHearbeatAlarm , MS_TO_TIMEVAL(time), MS_TO_TIMEVAL(time)); 00249 } 00250 } 00251 00252 /*! 00253 ** 00254 ** 00255 ** @param d 00256 **/ 00257 void heartbeatStop(CO_Data* d) 00258 { 00259 UNS8 index; 00260 for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ ) 00261 { 00262 d->ConsumerHeartBeatTimers[index] = DelAlarm(d->ConsumerHeartBeatTimers[index]); 00263 } 00264 00265 d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer); 00266 } 00267 00268 /*! 00269 ** 00270 ** 00271 ** @param heartbeatID 00272 **/ 00273 void _heartbeatError (CO_Data* d, UNS8 heartbeatID){} 00274 void _post_SlaveBootup(CO_Data* d, UNS8 SlaveID){} 00275 void _post_SlaveStateChange(CO_Data* d, UNS8 nodeId, e_nodeState newNodeState){} 00276
Generated on Tue Jul 12 2022 17:11:51 by
1.7.2