Hallo,
Für unser Projekt wurde auf dem NETDCU8 ein DOS-Programm so angepasst, dass die Kommunikation mit
unserer Hardware über die CAN-Schnittstelle ohne Probleme funktionierte. Beim Umstieg auf den PicoCom1
wurden zwar CAN-Telegramme ausgegeben (HW reagierte) aber die Antworttelegramme wurden nicht eingelesen (Timeout).
Für Testzwecke habe ich das folgende vereinfachte Testprogramm auf Basis der bestehenden Funktionen geschreiben (NetDCU ok, Picocom1 mit Timeout beim Empfang)
Aufgefallen ist mir, dass beim Aufruf des Programms die Meldung: 'ETH: LookupRxBuffers : Error BNA!!' mehrfach auf der Debugschnittstelle
(COM3) ausgegeben wird. Besteht evtl. damit ein Zusammenhang und wie kann ich diesen Fehler beheben?
Wenn sie mir weiterhelfen könnten wäre ich ihnen sehr dankbar
aktuelle PICOCom1 Firmware:
Boot Loader, Version 1.1
PicoCOM1 V1.03 Build: Jul 30 2008/08:12:04
Sourcen
- int WINAPI WinMain( HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
- {
- test_can();
- return 0;
- }
- int test_can()
- {
- DWORD dwCount = 1000;
- OBJEKT obj_ptr;
- BYTE b[8]={0,0,0,0,0,0,0,0};
- DWORD dwBaud = 1000000;
- if(!CanADR[0].Init(_T("CID1:"),dwBaud))
- return(0);
- obj_ptr.id = 0x380;
- obj_ptr.dlc = 1;
- memcpy(obj_ptr.daten,b,8);
- write_bcan(0,&obj_ptr);
- do
- {
- if (read_bcan(1,0,&obj_ptr) == BCAN_OK)
- {
- obj_ptr.dlc = 1;
- memcpy(obj_ptr.daten,b,8);
- write_bcan(0,&obj_ptr);
- }
- Sleep(100);
- }while(dwCount--);
- return(0);
- }
- can_fun.c:
- CCAN CanADR[CAN_MAX];
- DWORD ErrorStatus[CAN_MAX]; //Fehlerspeicher
- OBJEKT objecT; //Zwischenspeicher für einkommende message
- char objectReceived = FALSE; //Zwischenspeicher gefüllt?
- /*----------------------------------------------------------------------
- **
- ** @func unsigned char | read_bcan | Objekt aus dem Controller auslesen und dabei den Timeout in ms abwarten<nl>
- **
- ** @parm unsigned short | timeout | Timeout in ms<nl>
- ** @parm unsigned char | net | Nummer des Netzwerks<nl>
- ** @parm OBJEKT * | obj_ptr | Zeiger für die Daten<nl>
- **
- ** @rdesc BCAN_ERR_ERROR - bei Fehler<nl>
- ** BCAN_OK - Daten eingelesen<nl>
- ** BCAN_ERR_OVER - event over run<nl>
- **
- */
- unsigned char read_bcan(unsigned short timeout,unsigned char net,OBJEKT *obj_ptr)
- {
- unsigned char status;
- CANMSG pcm;
- if (objectReceived) //zwischengespeicherte Daten?
- {
- obj_ptr->dlc = objecT.dlc; // Anzahl der Datenbytes
- obj_ptr->id = objecT.id; // Identifier
- obj_ptr->rtr = objecT.rtr; // RTR-Bit eintragen
- memcpy(obj_ptr->daten,objecT.daten,obj_ptr->dlc);
- objectReceived = FALSE;
- status = BCAN_OK;
- }
- else
- {
- status = BCAN_ERR_TIME;
- timer_1ms_start( timeout );
- do
- {
- switch (CanADR[net].ReadMessage(&pcm))
- {
- case CANBUS_EVENT_RECEIVED:
- obj_ptr->dlc = (unsigned char)(pcm.byDatalength); // Anzahl der Datenbytes
- obj_ptr->id = (unsigned short)(pcm.dwIdentifier); // Identifier
- obj_ptr->rtr = 0; // RTR-Bit eintragen
- memcpy(obj_ptr->daten,pcm.byContent,obj_ptr->dlc);
- status = BCAN_OK;
- break;
- case CANBUS_EVENT_OVERRUN:
- CanADR[net].ClearOverrun();
- status = BCAN_ERR_OVER;
- break;
- case CAN_ERROR:
- status = BCAN_ERR_ERROR;
- break;
- default:
- break;
- }
- }
- while( timer_1ms_laeuft() && (status == BCAN_ERR_TIME));
- }
- return(status);
- }
- /*----------------------------------------------------------------------
- **
- ** @func unsigned char | write_bcan | ein Objekt verschicken<nl>
- **
- ** @parm unsigned char | net | Nummer des Netzwerks<nl>
- ** @parm OBJEKT * | obj_ptr | Zeiger für die Daten<nl>
- **
- ** @rdesc Status<nl>
- **
- */
- unsigned char write_bcan(unsigned char net,OBJEKT *obj_ptr)
- {
- unsigned char status;
- CANMSG cm;
- timer_1ms_start( 10u ); // Timeout 10 ms
- do
- {
- switch (ReadTxStatus(net))
- {
- case 0 : // daten können gesendet werden
- memcpy(cm.byContent,obj_ptr->daten,8);
- cm.byDatalength = obj_ptr->dlc;
- cm.dwIdentifier = obj_ptr->id;
- CanADR[net].Write(&cm);
- status = BCAN_OK;
- break;
- case 1 : /* sendevorgang noch nicht beendet */
- case 2 : /* daten im empfangspuffer */
- status = BCAN_ERR_TIME;
- break;
- case 3 : /* BC-Error */
- status = BCAN_ERR_ERROR;
- break;
- default : /* overrun flag gesetzt ? softi stp */
- status = BCAN_ERR_OVER;
- CanADR[net].ClearOverrun();
- break;
- }
- }
- while( timer_1ms_laeuft() && (status != BCAN_OK));
- return(status);
- }
- /*----------------------------------------------------------------------
- **
- ** @func BYTE | ReadTxStatus | Die Funktion 'ReadTxStatus' liefert den Status über 'TransmitBCan'
- ** Wird ein BasicCan-Error zurückgeliefert, so kann das Statusregister aus
- ** der globalen Variable 'ErrorStatus[can_nr]' ausgelesen werden.<nl>
- **
- ** @parm unsigned char | can_nr | Nummer des angewählten CAN im Array CanADR[..]<nl>
- **
- ** @rdesc 0 --> Daten dürfen eingetragen/gesendet werden<nl>
- ** 1 --> Daten können noch nicht eingetragen werden, da Zugriff auf Transfer-Buffer gesperrt<nl>
- ** 2 --> Daten können nicht gesendet werden, da Receive-Buffer nicht frei<nl>
- ** 3 --> BasicCan-Error aufgetreten<nl>
- ** 4 --> nicht definiert<nl>
- **
- */
- BYTE ReadTxStatus( BYTE can_nr )
- {
- CANMSG pcm;
- BYTE nret;
- switch (CanADR[can_nr].ReadMessage(&pcm))
- {
- case 0: //no event
- case BCAN_ERR_TIME: //Daten können gesandt werden (eingangspuffer ist leer)
- nret = 0; //Daten dürfen gesendet werden
- break;
- case CANBUS_EVENT_TRANSMITTED:
- nret = 1;
- break;
- case CANBUS_EVENT_RECEIVED:
- nret = 2; //Receive-Buffer nicht frei -> Daten zwischenspeichern
- objecT.dlc = (unsigned char)(pcm.byDatalength); // Anzahl der Datenbytes
- objecT.id = (unsigned short)(pcm.dwIdentifier); // Identifier
- objecT.rtr = 0; // RTR-Bit eintragen
- memcpy(objecT.daten,pcm.byContent,objecT.dlc);
- objectReceived = TRUE; //Daten zwischengespeichert!
- break;
- case CAN_ERROR:
- ErrorStatus[can_nr] = GetLastError();
- nret = 3; //BasicCAN Error
- break;
- default:
- nret = 4; //event overrun?
- break;
- }
- return(nret);
- }
- ===================================================
- Änderungen in can.cpp aus cancheck-Demo:
- bool CCAN::Init(TCHAR* pszName, DWORD dwBaudrate)
- {
- if( m_hCAN != INVALID_HANDLE_VALUE )
- {
- CloseHandle( m_hCAN );
- }
- m_hCAN = CreateFile(pszName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
- DWORD dwMode=CANBUS_FORMAT_CAN_2_0_A;
- CAN_ACCEPTANCE_FILTER filter;
- filter.mask = 0x3FF;
- filter.code = 0x000;
- if( m_hCAN == INVALID_HANDLE_VALUE )
- return false;
- if(!DeviceIoControl( m_hCAN, IOCTL_CAN_INIT, NULL, 0, NULL, 0, NULL, NULL ))
- return false;
- if(!DeviceIoControl( m_hCAN, IOCTL_CAN_SET_CAN_MODE,&dwMode, sizeof(DWORD), NULL, 0, NULL, NULL ))
- return false;
- if(!SetFilter( &filter))
- return false;
- if(!SetBaudRate(dwBaudrate))
- return false;
- ::SetCommMask(m_hCAN,CANBUS_EVENT_RECEIVED|CANBUS_EVENT_BUS_ERROR|CANBUS_EVENT_WARNING);
- return true;
- }
- DWORD CCAN::ReadMessage( CANMSG* pcm )
- {
- DWORD dlc=0;
- DWORD dwEvent=0;
- DWORD dRet = 0;
- CAN_EVENT event;
- memset( &event, 0, sizeof( event ) );
- DWORD dw;
- if( DeviceIoControl( m_hCAN, IOCTL_CAN_READ_EVENT_DATA, NULL, NULL, &event, sizeof(CAN_EVENT), &dw, NULL ) )
- {
- // msg available
- if( event.event == CANBUS_EVENT_TRANSMITTED )
- {
- // check for lost message
- if( event.lost )
- {
- dRet = CAN_ERROR;
- }
- else
- dRet = CANBUS_EVENT_TRANSMITTED;
- }
- else if( event.event == CANBUS_EVENT_RECEIVED )
- {
- // new msg received. finish loop.
- pcm->dwIdentifier = event.data.identifier;
- pcm->byDatalength = event.data.dlc;
- memcpy( pcm->byContent, event.data.msg, pcm->byDatalength );
- dRet = CANBUS_EVENT_RECEIVED;
- }
- else if( event.event == CANBUS_EVENT_OVERRUN )
- dRet = CANBUS_EVENT_OVERRUN;
- }
- else
- {
- dRet = GetLastError();
- if (dRet == ERROR_NO_MORE_ITEMS)
- dRet = 0;
- else
- dRet = CAN_ERROR;
- }
- return (dRet);
- }