Automotive and Embedded Networks

cancel
Showing results for 
Search instead for 
Did you mean: 

Driver errors reported when trying to start objects

We have a standard PCI can card, and are developing in the following environment:


Software written in VC++ Version6,
running under NT4.0,
Port configured as 'CAN0',
using extended arbitration IDs.

We create one network interface object, and, depending on the test configuration, four CAN response objects.

The problems are :-
1) if the network interface object (nio) is configured as 'start on open'= TRUE then the other objects fail to initialise. If the other objects aren't started, the nio works perfectly though.

2) If the nio is configured not to start on open, the other objects will initialise successfully (obviously not a lot of use though).
Any attempt to call ncAction trying to start any of the objects will however fail with a status of 0xBFF62002, which is CanErrDriver.

Below is a stripped down set of events as to how we start our card.


AttrIdList[0] = NC_ATTR_BAUD_RATE;
AttrValueList[0] = 125000; //BaudRate;
AttrIdList[1] = NC_ATTR_START_ON_OPEN;
if( Response_Enabled == 0 )
{
AttrValueList[1] = NC_TRUE;
NotificationStates = (NC_ST_READ_AVAIL |
NC_ST_ERROR | NC_ST_WARNING | NC_ST_STOPPED);

}
else
{
AttrValueList[1] = NC_FALSE;
// don't look for stopped state else it
// will interrupt continuously.
NotificationStates =
(NC_ST_READ_AVAIL | NC_ST_ERROR |
NC_ST_WARNING);
}
AttrIdList[2] = NC_ATTR_READ_Q_LEN;
AttrValueList[2] = 50; //500;
AttrIdList[3] = NC_ATTR_WRITE_Q_LEN;
AttrValueList[3] = 20;
AttrIdList[4] = NC_ATTR_CAN_COMP_STD;
AttrValueList[4] = 0;
AttrIdList[5] = NC_ATTR_CAN_MASK_STD;
AttrValueList[5] = 0; // NC_CAN_MASK_STD_DONTCARE;
AttrIdList[6] = NC_ATTR_CAN_COMP_XTD;
AttrValueList[6] = 0;
AttrIdList[7] = NC_ATTR_CAN_MASK_XTD;
AttrValueList[7] = 0; // NC_CAN_MASK_XTD_DONTCARE;


// Configure the CAN Network Interface Object
Status = ncConfig(szCanObject, 8, AttrIdList,
AttrValueList);
CheckStatus(Status, "ncConfig");


CCanObject* pCanObject = new CCanObject;
pCanObject->m_phObject = new (NCTYPE_OBJH);
ASSERT (pCanObject->m_phObject != NULL);

Status = ncOpenObject(szCanObject,
pCanObject->m_phObject);
CheckStatus(Status, "ncOpenObject");

if (Status == 0) // object was
// successfully created
{
// add the CAN object to the list,
// indexed by name
m_CanObjectMap.SetAt(strObjectName,
pCanObject);

// create a string to identify the Notification
pCanObject->m_pszObjectName = new char[strObjectName.GetLength() + 1];
strcpy(pCanObject->m_pszObjectName, strObjectName);

// Create the notification used to store incoming frames.
// CanCallback will be called whenever a frame is available,
// a background error occurs, or no frame is received for 30 seconds.
// We pass a pointer to the global Queue data structure to the
// callback's RefData parameter.
Status = ncCreateNotification(
*(pCanObject->m_phObject),
NotificationStates,
NC_DURATION_INFINITE, //CAN_TIMEOUT
pCanObject->m_pszObjectName,
CanCallback); // name of callback fn

// check callback was installed
CheckStatus(Status, "ncCreateNotification");

******
at this point we kick off a timer for 200 msecs, and then carry on when the timer expires.
This allows the card to get itself settled.
******

This consists of checking configuration, and doing the following code for each of the response objects.
The things that change are the object names, the arbitration IDs, and the response data.

AttrIdList[0] = NC_ATTR_COMM_TYPE;
AttrValueList[0] = NC_CAN_COMM_TX_RESP_ONLY;
//failed bff62002 if objects set to 'start on open'

// All of the following are here as a result of testing.
// The setting above is the one that should eventually be used.
// Finally resolved by not using start-on-open above.
// AttrValueList[0] = NC_CAN_COMM_RX_UNSOL; //worked
// AttrValueList[0] = NC_CAN_COMM_RX_PERIODIC; //failed bff62005
// AttrValueList[0] = NC_CAN_COMM_RX_BY_CALL; //worked
/// AttrValueList[0] = NC_CAN_COMM_TX_PERIODIC; //worked - crashed with unhandled exception on closure though
// AttrValueList[0] = NC_CAN_COMM_TX_BY_CALL; //worked
// AttrValueList[0] = NC_CAN_COMM_TX_WAVEFORM; //worked - crashed with unhandled exception on closure though



// Specify watchdog timer period
AttrIdList[1] = NC_ATTR_BKD_PERIOD;
AttrValueList[1] = 1000;

// respond with DLC
AttrIdList[2] = NC_ATTR_BKD_READ_SIZE;
AttrValueList[2] = 0;
AttrIdList[3] = NC_ATTR_BKD_WRITE_SIZE;
AttrValueList[3] = DataLengthCode; // normally 3
AttrIdList[4] = NC_ATTR_CAN_TX_RESPONSE;
AttrValueList[4] = NC_TRUE;
/* This attribute is ignored for CAN Objects which transmit data. */
AttrIdList[5] = NC_ATTR_RX_CHANGES_ONLY;
AttrValueList[5] = NC_TRUE;
// maximum number of frames to hold in read queue
AttrIdList[6] = NC_ATTR_READ_Q_LEN;
AttrValueList[6] = 0;
// The write queue length is set to zero (queuing disabled).
// This means that for each request, the most recent data written
// using ncWrite will be transmitted in a Data Frame.
AttrIdList[7] = NC_ATTR_WRITE_Q_LEN;
AttrValueList[7] = 0;

// build the CAN object name
sprintf(szCanName, "%s::XTD0x%08lx", CanBus, ArbitrationId );
//*******
//*arbitration IDs normally used are
//*0x19008000,
//*0x19008001,
//*0x19008002
//*******



// configure the CAN object
Status = ncConfig(szCanName, ATTR_LIST_LEN, AttrIdList, AttrValueList);

// check for errors
CheckStatus(Status, szTemp);

// Open the transmitting CAN Object. The object starts up, but it
// will wait for the first call to ncWrite before it transmits a Data
// Frame.

CCanObject* pCanObject = new CCanObject;
pCanObject->m_phObject = new (NCTYPE_OBJH);
ASSERT (pCanObject->m_phObject != NULL);

Status = ncOpenObject(szCanName,
pCanObject->m_phObject);

CheckStatus(Status, szTemp);

if (Status == 0) // CAN object created successfully
{
// Store CAN bus information into object
pCanObject->m_strCanBusName = CanBus;
pCanObject->m_strCanName.Format("%s", szCanName);
pCanObject->m_ArbitrationID = ArbitrationId;

// add the CAN object to the list, indexed by name
// put data into output buffer
for (int i = 0; i < DataLengthCode; i++)
Transmit.Data[i] = DefaultData[i];

// setup CAN object output buffer
Status= ncWrite(*(pCanObject->m_phObject),
sizeof(Transmit), &Transmit);
CheckStatus(Status, "ncWrite");

// create a string to identify the Notification
pCanObject->m_pszObjectName = new char
[strObjectName.GetLength() + 1];
strcpy(pCanObject->m_pszObjectName,
strObjectName);

Status = ncCreateNotification(
*(pCanObject->m_phObject),
NC_ST_WRITE_SUCCESS,
NC_DURATION_INFINITE,
pCanObject->m_pszObjectName,
NotificationCallback);

// check callback was installed
CheckStatus(Status, "ncCreateNotification");

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

So, Any ideas what we're doing wrong ??

The cards were new in December 2001.
Software driver version installed is Version 1.5.1
It makes little difference which card we use, as we have many cards at this site in various pieces of test equipment, and I have tried at least 6 !

Things are beginning to get a little depserate here =:-/

Regards,
John Webster.
0 Kudos
Message 1 of 3
(4,170 Views)
Hi,

I took me a while to reproduce the error. I was using the Obj2obj.c example program and changing the attributtes to get the error.

The error occurs when using an extended arbitration ID and the NC_ATTR_CAN_COMP_XTD network object attribute is set to zero. The user manual specifies that since the CAN object are performing the communication, this attribute should be set to NC_CAN_ARBID_NONE. The error does not ocurr when using this constant. I also used 0 for the Network object read and write queues.

I'm still researching on the exact reasons why this error occurs. I'll let you know as soon as I get more info.

Diego F.
National Instruments
0 Kudos
Message 2 of 3
(4,170 Views)
Many thanks for the prompt reponse Diego.

A couple of comments on what you have written above.
The Response objects are only used for the 4 messages that need responses. All other messages are handled (received) by the Network Interface Object. Is it still therefore true to say that I should be using NC_CAN_ARBID_NONE ?

I think the answer will be yes, but want to confirm.


Am I correct to say that from your description, the only change was as belows :-
AttrValueList[2] = 0;
AttrValueList[3] = 0;
AttrValueList[6] = NC_CAN_ARBID_NONE;

Should I also be setting NC_ATTR_CAN_COMP_STD to NC_CAN_ARBID_NONE too ?

Many thanks for your help. This one has been causing us a lot of problems for a long time. I have changed many of the pa
rameters, but must admit I don't think I tried that one before.

Just off now to try this, see if it makes our code work !

Regards,
John.
0 Kudos
Message 3 of 3
(4,170 Views)