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