Read (FUN)ΒΆ

FUNCTION Read : CAA.HANDLE

Receives CAN or CAN FD messages from a receiver.

Note

To avoid losing receive messages an application has to read all messages of all receivers each cycle. All messages should be processed and released by FreeMessage afterwards.

Note

Normally a receiver returns CAA.gc_hINVALID if all messages are read by application.
But receivers with xAlwaysNewest = TRUE return always the newest message even if it was already received.
The application has to free the message each time it is returned by CL2.Read!!!
In case of an always newest receiver the data pctMsgLeft points to should be interpreted as follows:
0: old message; 1: new message; 2: message overflow

Example

VAR
    xInitialized : BOOL;
    hDriver : CAA.HANDLE;
    hReceiver : CAA.HANDLE;
    hMsg : CAA.HANDLE;
    ctMsgLeft : CAA.COUNT;
    pbyData : POINTER TO BYTE;
    usiDataLength : USINT;
    xFd : BOOL;
    xBRS : BOOL;
    xESI : BOOL;
    eError : CL2.ERROR;
END_VAR

IF NOT xInitialized THEN
    hDriver := CL2.DriverOpenH(usiNetId := 0,
                            uiBaudrate := 1000,
                            xSupport29Bits := FALSE,
                            ctMessages := 100,
                            peError := ADR(eError)
    );

    // Alternative:
    //hDriver := CL2.FdDriverOpenH(usiNetId := 0,
    //                            uiNominalBaudrate := 500,
    //                            uiDataBaudrate := 4000,
    //                            xSupport29Bits := FALSE,
    //                            ctMessages := 100,
    //                            peError := ADR(eError)
    //);

    //Create a MaskReceiver which receives all messages with CAN ID 16#80.
    hReceiver := CL2.CreateMaskReceiver(hDriver := hDriver,
                                        cobIdValue := 16#80, //cobID value
                                        cobIdMask := 16#FFFFFFFF, //cobID mask ==> all bits of value are relevant
                                        xRTRValue := FALSE, //no RTR messages
                                        xRTRMask := TRUE, //activate RTR filter ==> xRTRValue will be checked
                                        x29BitIdValue := FALSE, //no 29 bit CAN messages
                                        x29BitIdMask := TRUE, //activate 29 bit filter ==> x29BitIdValue will be checked
                                        xTransmitValue := FALSE, //only receive messages, no transmit message loopback
                                        xTransmitMask := TRUE, //activate transmit mask filter ==> xTransmitValue will be checked
                                        xAlwaysNewest := FALSE, //FALSE := receiver with queue; TRUE: only newest message
                                        eEvent := CB.EVENT.NO_EVENT, //no receive event
                                        xEnableSyncWindow := FALSE, //not implemented
                                        peError := ADR(eError) //optional pointer to error
    );

    IF hReceiver <> CAA.gc_hINVALID THEN
        xInitialized := TRUE;
    ELSE
        RETURN;
    END_IF
END_IF

REPEAT
    //receive a message from hReceiver
    hMsg := CL2.Read(hReceiverId := hReceiver, pctMsgLeft := ADR(ctMsgLeft), peError := ADR(eError));
    IF hMsg <> CAA.gc_hINVALID THEN
        //TODO: Process message, for example:
        pbyData := CL2.GetMessageDataPointer2(hMessage := hMsg, peError := ADR(eError));
        usiDataLength := CL2.GetMessageLength(hMessage := hMsg, peError := ADR(eError));
        //following code applies if hDriver is a CAN FD interface opened by FdDriverOpenH or FdDriverOpenP
        xFd := Cl2.IsFdMessage(hMessage := hMsg, peError := ADR(eError));
        IF xFd THEN
            //it's a CAN FD message
            xBRS := CL2.IsBitrateSwitchingBitEnabled(hFdMessage := hMsg, peError := ADR(eError));
            xESI := CL2.IsErrorStateIndicatorBitEnabled(hFdMessage := hMsg, peError := ADR(eError));
        END_IF
        //Processing finished

        CL2.FreeMessage(hMsg); //release message to avoid handle leak
        hMsg := CAA.gc_hINVALID;
    END_IF
UNTIL ctMsgLeft = 0
END_REPEAT
InOut:

Scope

Name

Type

Comment

Return

Read

CAA.HANDLE

handle of received CAN or CAN FD message or CAA.gc_hINVALID if receiver is empty.

Input

hReceiverId

CAA.HANDLE

receiver handle

pctMsgLeft

POINTER TO CAA.COUNT

Optional pointer to ctMsgLeft. After calling CL2.Read ctMsgLeft contains the number of remaining messages in receive queue.

peError

POINTER TO ERROR

optional pointer to error enum