Automotive and Embedded Networks

cancel
Showing results for 
Search instead for 
Did you mean: 

USB-8473s Write Queue overflow error

Hi

 

I'm using a USB-8473s for can communication on a test setup, once a while i get an BFF62008 (-1074388984) Write queue overflow error.

 

I use the frame API, I have set the send buffer size to 0. I have 2 programs which both use the same Ni-CAN simultaneously, (one program read the other one writes).

The writing program set the configuration and in a loop it calls ncWaitForState with NC_ST_READ_AVAIL.

 

The other program is then started and takes care of transmit.

 

some times i get write queue overflow error, but as far as I can find it should not happen when write queue length is set to 0.

 

What can be done to solve this problem (I can't combine the 2 programs that causes other problems).

The code is written in c#.

 

 

René

0 Kudos
Message 1 of 12
(4,051 Views)

You set the write buffer to a size of zero and then are surprised when the write buffer becomes full?  I don't know the C side of things and don't have lots to suggest but that just seems like something that will always fail if it works the way you described.  Why do you want the buffer size to be set to 0?  These frames need time to go out, and the CAN bus is mean to be non-deterministic so you should have a buffer to allow time for things to go out.

0 Kudos
Message 2 of 12
(4,035 Views)

Hi

 

the reason for setting the queue to 0 length is this paragraph from the NI-can manual.

 

If an object write queue is full, a call to ncWrite returns the CanErrOverflowWrite error
and NI-CAN discards the data you provide. One way to avoid this overflow error is to set the
write queue length to zero. When ncWrite is called for a zero length queue, the data item
you provide with ncWrite simply overwrites the previous data item without indicating an
overflow.
0 Kudos
Message 3 of 12
(4,026 Views)

I'm unfamiliar with this feature since data loss is never anything I'd intentionally write into my application.  Someone from NI would be more equipped to tell you about how that feature works.

0 Kudos
Message 4 of 12
(4,017 Views)

Are you experiencing any bus errors when the write queue overflows? Specifically, is there a listening device to provide an Ack to the frame you are transmitting?

 

My current hypothesis is that the transmitting interface is not receiving an acknowledgement and will then try to re-transmit the frame per the CAN standard. During the re-transmission period, there may be a small window where a mutex prevents the new frame from overwriting the old frame in the queue and then generates the overflow error.

Jeff L
National Instruments
0 Kudos
Message 5 of 12
(4,016 Views)

Hi there are no bus errors, and when the error occures it will not go away again unless i close the connection completly down and repoen it (which will cause the device in the other end to time out).

I send the same telegrams cyclic every 100 ms (up to 18 different telegrams). All the sudden it will give me a write overflow, but when i happens I can see that i'm still receiving telegrams the other devices on the bus on the same Ni-CAN which gives me write error.

 

I have not tried to set the send buffer to a actual length, i'm thinking of trying that and see if that solves the problem. Any one who might have an idea what could cause the problem.

0 Kudos
Message 6 of 12
(4,003 Views)

Even though you have set up one to be the talker, and the other a listener, there is still some level of handshaking that needs to be accommodated.  CAN is fault tolerant and will send data out awaiting the other end to calculate the same checksum.  If it doesn't calculate the same, it will not pull the line low acknowledging a good package.  It will then await a re-send of the current data up to two more times before failing.  Are you using a 120-ohm controlled impedance cable between your two nodes?  Are you using the series terminating resistors at both ends?

Help the Community (and future reviewers) by marking posts as follows:
If it helped - KUDOS
If it answers the issue - SOLUTION
0 Kudos
Message 7 of 12
(3,998 Views)

I use 120 ohm resisters in each end of the cable. I am aware of the low lever can retry and ack.

 

The biggest problem is that when the error occures it does not go away again, it would not be a problem if the error came and went again.

I have tried to connect logger after the error has occured(just another can adapter to the bus), when I connect this (which is set to send ack) I can see the frames send by the remote party, but none of the telegrams from the NI-CAN are visible.

 

It occures very random.

 

It looks like a driver bug to me?

0 Kudos
Message 8 of 12
(3,992 Views)

In your first post you mention that the code is written in C#. Since NI-CAN only has a C API that implies that you have created a C# wrapper of some kind for the NI-CAN driver. If that is true we would need to rule out the wrapper code as a possible source of the problem.

 

Are you able to reproduce the problem using only the native C API? Can you post a copy of that application to see if we can reproduce the problem?

Jeff L
National Instruments
0 Kudos
Message 9 of 12
(3,982 Views)

Hi I don't do native C programming, so I can't tell. I can post the C# wrapper and the code.

 

A long verson of how the application work is:

The main c# application opens a connection with the Ni-CAN

int[] AttrIdList = new int[10];
int[] AttrValueList = new int[10];

AttrIdList[0] = NiCanFrameApi.NC_ATTR_BAUD_RATE;
AttrValueList[0] = baudrate;
//start communication when connect is send
AttrIdList[1] = NiCanFrameApi.NC_ATTR_START_ON_OPEN;
AttrValueList[1] = NiCanFrameApi.NC_TRUE;
//Set the length of the read queue to 150 frames
AttrIdList[2] = NiCanFrameApi.NC_ATTR_READ_Q_LEN;
AttrValueList[2] = 150;
//set the length of the write queue, when set to 0 the queue is disabled and only the latest telegram is transmitted
//it is set for 30 to make sure that one instance of all telegrams for one group will fit in the queue
AttrIdList[3] = NiCanFrameApi.NC_ATTR_WRITE_Q_LEN;
AttrValueList[3] = 30;
AttrIdList[4] = NiCanFrameApi.NC_ATTR_CAN_COMP_STD;
AttrValueList[4] = 0;
AttrIdList[5] = NiCanFrameApi.NC_ATTR_CAN_MASK_STD;
AttrValueList[5] = NiCanFrameApi.NC_CAN_MASK_STD_DONTCARE;
AttrIdList[6] = NiCanFrameApi.NC_ATTR_CAN_COMP_XTD;
AttrValueList[6] = 0;
AttrIdList[7] = NiCanFrameApi.NC_ATTR_CAN_MASK_XTD;
AttrValueList[7] = NiCanFrameApi.NC_CAN_MASK_XTD_DONTCARE;
//communication errors are logged as special error frame
AttrIdList[8] = NiCanFrameApi.NC_ATTR_LOG_COMM_ERRS;
AttrValueList[8] = NiCanFrameApi.NC_TRUE;
// Echo frames back to self
AttrIdList[9] = NiCanFrameApi.NC_ATTR_SELF_RECEPTION;
AttrValueList[9] = NiCanFrameApi.NC_TRUE;

var result = NiCanNative.ncConfig(m_prop.InterfaceName, AttrValueList.Length, AttrIdList, AttrValueList);
CheckForError(result);
int handle;
result = NiCanNative.ncOpenObject(m_prop.InterfaceName, out handle);
CheckForError(result);

 

 

I then spin a thread to listen for incomming packages, this thread runs in a loop.

var result = NiCanNative.ncWaitForState(Handle, NiCanFrameApi.NC_STATE_ENUM.NC_ST_READ_AVAIL, 100, out currentState);
//If it's just a timeout then this is expected
try
{
 if (result != -1074388991)
 {
  CheckForError(result);

  IList<NCTYPE_CAN_STRUCT> frames;
  result = NiCanNative.ncReadMultiple(Handle, 100, out frames);
  CheckForError(result);
  
  OnFrameReceived(frames);
 }
}
catch (NiCanException ex)
{
 //if the error code is invalid handle then just quit (the disconnect caused this)
 if (ex.ErrorCode == -1074388956)
 {
  try
  {
  //Disconnect will cause loop to exit
   Disconnect();
  }
  catch (Exception)
  {


  }

  return;
 }

 Error.WriteLine(ex);
 //pass the error on as an event
 OnErrorReceived(new ErrorReceivedEventArgs(ex));
}

 

 

After I have called the connect i also start another application which takes care of sending data on the bus, I had to make this 2 application contept because when the garbage collector in .net kicks in it will freeze all threads causing my transmit to stop for up to 150ms which is not accaptable.

The transmit application is told via sharedmemory what to send on the bus and how often. So the main application tells which telegram to send cyclic and how often.

 

The transmit application opens a connection to the same can controller.

 

status = Safe.ncOpenObject(name, out handle);
//only accept status 0x3ff62006 which is a warning telling that handle is already open
if (status == 0x3ff62006)
{
 //Start the transmit loop thread here
}

 

 

With in the transmit loop i check when i last send a telegram if it is due I will call

var status = Safe.ncWrite(m_handle, frame);

The connection stays open for a max of 30 min at a time, then a break for 10-30 minuttes then I open the connection again. this happes 24 hours a day. The error seems to happen roughly once to twice a day (some days it doens happen at all), and it doesn't seem to be at specific hours of the day.

Must of the time there is no problems, but once in while i get the writer buffer overflow, when it occures it does not go away again unless i disconnect and reconnect.

When I disconnect the transmit application is closed, and the connection is closed in the main application, a reconnect will perform the above steps all over again.

 

I run 2 can adapters on the same computer, there does not seem to be any difference if one or both adapters are connected simultaneously.

0 Kudos
Message 10 of 12
(3,978 Views)