static Vstatus CleanUp(void) { ncdClosePort(gPortHandle); gPortHandle = INVALID_PORTHANDLE; ncdCloseDriver(); return VSUCCESS; // No error handling }
tcCanVector::~tcCanVector() { m_NbCarteChargee--; if(m_hLib!=NULL) { if (m_CartePresente) { // On vide la file d'emission hard ncdFlushTransmitQueue(m_gPortHandle,m_gChannelMask); // On désactive le canal if (m_InitOk) { ncdDeactivateChannel(m_gPortHandle,m_gChannelMask); } // On ferme le port Can if (m_gPortHandle != INVALID_PORTHANDLE) { ncdClosePort(m_gPortHandle); m_gPortHandle = INVALID_PORTHANDLE; } ncdCloseDriver(); } } }
bool CVectorObj::close( void ) { // Do nothing if already terminated if ( !m_bRun ) return false; m_bRun = false; ncdClosePort( m_portHandle ); m_portHandle = INVALID_PORTHANDLE; ncdCloseDriver(); UNLOCK_MUTEX( m_vectorMutex ); LOCK_MUTEX( m_vectorMutex ); // terminate the worker thread #ifdef WIN32 DWORD rv; // Wait for transmit thread to terminate while ( true ) { GetExitCodeThread( m_hTreadTransmit, &rv ); if ( STILL_ACTIVE != rv ) break; } // Wait for receive thread to terminate while ( true ) { GetExitCodeThread( m_hTreadReceive, &rv ); if ( STILL_ACTIVE != rv ) break; } #else int *trv; pthread_join( m_threadIdReceive, (void **)&trv ); pthread_join( m_threadIdTransmit, (void **)&trv ); pthread_mutex_destroy( &m_vectorMutex ); #endif return true; }
bool CVectorObj::open( const char *szFileName, unsigned long flags ) { Vstatus vErr; const char *p; unsigned long busspeed = 125; unsigned char btr0 = 0, btr1 = 0; char szDrvParams[ MAX_PATH ]; m_initFlag = flags; // save parameter string and conbert to upper case strncpy( szDrvParams, szFileName, MAX_PATH ); _strupr( szDrvParams ); // Initiate statistics m_stat.cntReceiveData = 0; m_stat.cntReceiveFrames = 0; m_stat.cntTransmitData = 0; m_stat.cntTransmitFrames = 0; m_stat.cntBusOff = 0; m_stat.cntBusWarnings = 0; m_stat.cntOverruns = 0; // if open we have noting to do if ( m_bRun ) return true; // Adapter type p = strtok( (char * )szDrvParams, ";" ); if ( NULL != p ) { if ( isalpha( *p ) ) { // Symbolic form int symidx = 0; while( -1 != vectorsymtbl[ symidx ]. id ) { if ( NULL != strstr( vectorsymtbl[ symidx ]. symname, p ) ) { m_nBrdType = vectorsymtbl[ symidx ]. id; break; } symidx++; } } else { // Numeric form m_nBrdType = atoi( p ); } } // Board Index p = strtok( NULL, ";" ); if ( NULL != p ) { if ( ( NULL != strstr( p, "0x" ) ) || ( NULL != strstr( p, "0X" ) ) ) { sscanf( p + 2, "%x", &m_idxBoard ); } else { m_idxBoard = atoi( p ); } } // channel p = strtok( NULL, ";" ); if ( NULL != p ) { if ( ( NULL != strstr( p, "0x" ) ) || ( NULL != strstr( p, "0X" ) ) ) { sscanf( p + 2, "%x", &m_channel ); } else { m_channel = atoi( p ); } } // Filter p = strtok( NULL, ";" ); if ( NULL != p ) { if ( ( NULL != strstr( p, "0x" ) ) || ( NULL != strstr( p, "0X" ) ) ) { sscanf( p + 2, "%x", &m_Vector_filter ); } else { m_Vector_filter = atol( p ); } } // Mask p = strtok( NULL, ";" ); if ( NULL != p ) { if ( ( NULL != strstr( p, "0x" ) ) || ( NULL != strstr( p, "0X" ) ) ) { sscanf( p + 2, "%x", &m_Vector_mask ); } else { m_Vector_mask = atol( p ); } } // Bus-Speed p = strtok( NULL, ";" ); if ( NULL != p ) { if ( ( NULL != strstr( p, "0x" ) ) || ( NULL != strstr( p, "0X" ) ) ) { sscanf( p + 2, "%x", &busspeed ); } else { busspeed = atol( p ); } } // Open the driver if ( ( vErr = ncdOpenDriver () ) ) return false; // get the number of channels int nChannels; vErr = ncdGetDriverConfig( &nChannels, NULL ); // Get channel index for requested card short idxChannel; if ( -1 == ( idxChannel = ncdGetChannelIndex( m_nBrdType, m_idxBoard, m_channel ) ) ) { ncdCloseDriver(); return false; } Vaccess initMask; if ( -1 == ( m_channelMask = ncdGetChannelMask( m_nBrdType, m_idxBoard, m_channel ) ) ) { ncdCloseDriver(); return false; } // Try to get init status for the channel if possible initMask = m_channelMask; char vectorChName[ MAX_APPNAME+1 ]; Vaccess permissionMask; sprintf( vectorChName, "vectordrv%i", m_drvidx ); if ( VERROR == ncdOpenPort( &m_portHandle, vectorChName, m_channelMask, initMask, &permissionMask, 1024 ) ) { ncdCloseDriver(); return false; } // if permission to initialize if ( permissionMask ) { VchipParams chipInit; chipInit.sjw = 1; chipInit.tseg1 = 4; chipInit.tseg2 = 3; chipInit.sam = 1; chipInit.bitRate = busspeed; if ( VERR_WRONG_PARAMETER == ncdSetChannelParams( m_portHandle, permissionMask, &chipInit ) ) { ncdClosePort( m_portHandle ); ncdCloseDriver(); return false; } // Open if passive mode if requested to do so if ( m_initFlag & 0x08 ) { ncdSetChannelOutput( m_portHandle, m_channelMask,OUTPUT_MODE_SILENT ); } else { ncdSetChannelOutput( m_portHandle, m_channelMask,OUTPUT_MODE_NORMAL ); } // Echo if ( m_initFlag & 0x04 ) { ncdSetChannelMode( m_portHandle, m_channelMask, 1, 0 ); } else { ncdSetChannelMode( m_portHandle, m_channelMask, 0, 0 ); } // Should error frames be suppressed if ( m_initFlag & 0x10 ) { ncdSetReceiveMode( m_portHandle,1, 1 ); } else { ncdSetReceiveMode( m_portHandle,0, 1 ); } } // set the acceptance filter VsetAcceptance acc; // standard acc.mask = 0x000; // Open for all acc.code = 0x000; ncdSetChannelAcceptance( m_portHandle, m_channelMask, &acc ); // extended acc.mask = 0x80000000; // Open for all acc.code = 0x80000000; ncdSetChannelAcceptance( m_portHandle, m_channelMask, &acc ); // User mask acc.mask = m_Vector_mask; acc.code = m_Vector_filter; ncdSetChannelAcceptance( m_portHandle, m_channelMask, &acc ); // Activate the channel ncdActivateChannel( m_portHandle, m_channelMask ); // Run run run ..... // (otional (for hard fellow rockers) "to the hills..." m_bRun = true; #ifdef WIN32 // Start write thread DWORD threadId; if ( NULL == ( m_hTreadTransmit = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) workThreadTransmit, this, 0, &threadId ) ) ) { // Failure close(); return false; } // Start read thread if ( NULL == ( m_hTreadReceive = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) workThreadReceive, this, 0, &threadId ) ) ) { // Failure close(); return false; } // Release the mutex UNLOCK_MUTEX( m_vectorMutex ); UNLOCK_MUTEX( m_receiveMutex ); UNLOCK_MUTEX( m_transmitMutex ); #else // LINUX pthread_attr_t thread_attr; pthread_attr_init( &thread_attr ); // Create the log write thread. if ( pthread_create( &m_threadId, &thread_attr, workThreadTransmit, this ) ) { syslog( LOG_CRIT, "canallogger: Unable to create vector write thread."); rv = false; fclose( m_flog ); } // Create the log write thread. if ( pthread_create( &m_threadId, &thread_attr, workThreadReceive, this ) ) { syslog( LOG_CRIT, "canallogger: Unable to create vector receive thread."); rv = false; fclose( m_flog ); } // We are open m_bOpen = true; // Release the mutex pthread_mutex_unlock( &m_vectorMutex ); #endif return true; }
//********************************************************************// // Reinit can card needed for BUS OFF by example //********************************************************************// void tcCanVector::ReinitCard() { m_CanCardMutex.Lock(); //---- Deactivate channel previously loaded ---- ncdDeactivateChannel(m_gPortHandle,m_gChannelMask); ncdClosePort(m_gPortHandle); m_gPortHandle = INVALID_PORTHANDLE; ncdCloseDriver(); //---- Initialise channel ----- int gHwType = m_ParamCan.Port>>8; // HWTYPE int gHwChannel = (m_ParamCan.Port&0xFF)%2; // 2 ports par carte int gHwIndex = (m_ParamCan.Port&0xFF)/2; // N° de carte Vstatus Statut; VsetAcceptance acc; Vaccess gPermissionMask = 0; m_gPortHandle = INVALID_PORTHANDLE; Statut = ncdOpenDriver(); if (Statut!=VSUCCESS) { char Buffer[256]; sprintf(Buffer,"tcCanVector::tcCanVector> Can driver failed (%04X)",Statut); SetMsg(cErrorMsg,Buffer); return; } // On cherche le masque du canal Cancardx d'index 0 et de canal Port m_gChannelMask = ncdGetChannelMask(gHwType,gHwIndex,gHwChannel); if (m_gChannelMask==0) { char Buffer[256]; sprintf(Buffer,"tcCanVector::tcCanVector> %s not found",m_ParamCan.CanCardName); SetMsg(cErrorMsg,Buffer); return; } gPermissionMask = m_gChannelMask; // On ouvre le port Statut = ncdOpenPort(&m_gPortHandle,"JCAE",m_gChannelMask,m_gChannelMask,&gPermissionMask,m_ParamCan.QueueRead); if (Statut!=VSUCCESS) { char Buffer[256]; sprintf(Buffer,"tcCanVector::tcCanVector> Can port failed (%04X)",Statut); SetMsg(cErrorMsg,Buffer); return; } if (gPermissionMask!=m_gChannelMask) { SetMsg(cErrorMsg,"tcCanVector::tcCanVector> Can card configuration unauthorized"); return; } // On configure la vitesse Statut = ncdSetChannelBitrate(m_gPortHandle,m_gChannelMask,m_ParamCan.BaudRate); if (Statut!=VSUCCESS) { char Buffer[256]; sprintf(Buffer,"tcCanVector::tcCanVector> Baudrate configuration failed (%04X)",Statut); SetMsg(cErrorMsg,Buffer); return; } // Change Ack Statut = ncdSetChannelOutput(m_gPortHandle,m_gChannelMask,(m_ParamCan.Spy==1)?OUTPUT_MODE_SILENT:OUTPUT_MODE_NORMAL); if (Statut!=VSUCCESS) { char Buffer[256]; sprintf(Buffer,"tcCanVector::tcCanVector> spy configuration failed (%04X)",Statut); SetMsg(cErrorMsg,Buffer); return; } // Inhiber les notifications TX et TXRQ Statut = ncdSetChannelMode(m_gPortHandle,m_gChannelMask,0,0); if (Statut!=VSUCCESS) { char Buffer[256]; sprintf(Buffer,"tcCanVector::tcCanVector> Tx and TXRQ disabling failed (%04X)",Statut); SetMsg(cErrorMsg,Buffer); return; } // On configure les masques d'acceptances acc.mask = m_ParamCan.MaskStd; // relevant=1 acc.code = m_ParamCan.CodeStd; Statut = ncdSetChannelAcceptance(m_gPortHandle,m_gChannelMask,&acc); if (Statut!=VSUCCESS) { char Buffer[256]; sprintf(Buffer,"tcCanVector::tcCanVector> STD Mask id configuration failed (%04X)",Statut); SetMsg(cErrorMsg,Buffer); return; } acc.mask = 0x80000000 | m_ParamCan.MaskXtd; // relevant=1 acc.code = 0x80000000 | m_ParamCan.CodeXtd; Statut = ncdSetChannelAcceptance(m_gPortHandle,m_gChannelMask,&acc); if (Statut!=VSUCCESS) { char Buffer[256]; sprintf(Buffer,"tcCanVector::tcCanVector> XTD Mask id configuration failed (%04X)",Statut); SetMsg(cErrorMsg,Buffer); return; } // On vide la queue de réception Statut = ncdFlushReceiveQueue(m_gPortHandle); if (Statut!=VSUCCESS) { char Buffer[256]; sprintf(Buffer,"tcCanVector::tcCanVector> Reception queue erasing failed (%04X)",Statut); SetMsg(cErrorMsg,Buffer); return; } // On vide la queue de transmission Statut = ncdFlushTransmitQueue(m_gPortHandle,m_gChannelMask); if (Statut!=VSUCCESS) { char Buffer[256]; sprintf(Buffer,"tcCanVector::tcCanVector> Emission queue erasing failed (%04X)",Statut); SetMsg(cErrorMsg,Buffer); return; } // On crée l'évènement pour recevoir m_gEventHandle = CreateEvent(NULL, FALSE, FALSE, NULL); Statut = ncdSetNotification(m_gPortHandle,(unsigned long*)&m_gEventHandle, 1); if (Statut!=VSUCCESS) { char Buffer[256]; sprintf(Buffer,"tcCanVector::tcCanVector> Reception event configuration failed (%04X)",Statut); SetMsg(cErrorMsg,Buffer); return; } // On active le canal Statut = ncdActivateChannel(m_gPortHandle,m_gChannelMask); if (Statut!=VSUCCESS) { char Buffer[256]; sprintf(Buffer,"tcCanVector::tcCanVector> Channel activation failed (%04X)",Statut); SetMsg(cErrorMsg,Buffer); return; } m_StatutReq = VSUCCESS; m_CanCardMutex.Unlock(); }