📄 lifegrd.c
字号:
/***************************************************************************
lifegrd.c - description
-------------------
begin : Fri May 17 2002
copyright : (C) 2002 by Raphael Zulliger
email : zulli@hsr.ch
***************************************************************************/
/***************************************************************************
* *
* This library is Copyright (c) Raphael Zulliger <zulli@gmx.net>. *
* It is licensed under the GNU Library General Public License (LGPL). *
* *
***************************************************************************/
#include <lifegrd.h>
#include <def.h>
#include <general.h>
#include <canop.h>
#include <init.h>
#include <nmt.h>
#include <objacces.h>
#include <basiccan.h>
#include <timer.h>
// because of the notfallmodus....
#ifdef PIC_CAN
#include <p18c658.h>
#endif
s_heartbeat_entry heartBeatTable[COUNT_OF_HEARTBEAT_CONSUMER];
s_ourHeartBeatValues ourHeartBeatValues;
BOOL bErrorOccured;
void processReceivedNMTErrorControl( s_rx_buffer_message* canopenMessage )
{
BYTE prnec_i;
for( prnec_i=(BYTE)0x00; prnec_i<(BYTE)COUNT_OF_HEARTBEAT_CONSUMER; prnec_i++ )
{ // for every possibly configured heartbeat prodcuer, check wheter we are a consumer
// check if the id is correct and check whetere the heartbeat is enabled (should_time != (BYTE)0x00) or
// disabled (should_time == (BYTE)0x00)
if( ( heartBeatTable[prnec_i].id == (WORD)(canopenMessage->m.cob_id.w) ) && ( heartBeatTable[prnec_i].should_time > (WORD)0x0000 ) )
{// the acutally checked message we received was configured in the object dictionary... so check wheter
// the heartbeat message was sent within the correct time
// so lets reset the time!
setTime( &heartBeatTable[prnec_i].time, (BYTE)0x0000 );
if( bErrorOccured == TRUE )
lifeguardCallback( (BYTE)CONNECTION_OK );
}
}
}
void processLifeGuard( void )
{
BYTE plg_i;
Message plg_m;
WORD time;
// now we have to check if one or more heartbeat messages haven't been received
// within the configured time. if this is the case, we have to call
// lifeguardCallback( ) with the argument LOST_HEARTBEAT_MESSAGE
for( plg_i=(BYTE)0x00; plg_i<(BYTE)COUNT_OF_HEARTBEAT_CONSUMER; plg_i++ )
{
if( heartBeatTable[plg_i].should_time > (WORD)0x0000 )
{ // this heartbeat-consumer is configured
time = getTime( &(heartBeatTable[plg_i].time) );
if( heartBeatTable[plg_i].should_time < time )
{
setTime( &heartBeatTable[plg_i].time, (WORD)0x0000 );
lifeguardCallback( (BYTE)HEARTBEAT_CONSUMER_LOST );
}
}
}
if( ourHeartBeatValues.ourShouldTime != (WORD)0x0000 )
{ // if the value is 0, heartbeat is disabled
// last but not least, check wheter we have to send OUR heartbeat message...
// before i tried to check with the use of ourHeartBeatValues.ourLastTime, but this failed due to
// undefined values of ourLastTime... but i really don't know why...
time = getTime( &ourHeartBeatValues.ourTime );
// Two possibilities: either we "look in the future" and decide wheter we would have
// to send a heartbeat within the next loop -> the heartbeat is always sent to fast.
// or we always send the heartbeat to late...
if( ( time > ourHeartBeatValues.ourShouldTime ) || ( ( (WORD)(time << (WORD)0x0001) - ourHeartBeatValues.ourLastTime ) >= ourHeartBeatValues.ourShouldTime ) )
{ // send message immediately
// genearte the correct node-id: this is done by the offset 1792(decimal) and additionaly
// the node-id of this device.
plg_m.cob_id.w = (WORD)(bDeviceNodeId + (WORD)0x700);
plg_m.len = (BYTE)0x01;
plg_m.data[0] = bStateMachineState;
// send the heartbeat
canSend( (BYTE)0x00, &plg_m );
// reset the timers...
setTime( &(ourHeartBeatValues.ourTime), (WORD)0x0000 );
ourHeartBeatValues.ourLastTime = (WORD)0x0000;
}
else
{
ourHeartBeatValues.ourLastTime = getTime( &(ourHeartBeatValues.ourTime) );
}
}
}
void lifeguardInit(void)
{
BYTE li_i;
BYTE XHUGE* XDATA pbConsumerHeartbeatCount;
DWORD XHUGE* XDATA pbConsumerHeartbeatEntry;
WORD XHUGE* XDATA pbProducerHeartbeatEntry;
DWORD XDATA* pdwSize;
DWORD XDATA dwSize;
pdwSize = &dwSize;
// first: we get all necessary values of the devices we are a heartbeat consumer... (this means: we have to
// check, wheter the device is still running or not
// first we have to get the count of entries. this count shows of how many heartbeat producers this device
// is the hearbeat consumer.
if( getODEntry( (WORD)0x1016, (BYTE)0x0, (void XHUGE* XDATA*)&pbConsumerHeartbeatCount, pdwSize ) == SUCCESSFUL )
{
// first set all values to 0
for( li_i=(BYTE)0x00; li_i<(BYTE)COUNT_OF_HEARTBEAT_CONSUMER; li_i++ )
{
// this disables the heartbeat
heartBeatTable[li_i].should_time = (WORD)0x00;
}
// for each of this entries, check wheter we are a consumer of this cob_id
for( li_i=(BYTE)0x00; li_i<(BYTE)*pbConsumerHeartbeatCount; li_i++ )
{
// get the time in [ms] within a new heartbeat has to be arrived
// add 1 to i, because subindex 0 is the count, which we have read just before.
if( getODEntry( (WORD)0x1016, (BYTE)li_i + (BYTE)1, (void XHUGE* XDATA*)&pbConsumerHeartbeatEntry, pdwSize ) == SUCCESSFUL )
{
if( (WORD)( (*pbConsumerHeartbeatEntry) & (DWORD)0x0000FFFF ) != (WORD)0x0 )
{ // if the time is set to 0, the entry is disabled
// The id is written within the bits 23-16
// 0x700 is the "offset" for the heartbeat messages...
heartBeatTable[li_i].id = ( ((*pbConsumerHeartbeatEntry) & (DWORD)0x00FF0000) >> (BYTE)16 ) + (WORD)0x700;
// The time is written within the bits 15-0
heartBeatTable[li_i].should_time = (WORD)( (*pbConsumerHeartbeatEntry) & (DWORD)0x0000FFFF );
// set the actual time to 0, so the device don't assumes that it hasn't received a
// heartbeat message for a long time ;-)
setTime( &heartBeatTable[li_i].time, (WORD)0x0000 );
}
}
}
}
// first set our heartbeattime to 0, for case the getODEntry fails...
ourHeartBeatValues.ourShouldTime = (WORD)0x0000;
// store the values about OUR heartbeat in the appropriate variable
if( getODEntry( (WORD)0x1017, (BYTE)0, (void XHUGE* XDATA*)&pbProducerHeartbeatEntry, pdwSize ) == SUCCESSFUL )
{
ourHeartBeatValues.ourShouldTime = *pbProducerHeartbeatEntry;
setTime( &ourHeartBeatValues.ourTime, (WORD)0x0000 );
ourHeartBeatValues.ourLastTime = (WORD)0x0000;
}
bErrorOccured = FALSE;
}
void lifeguardCallback( BYTE bReason )
{
if( bReason == HEARTBEAT_CONSUMER_LOST )
{
bErrorOccured = TRUE;
}
else if( bReason == CONNECTION_OK )
{
bErrorOccured = FALSE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -