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 callingCL2.Read
ctMsgLeft
contains the number of remaining messages in receive queue.peError
POINTER TO ERROR
optional pointer to error enum