Automotive and Embedded Networks

cancel
Showing results for 
Search instead for 
Did you mean: 

CAN FD Read and Write frame using C API

Solved!
Go to solution

I am trying to setup communication using CAN FD.
I was able setup CAN communication with 8 byte payload (standard CAN frame with baud rate less than 1Mbs)
Now my next step is to use the CAN FD feature (max 64 byte payload and max 8 Mbps baud rate). To achieve this I have few questions with the setup of the API calls.

- Are my API calls for Read and Write frame called with correct parameters?
- How does ReadFrame account for large payload of data?

 

nxStatus_t                   ni_rc; 
nxSessionRef_t          inSession;
nxSessionRef_t          outSession ;
nxFrameCAN_t          ni_frame = {0}; 
u32                              numBytesReturned;

{//initial setup when ports are open for communication

//Create session for out stream with ":can_fd:" database name
ni_rc = nxCreateSession(":can_fd:", "", "", chanName,
                              nxMode_FrameOutStream, &outSession);

//Create session for in stream with ":can_fd:" database name
ni_rc = nxCreateSession(":can_fd:", "", "", chanName,
                              nxMode_FrameInStream, &inSession);


// Set property for outsession "nxPropSession_IntfBaudRate" and baudRate of 125K
ni_rc = nxSetProperty(outSession, nxPropSession_IntfBaudRate,
                            sizeof baudRate, &baudRate);

// Set property for outsession "nxPropSession_IntfCanFdBaudRate" and baudRate of 125K
ni_rc = nxSetProperty(outSession, nxPropSession_IntfCanFdBaudRate,
                            sizeof baudRate, &baudRate);
}

{
//Read Frame
ni_rc = nxReadFrame(inSession, &ni_frame, sizeof ni_frame,
                       0.005, &numBytesReturned);
}


{
//Write Frame
ni_rc = nxWriteFrame(outSession, &ni_frame, sizeof ni_frame, 0.500);
} 

Any help is appreciated.

 

Thanks,

 

Ashwin

 

 

0 Kudos
Message 1 of 20
(11,056 Views)

As far as I know, it looks like your read and write have the correct parameters. If it works with the CAN communication with the 8 byte payload, they should be the same. 

 

To account for the larger payload you would change a property to specify that you are using CAN FD. You would also need to set the baud rate property. 

 

Please see this documentation for background information: http://www.ni.com/white-paper/52288/en/

as well as this manual for detailed documentation: http://www.ni.com/pdf/manuals/372840h.pdf

 

On pages 114, 366, 147 of the manual above. 

 

Page 114 explains what needs to be configured and 366 and 147 discuss the properties further. 

Becca B.
Product Marketing
National Instruments
0 Kudos
Message 2 of 20
(11,018 Views)

Thanks for your reply beccamir. Based on reading C API documentation. (from the manual)

 

1) Setting baud rate property, following are some changes I did

 

nxStatus_t                   ni_rc; 
nxSessionRef_t          inSession;
nxSessionRef_t          outSession ;
nxFrameCAN_t          ni_frame = {0}; 
u32                              numBytesReturned;

{//initial setup when ports are open for communication

//Create session for out stream with ":can_fd_brs:" database name
ni_rc = nxCreateSession(":can_fd_brs:", "", "", chanName,
                              nxMode_FrameOutStream, &outSession);

//Create session for in stream with ":can_fd_brs:" database name
ni_rc = nxCreateSession(":can_fd_brs:", "", "", chanName,
                              nxMode_FrameInStream, &inSession);


// Set property for outsession "nxPropSession_IntfBaudRate" and baudRate of 125K. This sets my Arbitation phase baud rate. Right?
ni_rc = nxSetProperty(outSession, nxPropSession_IntfBaudRate,
                            sizeof baudRate, &baudRate);

// Set property for outsession "nxPropSession_IntfCanFdBaudRate" and baudRate of 125K. I think for this set property I can set baud rate max up to 8Mbps. Right?
ni_rc = nxSetProperty(outSession, nxPropSession_IntfCanFdBaudRate,
                            sizeof baudRate, &baudRate);
}

 

2) Sending payload of more than 8 bytes I am running into errors because of struct nxFrameCAN_t  "typedef nxFrameFixed_t(8) nxFrameCAN_t; " in "nixnet.h" so anything above 8 byte throws error.

Not sure if this is the right way of getting buffer out of nxReadFrame?

 

nxStatus_t                   ni_rc; 
nxSessionRef_t          inSession;
nxSessionRef_t          outSession ;
nxFrameCAN_t          ni_frame = {0}; 
u32                              numBytesReturned;

{
//Trying to Read Frame which has data of 16 bytes.
ni_rc = nxReadFrame(inSession, &ni_frame, sizeof ni_frame,
                       0.005, &numBytesReturned);
}


{
//Trying to Write Frame which has data of 16 bytes.
ni_rc = nxWriteFrame(outSession, &ni_frame, sizeof ni_frame, 0.500);
}

 

 

 

 

0 Kudos
Message 3 of 20
(11,014 Views)

mahajan24,

 

It looks correct. I am looking into this a bit more and it may end up being a little more involved. I have a couple questions in regards to your application:

 

What hardware are you using?

What version of the XNET driver are you using?

Which version of CVI are you using?

 

One suggestion I have is to look into the FlexRay examples as this protocol uses higher throughput than CAN. 

Becca B.
Product Marketing
National Instruments
0 Kudos
Message 4 of 20
(10,990 Views)

 

 

What hardware are you using? NI-PCI-8512/2

What version of the XNET driver are you using? driver version 15.0

Which version of CVI are you using? I am not using Labview or CVI for development. I am using Visual Studio 2012.

 

I will look at the FlexRay examples and see if that help.

0 Kudos
Message 5 of 20
(10,985 Views)

@mahajan24 wrote:

 

 

I will look at the FlexRay examples and see if that help.


That is a good idea. CAN FD will be more like FlexRay in that you must use variable length frames.

0 Kudos
Message 6 of 20
(10,983 Views)

 

After following some example for CAN and FlexRay. (I didn't find any FlexRay examples with more than 8 bytes payload)

 

For CAN FD the length of data is variable between 0-64 bytes. I have been using "nxFrameCAN_t" structure for my logic for read/write frame. This wont work as it would only handle 8 byte payload.

So if I went with the variable frame logic and use "nxFrameVar_t" instead with a max frame buffer of 512, how do I distinguish my frames in "nxReadFrame"?

 

Is there a CAN FD example with payload greater than 8 bytes using stream mode(in/out)?

0 Kudos
Message 7 of 20
(10,939 Views)

mahajan24,

 

Unfortunately there is not an example for CAN FD example in CVI.

 

What you could do is the following:

 

1. Go to the example in Visual Studio by going to All Programs>> National Instruments>> NI-XNET >> NI-XNET Examples in your start menu.

2. Open the CAN Frame Stream Input.c and CAN Frame Stream Output.c examples.

 

To get these to work with CAN FD, you can do the following:

 

1. In both the Input and Output files change the following:

- change the Baud rate from 125,000 to 250,000 under the global functions declaration area

-also in the global functions declaration section, change the database to ":can_fd:" from ":memory:"

-add a second nxSetProperty and change it to CAN FD. For example: g_Status = nxSetProperty(g_SessionRef,nxPropSession_IntfCanFdBaudRate,sizeof(u32),&l_Baud);

where l_Baud is the Baud Rate you changed above to 250,000

 

2. In the Write or Output file, you will have to make changes in the way you are writing in the loop. This is where you are actually writing the payload. For example:

for(i=0;i<64;i++)
{
l_MyFramePtr->Payload[i]=i;
}

 

Hopefully this information helps!!

 

where l_MyFramePtr->PayloadLength=64; where you set the frames parameters. 

 

 

Becca B.
Product Marketing
National Instruments
Message 8 of 20
(10,907 Views)

 

 

I am working on the same lines and using the Stream input and Stream output examples.

 

One question I have is when I use "nxFrameVar_t" the payload length (data array) is always max 8 bytes. So how should I accomodate data greater than 8 bytes into my frame (l_MyFramePtr)  ?

 

So if my "l_MyFramePtr->PayloadLength=64;" looping through payload array wont work as it would only accomodate initial 8 bytes.

 

 

 

 

0 Kudos
Message 9 of 20
(10,900 Views)

Create whatever sized array you need and just overlay it with the variable length struct (typecast) and you can fill it up. C allows for this.

0 Kudos
Message 10 of 20
(10,892 Views)