GeorgScheidel
2008-03-03 16:40:09 UTC
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: 0x3FF6
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: 0x3FF6