xPC Target    

CAN Bit-Packing Block

This block is used to construct CAN data frames and its output port is normally connected to an input port of a CAN Send driver block. The block has one output port of data type double (a scalar) which represents the data frame entity constructed by the signals entering the block at its input ports. The number of input ports and the data type of each input port depends on the setting in the blocks dialog box.

The dialog box contains one single control (edit field) which lets you define the bit patterns in a flexible way. The data type entered in the control has to be a MATLAB cell array vector. The number of elements in the cell array define the number of input ports shown by this block instance. The cell array elements have to be of type double array and define where each bit of the incoming value (data typed input port) comes to lie at what position in the outgoing double value (data frame).

From a data type perspective (input ports) the block behaves like a Simulink sink block and therefore the data types of the input ports are inherited from the driving blocks.

The sample time of the block is also inherited from the driving blocks. Therefore no explicit sample time has to be provided in the block's dialog box.

The functionality of the block is easiest explained by means of an example.

We assume that a node on the CAN network needs to receive a CAN message with identifier 156 having the following data frame content. The data frame has to be 6 bytes long.

Byte 0
Function class of type uint8
Byte 1
Function subclass of type uint8 with reversed bit order
Byte 2
Reserved, all bits have to be 1
Byte 3
Bit 0 has to be 0, Bit 1 has to be a boolean (flag), bits 2 to 7 have to be bit 2 to 7 of an incoming int8 value (control)
Byte 4 and 5
Value of type int16

The bit pattern cell array, which bit-packs the data frame according to the above specification, can look as follows.

And the Simulink model simulating the needed behavior would be as show below.

Let us analyze the model.

The first input is the Function class of type uint8, which has an example value of 112. This value has to become byte 0 (bits 0 to 7) of the data frame. Therefore the first bit (element 1 of double array [0:7]) has to get bit 0 of the data frame, the second bit 1 and so on. It is easiest to define this mapping by the MATLAB colon operator:.

The second input is the Function subclass of type uint8, which has an example value of 23. This value has to become byte 1 (bits 8:15) of the data frame but in reversed bit order. Therefore the first bit (element 1 of double array [15:-1:8]) has to get bit 15, the second bit 14 and so on. It is easiest to define this mapping by the MATLAB colon operator: and an increment of -1.

The third input is only necessary because the reserved byte 2 has to have all bits set to 1. If a bit position in the outgoing data frame isn't referenced by a bit pattern array element, the bit will be by default 0, but there is no construct to have them set to 1 as the default. Therefore a uint8 constant with value 255 has to be externally brought in. The constant 255 has to get to bit position 16 to 23 (byte 2) of the outgoing data frame.

Because bit 0 of data frame byte 3 (bit 24) has to be 0 and 0 is the default bit value if not referenced by a bit pattern array element, no explicit action has to be taken here.

The fourth input is the Flag of type boolean, which has an example value of 1. This value has to become bit 1 of byte 3 (bit 25) of the data frame. Therefore the single bit (element 1 of double array [25]) has to get bit 25 of the data frame.

The fifth input is the Control of type int8, which has an example value of 121. But only bits 2 to 7 have to be mapped into the outgoing data frame or in other words bits 0 and 1 have to be thrown away. Because indexing of incoming values always starts with the first bit (bit 0) a special indexing value (-1) has to be used in order to skip bit 0 and 1 of the incoming int8 value. Bits 2 to 7 will be directly mapped to bit 2 to 7 of byte 3 (bits 26 to 31) of the outgoing data frame. This leads to the following bit pattern: [-1,-1,26:31]

The sixth input is the Value of type int16, which has an example value of -12270. This value has to become byte 4 and 5 (bits 32 to 47) of the outgoing data frame. Therefore the first bit (element 1 of double array [32:47]) has to get bit 32 of the data frame, the second bit 33 and so on. It is easiest to define this mapping by the MATLAB colon operator:.

The output of the block then consists of a double value representing the packed data types within the first 6 bytes. The last two bytes are zero. This means that even in the case were less than 8 bytes are significant, the CAN data frame is always represented by a double value (8 bytes). The value of the constructed floating point double doesn't have any particular meaning but still can be inspected by a numerical display.

The data frame is then propagated to the CAN Send driver block and is sent out as part of a CAN-message having identifier 156. When looking at the Send block's dialog box, the data frame size is defined as 6 bytes. This makes sure that only the first 6 bytes of the incoming double value are transmitted as part of the CAN-message.


  Constructing and Extracting CAN Data Frames CAN Bit-Unpacking Block