Frame API Additional Programming Topics

NI-CAN

Frame API Additional Programming Topics

The following sections include information you can use to extend the basic programming model.

RTSI

The Frame API provides RTSI features that are lower level than the synchronization features of the Channel API. The following list describes some of the more commonly used RTSI features in the Frame API.

  • You can configure the CAN Network Interface Object to log a special RTSI frame into the read queue when a RTSI input transitions from low to high. This RTSI frame is timestamped, so you can use it to analyze the time of the RTSI pulse relative to the CAN frames on the network.
  • You can configure the CAN Object to generate a RTSI output pulse when its ID is received. This allows you to trigger other products based on the reception of a specific CAN frame.
  • You can configure the CAN Object to transmit a CAN frame when a RTSI input transitions from low to high. This allows you to transmit based on a functional unit in another product, such as a counter in an NI-DAQ or NI-DAQmx E Series MIO product.
  • You can use ncConnectTerminals and the Timestamp Format attribute to synchronize multiple CAN cards by connecting timebases and start triggers. The ncConnectTerminals function provides additional RTSI features that can be used in conjunction with the object-based RTSI features described above.

For more information on RTSI configuration, refer to the ncConfig and ncConnectTerminals functions in this help file.

Remote Frames

The Frame API has extensive features to transmit and receive remote frames. The following list describes some of the more commonly used remote frame features in the Frame API.

  • The CAN Network Interface Object can transmit arbitrary remote frames.
  • If you are using Series 2 hardware or later, the CAN Network Interface Object can receive remote frames, such as to monitor bus traffic. Series 1 hardware uses the Intel 82527 CAN controller, which cannot receive arbitrary remote frames.
  • You can configure a CAN Object to transmit a remote frame and receive the corresponding data frame. The remote frame can be transmitted periodically, based on a RTSI input, or each time you call ncWrite.
  • You can configure a CAN Object to transmit a data frame in response to reception of the corresponding remote frame.

Using Queues

To maintain an ordered history of data transfers, NI-CAN supports the use of queues, also known as FIFO (first-in-first-out) buffers. The basic behavior of such queues is common to all NI-CAN objects.

There are two basic types of NI-CAN queues: the read queue and the write queue. NI-CAN uses the read queue to store incoming network data items in the order they arrive. You access the read queue using ncRead to obtain the data. NI-CAN uses the write queue to transmit network frames one at a time using the network interface hardware. You access the write queue using ncWrite to store network data items for transmission.

State Transitions

The NC_ST_READ_AVAIL state transitions from false to true when NI-CAN places a new data item into an empty read queue, and remains true until you read the last data item from the queue and the queue is empty.

The NC_ST_READ_MULT state transitions from false to true when the number of items in a queue exceeds a threshold. The threshold is set using the NC_ATTR_NOTIFY_MULT_LEN attribute. The NC_ST_READ_MULT state and ncReadMult function are useful in high-traffic networks in which data items arrive quickly.

The NC_ST_WRITE_SUCCESS state transitions from false to true when the write queue is empty and NI-CAN has successfully transmitted the last data item onto the network. The NC_ST_WRITE_SUCCESS state remains true until you write another data item into the write queue. When communication starts, the NC_ST_WRITE_SUCCESS state is true by default.

Empty Queues

For both read and write queues, the behavior for reading an empty queue is similar. When you read an empty queue, the previous data item is returned again. For example, if you call ncRead when NC_ST_READ_AVAIL is false, the data from the previous call to ncRead is returned again, along with the CanWarnOldData warning. If no data item has yet arrived for the read queue, a default data item is returned, which consists of all zeros. You should generally wait for NC_ST_READ_AVAIL prior to the first call to ncRead.

Full Queues

For both read and write queues, the behavior for writing a full queue is similar. When you write a full queue, NI-CAN returns the CanErrOverflowWrite error code. For example, if you write too many data items to a write queue, the ncWrite function eventually returns the overflow error.

Disabling Queues

If you do not need a complete history of all data items, you can disable the read queue and/or write queue by setting its length to zero. Zero length queues are typically used only with CAN objects, not the CAN Network Interface Object. Using zero length queues generally saves memory, and often results in better performance. When a new data item arrives for a zero length queue, it overwrites the previous item without indicating an overflow. The NC_ST_READ_AVAIL and NC_ST_WRITE_SUCCESS states still behave as usual, but you can ignore them if you want only the most recent data. For example, when NI-CAN writes a new data item to the read buffer, the NC_ST_READ_AVAIL state becomes true until the data item is read. If you only want the most recent data, you can ignore the NC_ST_READ_AVAIL state, as well as the CanWarnOldData warning returned by ncRead.

Using the CAN Network Interface Object with CAN Objects

For many applications, it is desirable to use a CAN Network Interface Object in conjunction with higher level CAN Objects. For example, you can use CAN objects to transmit data or remote frames periodically, and use the CAN Network Interface Object to receive all incoming frames.

When one or more CAN Objects are open, the CAN Network Interface Object cannot receive frames which would normally be handled by the CAN Objects. The following flowchart shows the steps performed by the Frame API when a CAN frame is received.

The decisions outlined in this flowchart are generally performed by the onboard CAN communications controller chip. Nevertheless, if you intend to use CAN Objects as the sole means of accessing the CAN bus, it is best to disable all frame reception in the CAN Network Interface Object by setting the comparator attributes to NC_CAN_ARBID_NONE (hex CFFFFFFF). By doing this, the CAN communications controller chip is best able to filter out all incoming frames except those handled by CAN Objects.

Detecting State Changes

You can detect state changes for an object using one of the following schemes:

  • Call ncWaitForState to wait for one or more states to occur.
  • Use ncCreateNotification in C/C++ to register a callback for one or more states.
  • Use ncCreateOccurrence in LabVIEW to create an occurrence for one or more states. The ncCreateOccurrence function is not supported by the 847x and 847x with Sync series CAN and LIN interfaces.
  • Call ncGetAttribute to get the NC_ATTR_STATE attribute.

Use the ncWaitForState function when the application must wait for a specific state before proceeding. For example, if you call ncWrite to write a frame, and the application cannot proceed until the frame is successfully transmitted, you can call ncWaitForState to wait for NC_ST_WRITE_SUCCESS.

Use the ncCreateNotification function in C/C++ when the application must handle a specific state, but can perform other processing while waiting for that state to occur. The ncCreateNotification function registers a callback function, which is invoked when the desired state occurs. For example, a callback function for NC_ST_READ_AVAIL can call ncRead and place the resulting data in a buffer. The application can then perform any tasks desired, and process the CAN data only as needed.

Use the ncCreateOccurrence function in LabVIEW when the application must handle a specific state, but can perform other processing while waiting for that state to occur. The ncCreateOccurrence function creates a LabVIEW occurrence, which is set when the desired state occurs. Occurrences are the mechanism used in LabVIEW to provide multithreaded execution.

Use the ncGetAttribute function when you need to determine the current state of an object.

Frame to Channel Conversion

Many applications require the ability to convert CAN data between a CAN frame and a CAN channel. For information on frame to channel conversion, channel to frame conversion, and virtual interfaces, refer to Frame to Channel Conversion.

Differences between CAN and LIN

When transitioning from CAN to LIN programming, it is helpful to note some differences between the two networks. Unlike CAN, there is no prioritization of LIN frames based on ID. Since LIN is a polled bus with the master initiating all frame transfers, there is no need for frame prioritization. Also unlike CAN, the number of data bytes in a LIN frame may not be zero, but is limited to the range of one to eight bytes. A LIN frame contains neither a data length code nor an end-of-frame delimiter. This means that when a slave task is receiving response data, it has either been configured with the number of bytes expected to be received for the current ID, or has no knowledge of how many bytes it will receive, which means it must use frame slot timeout or reception of next break to determine end-of-current-frame. Although CAN may operate somewhat similarly to a polled bus when using remote frames, its normal operational behavior does not fit that mode.

There is no concept of master and slave in CAN. Any device may transmit data or remote frames at any time. Collisions are acceptable and resolved by ID prioritization. When a data or remote frame is transmitted, the full frame is transmitted by the sender. In contrast, a single LIN master task is responsible for initiating all frame transfers. The master task only sends the first part of the frame (the header) with the expectation that a slave task will complete the frame (by publishing a response). CAN provides advanced mechanisms for reporting multiple errors within a single frame, incrementing or decrementing error counters, and entering various error states (bus off, for example). In contrast, LIN error handling is a single-shot process. Upon encountering the first error in a frame, the LIN slave device reports the error, ignores the remainder of the frame, and prepares for reception of the next header from the master task.