Configuration:
I use the NICAN driver ver 2.3 to communicate with some devices over more CAN buses.
The application is developed with Visual C++ 6.0 and runs under Windows NT/2000/XP,
with an Intel Pentium 4 running at 2.8 GHz.
Four NICAN-PCI cards are installed, giving a total of eight CAN buses.
It seams not to matter, how many of the ports are connected and opened.
Problem:
Occasionaly my application is flooded with calls of the callback function.
Sometimes there are two short peeks of processor usage of 100% within 2-3 seconds, sometimes the processor usage remain at 100% until the port ist closed.
The problem seams to occur after a CAN bus is powered off, then powered on again.
The normal traffic on the lines is low - under 20 packets per second.
Code:
My callback function has nothing special.
It should be called only if data is available for read.
NCTYPE_STATE _NCFUNC_ NiCanCallback(NCTYPE_OBJH a_uiObjHandle, NCTYPE_STATE a_uiState, NCTYPE_STATUS a_iStatus, NCTYPE_ANY_P a_pRefData)
{
NCTYPE_STATE uiState = NC_ST_READ_AVAIL;
CNiCanLibInterface* pNiCanLibInterface;
CAN_FRM_DATA lCanFrmData;
// Typecast the pointer to appropriate type
pNiCanLibInterface = (CNiCanLibInterface*)thePack.gHandleToPtr.Get(a_uiObjHandle);
// If the data is available on the port
if( pNiCanLibInterface != NULL && (a_uiState & NC_ST_READ_AVAIL))
{
memset( &lCanFrmData, 0, sizeof(CAN_FRM_DATA) );
lCanFrmData.m_nLineNo = pNiCanLibInterface->m_iPortNo;
// Read the data from the port
LRESULT lrRetValue = pNiCanLibInterface->ReadPort(pNiCanLibInterface->m_iPortNo, &lCanFrmData);
if(lrRetValue == CAL_SUCCESS)
{
// Post the data as a user message to the thread in which this DLL is mapped
// VERY IMPORTANT: The thread should delete the data pointer which is passed as LPARAM
thePack.m_pApi->m_pInputQueue->AddPointer( &lCanFrmData );
if ( thePack.m_pApi->m_pCallerInfo->m_hReceiveEvent != NULL )
{
SetEvent(thePack.m_pApi->m_pCallerInfo->m_hReceiveEvent);
}
}
}
return uiState;
}
After the port is opened, a notification is created for reading:
iStatus = (*m_pDriverInfo->m_pncAction)(m_uiObjHandler, NC_OP_START, NULL);
if(iStatus == NC_SUCCESS)
{
m_pChanelData->m_bIsStarted = TRUE;
lrRetValue = CAL_SUCCESS;
// Register the required events for notifications
iStatus = (*m_pDriverInfo->m_pncCreateNotification)(m_uiObjHandler, NC_ST_READ_AVAIL, NC_DURATION_INFINITE, NULL, NiCanCallback);
if(iStatus == NC_SUCCESS)
{
// Store the thread ID. The received data messages will be sent to this thread.
m_dwThreadID = ::GetCurrentThreadId();
lrRetValue = CAL_SUCCESS;
}
else
{
//Close previously opened port if m_pDriverInfo->m_pncCreateNotification function call fails
ClosePort(m_iPortNo);
}
}
A sample of the NI Spy protocoll is attached.
The following message is continously repeated:
Invoking NI-CAN user callback (32376768, 1, 16546, 1073094668, 1),Prozess-ID: 0x00000AA0 Thread-ID: 0x00000C24,Startzeit: 10:22:58.502 Aufrufdauer: 00:00:00.000,Status: 0x3FF6200C,
Regards,
Georg