⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lifegrd.c

📁 This library is Copyright (c) Raphael Zulliger <zulli@gmx.net>. It is licensed under the GNU L
💻 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 + -