ReadFD(TPCANHandle, TPCANMsgFD, TPCANTimestampFD)

PCAN-Basic

PCAN-Basic Documentation
Home
PreviousUpNext
ReadFD(TPCANHandle, TPCANMsgFD, TPCANTimestampFD)

Reads a CAN message and its time stamp from the receive queue of a FD capable PCAN Channel.

Syntax
class function ReadFD(
    Channel: TPCANHandle;
    var MessageBuffer: TPCANMsgFD;
    var TimestampBuffer: TPCANTimestampFD
    ):TPCANStatus; overload;
[DllImport("PCANBasic.dll", EntryPoint = "CAN_ReadFD")]
public static extern TPCANStatus ReadFD(
     [MarshalAs(UnmanagedType.U1)]
     TPCANHandle Channel,
     out TPCANMsgFD MessageBuffer,
     out TPCANTimestampFD TimestampBuffer);
[DllImport("PCANBasic.dll", EntryPoint = "CAN_ReadFD")]
static TPCANStatus ReadFD(
     [MarshalAs(UnmanagedType::U1)]
     TPCANHandle Channel,
     TPCANMsgFD %MessageBuffer,
     TPCANTimestampFD %TimestampBuffer);
<DllImport("PCANBasic.dll", EntryPoint:="CAN_ReadFD")> _
Public Shared Function ReadFD( _
     <MarshalAs(UnmanagedType.U1)> _
     ByVal Channel As TPCANHandle, _
     ByRef MessageBuffer As TPCANMsgFD, _
     ByRef TimestampBuffer As TPCANTimestampFD) As TPCANStatus
End Function
Parameters 
Description 
Channel 
The handle of a FD capable PCAN Channel (see TPCANHandle). 
MessageBuffer 
A TPCANMsgFD buffer to store the CAN message. 
TimestampBuffer 
A TPCANTimestampFD buffer to get the reception time of the message. 

The return value is a TPCANStatus code. PCAN_ERROR_OK is returned on success. The typical errors in case of failure are:

PCAN_ERROR_ILLPARAMVAL: 
Indicates that the parameters passed to the method are invalid. Check the value of the MessageBuffer; it should point to a TPCANMsgFD structure. 
PCAN_ERROR_ILLOPERATION: 
Indicates that the PCAN Channel passed to the method was not initialized using InitializeFD (plain function: CAN_InitializeFD). 
PCAN_ERROR_INITIALIZE: 
Indicates that the given PCAN channel was not found in the list of initialized channels of the calling application. 
PCAN_ERROR_BUSWARNING: 
Indicates a bus error within the given PCAN Channel. The hardware is in bus-warning status. 
PCAN_ERROR_BUSPASSIVE: 
Indicates a bus error within the given PCAN Channel. The hardware is in bus-passive status. 
PCAN_ERROR_BUSOFF: 
Indicates a bus error within the given PCAN Channel. The hardware is in bus-off status. 
PCAN_ERROR_QRCVEMPTY: 
Indicates that the receive queue of the Channel is empty. 

The use of Read and ReadFD are mutually exclusive. The PCAN Channel passed to this method must be initialized using InitializeFD (plain function: CAN_InitializeFD). Otherwise the error PCAN_ERROR_ILLOPERATION is returned. 

If the time when the message was received is not needed, use the overloaded ReadFD method. 

The ReadFD method returns received messages or status messages from the receive queue. It is important to call ReadFD repeatedly until the queue is empty. In case there are no more messages in queue, the value PCAN_ERROR_QRCVEMPTY is returned. The error code PCAN_ERROR_QRCVEMPTY is also returned if the reception of messages is disabled. See Receive Status Parameter for more information. 

The receive queue can contain up to 32767 messages. 

There are two possibilities for reading messages from the receive queue of a Channel: 

Time-Triggered Reading: Consists in periodically calls to the ReadFD method. Typically, an application start a timer that every 50 or 100 milliseconds check for messages, calling the ReadFD method in a loop until the value of PCAN_ERROR_QRCVEMTY or another error condition is reached. 

Event-Triggered Reading: Consists in reacting to a notification sent by the PCAN driver to a registered application, when a message is received and inserted in its receive queue. See Using Events to obtain more information about reading with events. 

About bus errors / Status messages 

If a bus-off error occur, an application cannot use the channel to communicate anymore, until the CAN controller is reset. With PCAN-Basic it is not possible to reset the CAN controller through a function directly. Consider using the PCAN-Basic property PCAN_BUSOFF_AUTORESET which instructs the API to automatically reset the CAN controller when a bus-off state is detected. 

Another way to reset errors like BUSOFF, BUSWARNING, and BUSPASSIVE, is to uninitialize and initialise again the channel used. This causes a hardware reset. 

The message type (see TPCANMessageType) of a CAN message indicates if the message is a 11-bit, 29-bit, FD, RTR, Error, or Status message. This value should be checked every time a message has been read successfully. 

If the bit PCAN_MESSAGE_ERRFRAME is set in the TPCANMsg.MSGTYPE field, the message is an Error frame (see Error Frames). 

If the bit PCAN_MESSAGE_STATUS is set in the TPCANMsg.MSGTYPE field, the message is a Status message. The ID and DLC fields do not contain valid data. The first 4 data bytes of the message contain the Error Code. The MSB of the Error Code is in data byte 0, the LSB is in data byte 3. If a status message was read the return value of ReadFD is also the error code. 

Examples:

Data0 
Data1 
Data2 
Data3 
Error 
Error Code 
Description 
00h 
00h 
00h 
02h 
PCAN_ERROR_OVERRUN 
0002h 
CAN controller has been read out too late. 
00h 
00h 
00h 
08h 
PCAN_ERROR_BUSWARNING 
0008h 
Bus error: An error counter reached the 'warning' limit. 
00h 
04h 
00h 
00h 
PCAN_ERROR_BUSPASSIVE 
40000h 
Bus error: the CAN controller is error passive. 
00h 
00h 
00h 
10h 
PCAN_ERROR_BUSOFF 
0010h 
Bus error: CAN Controller is in 'Bus Off' state. 

The following example shows the use of method ReadFD on the channel PCAN_USBBUS1. In case of failure, the returned code will be translated to a text (according with the operating system language) in English, German, Italian, French or Spanish, and it will be shown to the user. 

Note: It is assumed that the channel was already initialized using the method InitializeFD and that the following code is an OnTimer event handler method. 

C#:  

TPCANStatus result;
StringBuilder strMsg;
TPCANMsgFD msg;
TPCANTimestampFD time;

strMsg = new StringBuilder(256);

do
{
    // Check the receive queue for new messages
    //
    result = PCANBasic.ReadFD(PCANBasic.PCAN_USBBUS1, out msg, out time);
    if (result != TPCANStatus.PCAN_ERROR_QRCVEMPTY)
    {
        // Process the received message
        //
        MessageBox.Show("A message was received");
        ProcessMessage(msg);
    }
    else
    {
        // An error occurred, get a text describing the error and show it
        //
        PCANBasic.GetErrorText(result, 0, strMsg);
        MessageBox.Show(strMsg.ToString());
        // Here can be decided if the loop has to be  terminated (eg. the bus
        // status is  bus-off)
        //
        HandleReadError(result);
    }
// Try to read a message from the receive queue of the PCAN-USB, Channel 1,
// until the queue is empty
//
}while((result & TPCANStatus.PCAN_ERROR_QRCVEMPTY) != TPCANStatus.PCAN_ERROR_QRCVEMPTY);

C++CLR:

TPCANStatus result;
StringBuilder^ strMsg;
TPCANMsgFD msg;
TPCANTimestampFD time;

strMsg = gcnew StringBuilder(256);

do
{
    // Check the receive queue for new messages
    //
    result = PCANBasic::ReadFD(PCANBasic::PCAN_USBBUS1, msg, time);
    if (result != TPCANStatus::PCAN_ERROR_QRCVEMPTY)
    {
        // Process the received message
        //
        MessageBox::Show("A message was received");
        ProcessMessage(msg);
    }
    else
    {
        // An error occurred, get a text describing the error and show it
        //
        PCANBasic::GetErrorText(result, 0, strMsg);
        MessageBox::Show(strMsg->ToString());
        // Here can be decided if the loop has to be  terminated (eg. the bus
        // status is  bus-off)
        //
        HandleReadError(result);
    }
// Try to read a message from the receive queue of the PCAN-USB, Channel 1,
// until the queue is empty
//
}while((result & TPCANStatus::PCAN_ERROR_QRCVEMPTY) != TPCANStatus::PCAN_ERROR_QRCVEMPTY);

Visual Basic:

Dim result As TPCANStatus
Dim strMsg As StringBuilder
Dim msg As TPCANMsgFD
Dim time As TPCANTimestampFD

strMsg = New StringBuilder(256)

Do
    ' Check the receive queue for new messages
    '
    result = PCANBasic.ReadFD(PCANBasic.PCAN_USBBUS1, msg, time)
    If result <> TPCANStatus.PCAN_ERROR_QRCVEMPTY Then
        MessageBox.Show("A message was received")
        ProcessMessage(msg)
    Else
        ' An error occurred, get a text describing the error and show it
        '
        PCANBasic.GetErrorText(result, 0, strMsg)
        MessageBox.Show(strMsg.ToString())
        ' Here can be decided if the loop has to be  terminated (eg. the bus
        ' status is  bus-off)
        '
        HandleReadError(result)
    End If
' Try to read a message from the receive queue of the PCAN-USB, Channel 1,
' until the queue is empty
'
Loop While ((result And TPCANStatus.PCAN_ERROR_QRCVEMPTY) <> TPCANStatus.PCAN_ERROR_QRCVEMPTY)

Pascal OO:

var
    result : TPCANStatus;
    strMsg: array [0..256] of Char;
    msg: TPCANMsgFD;
    time: TPCANTimestampFD;
begin
    repeat
        // Check the receive queue for new messages
        //
        result := TPCANBasic.ReadFD(TPCANBasic.PCAN_USBBUS1, msg, time);
        If (result <> PCAN_ERROR_QRCVEMPTY) Then
        begin
            // Process the received message
            //
            MessageBox(0,'A message was received','Success', MB_OK);
            ProcessMessage(msg);
        end
        else
        begin
            // An error occurred, get a text describing the error and show it
            //
            TPCANBasic.GetErrorText(result, 0, strMsg);
            MessageBox(0, strMsg, 'Error',MB_OK);
            // Here can be decided if the loop has to be  terminated (eg. the bus
            // status is  bus-off)
            //
            HandleReadError(result);
        end;
    // Try to read a message from the receive queue of the PCAN-USB, Channel 1,
    // until the queue is empty
    //
    until ((TPCANStatus(Integer(result) AND Integer(PCAN_ERROR_QRCVEMPTY))) = PCAN_ERROR_QRCVEMPTY);

WriteFD 

Using Events 

Error Frames 

 

Plain function Version: CAN_ReadFD

Copyright © 2017. PEAK-System Technik GmbH. All rights reserved.
Send feedback to this documentation