?? canopen.cpp
字號:
}
hashMutex.Lock();
r = *searchHash( frame.id );
if( r )
r->NewFrame(frame);
hashMutex.Unlock();
}
}
/***************************************************************************/
/**
Default constructor for CanOpenSettings object.
This constructor simply sets all the settings to their default values.
*/
/***************************************************************************/
CanOpenSettings::CanOpenSettings( void )
{
readThreadPriority = 9;
}
/***************************************************************************/
/**
Default constructor for a CANopen receiver object.
*/
/***************************************************************************/
Receiver::Receiver( void )
{
// Whenever the receiver is disabled, we self reference with the
// next pointer. This is a quick way to identify an enabled receiver
next = this;
co = 0;
}
/***************************************************************************/
/**
Initialize a new CANopen receiver. After construction, the receiver will
be disabled. Call Enable() to allow messages to be received.
@param canOpen Reference to the CANopen network object that this receiver
is associated with.
@param id COB ID of the receive message
*/
/***************************************************************************/
Receiver::Receiver( CanOpen &canOpen, uint32 id )
{
next = this;
co = 0;
Init( canOpen, id );
}
/***************************************************************************/
/**
Destructor for CANopen receiver objects. This destructor ensures that the
receiver is disabled before it is destroyed.
*/
/***************************************************************************/
Receiver::~Receiver()
{
UnInit();
}
/***************************************************************************/
/**
Initialize the CANopen receiver object. This function should be called
before the receiver is used in any way. It can only be called once.
@param canOpen Reference to the CANopen network object that this receiver
is associated with.
@param id COB ID of the receive message
@return A pointer to an error object, or NULL on success.
*/
/***************************************************************************/
const Error *Receiver::Init( CanOpen &canOpen, uint32 id )
{
const Error *err = CanInterface::ChkID( id );
if( err ) return err;
DisableReceiver();
this->id = id;
co = &canOpen;
return 0;
}
/***************************************************************************/
/**
Un-initialize a CANopen receiver. This returns the receiver object to it's
uninitialized state.
@return A pointer to an error object, or NULL on success.
*/
/***************************************************************************/
const Error *Receiver::UnInit( void )
{
DisableReceiver();
co = 0;
return 0;
}
/***************************************************************************/
/**
Process a new received CAN bus frame. This virtual function is called by
the CANopen read thread every time a CAN frame is received over the network
with an ID matching the receivers ID if the receiver is enabled.
Note that this function is called from the CANopen receive thread. No other
receive frames will be processed until this function returns.
Also note that the map object used to associate message IDs with receive objects
is locked when this function is called. The locking is required to prevent a
race condition that could occur when a receive object is disabled and it's
memory is deallocated. Since the map is locked, it's illegal to Enable() or
Disable() any receive object from within this function.
@param frame The CAN frame to be processed. Note that the memory holding the
frame structure may be reused after the call returns. If the frame
contents are to be used after the return the a copy of the frame should
be made.
@return non-zero if the frame was handled, zero if the frame type was unknown.
*/
/***************************************************************************/
int Receiver::NewFrame( CanFrame &frame )
{
return 0;
}
/***************************************************************************/
/**
Return the receive COB ID associated with this CANopen message receiver.
@return The receive COB ID.
*/
/***************************************************************************/
uint32 Receiver::getRecvID( void )
{
return id;
}
/***************************************************************************/
/**
Enable reception of this message type. Once enabled, any messages received
over the CANopen network of this type will be passed to the Receiver
using the member function NewFrame.
@return A pointer to an error object, or NULL on success.
*/
/***************************************************************************/
const Error *Receiver::EnableReceiver()
{
if( !co ) return &CanOpenError::NotInitialized;
return co->EnableReceiver( this );
}
/***************************************************************************/
/**
Search a hash table of receiver objects associated with this network.
The CanOpen object maintains a hash of all enabled receivers on the
network. Each time a new CAN frame is received, the hash is searched for
a receiver matching the frame's ID. This function handles the details of
the search.
This function is also used when adding receivers to the tree. To aid this
use, it actually returns a pointer to a pointer to the receiver, or to the
place where the new receiver would be added.
Note, it's assumed that the hash mutex will be locked when this function
is called.
@param id The CAN message ID of the receiver to be found.
@return A pointer to a pointer to the receiver, or the location where the
receiver should be added if there is none with a matching ID.
*/
/***************************************************************************/
Receiver **CanOpen::searchHash( uint32 id )
{
int i = id % CML_HASH_SIZE;
Receiver **pp = &hash[i];
while( 1 )
{
if( !*pp )
return pp;
uint32 x = (*pp)->id;
if( id == x )
return pp;
pp = &( (*pp)->next);
}
}
/***************************************************************************/
/**
Enable reception handling of the message identified by this Receiver
object. The receiver is enabled by adding it to a binary tree of
receiver objects maintained by the CanOpen object.
@param rPtr Pointer to the receiver to add
@return A pointer to an error object, or NULL on success.
*/
/***************************************************************************/
const Error *CanOpen::EnableReceiver( Receiver *rPtr )
{
const Error *err = 0;
hashMutex.Lock();
Receiver **pp = searchHash( rPtr->id );
if( *pp )
err = &CanOpenError::RcvrPresent;
else
{
rPtr->next = 0;
*pp = rPtr;
}
hashMutex.Unlock();
return err;
}
/***************************************************************************/
/**
Disable reception handling of the message identified by this Receiver
object. Receivers are disabled by removing them from a binary tree of
receiver objects maintained by the CanOpen object.
@param rPtr A pointer to the receiver to disable.
@return A pointer to an error object, or NULL on success.
*/
/***************************************************************************/
const Error *CanOpen::DisableReceiver( Receiver *rPtr )
{
const Error *err = 0;
hashMutex.Lock();
Receiver **pp = searchHash( rPtr->id );
if( !*pp )
err = &CanOpenError::RcvrNotFound;
else
{
rPtr = *pp;
*pp = rPtr->next;
// Point the receiver back at itself.
// This allows the receiver to determine it's disabled.
rPtr->next = rPtr;
}
hashMutex.Unlock();
return err;
}
/***************************************************************************/
/**
Disable reception of this message type. Any CAN frames received by the
CANopen object of a disabled message type will be ignored by the CANopen
object.
@return A pointer to an error object, or NULL on success.
*/
/***************************************************************************/
const Error *Receiver::DisableReceiver()
{
if( !co ) return &CanOpenError::NotInitialized;
if( next == this ) return &CanOpenError::RcvrNotFound;
return co->DisableReceiver( this );
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -