Ars
Ars

Reputation: 11

Bit Array in Codesys

I can assign different values to a bit variable with the array of bit structure in C. On the Codesys side, I am not allowed to define an array of bits in the structures. Is there a solution you can suggest to solve this problem?

Best regards

in C

struct {
            uint16_t reserved : 2;
            uint16_t reserved_0: 3;
} bits;

in codesys; this photo

Upvotes: 1

Views: 1501

Answers (2)

Guiorgy
Guiorgy

Reputation: 1734

As you can see, you can't define bit arrays in codesys. If you need bits in your structure, you either define them separately:

TYPE DUT1 :
STRUCT
    {attribute 'hide'}
    reserved1: BIT;
    {attribute 'hide'}
    reserved2: BIT;
    data1: BIT;
    data2: BIT;
    data3: BIT;
    data4: BIT;
    {attribute 'hide'}
    reserved3: BIT;
    {attribute 'hide'}
    reserved4: BIT;
END_STRUCT
END_TYPE

Note: The hide attribute is used to prevent them from being shown in the autocomplete:

Autocomplete suggestion where only data* appear and reserved* are missing

Or, you can combine them into a structure themselves:

TYPE DUT2 :
STRUCT
    {attribute 'hide'}
    reserved_before: Reserved2Bits;
    data1: BIT;
    data2: BIT;
    data3: BIT;
    data4: BIT;
    {attribute 'hide'}
    reserved_after: Reserved2Bits;
END_STRUCT
END_TYPE

However, if you do use a separate structure for that, the bits won't be compacted with the rest. In the above the size of DUT1 is 1 byte, and the size of DUT2 is 3 bytes (1 byte for each Reserved2Bits, and 1 byte for the data bits).

And finally, you can access bits directly on integer types, for example:

VAR
    bits: BYTE;
END_VAR

bits.2 := TRUE; // data1
bits.5 := FALSE; // data4

And instead of numbers you can use constants:

VAR
    bits: BYTE;
END_VAR
VAR CONSTANT
    data1: BYTE := 2;
    data2: BYTE := 3;
    data3: BYTE := 4;
    data4: BYTE := 5;
END_VAR

bits.data1 := TRUE;
bits.data4 := FALSE;

In the case above, you can skip defining reserved/unused bits entirely.

EDIT: Recently Codesys added VAR_GENERIC CONSTANT, which allows for the creation of Function Blocks with a constant integer inputs (kind of like C++ template arguments). This should make it possible to create a Function Block that takes an array_size constant/generic argument, and internally creates an array of bytes of size array_size / 8, and then takes a bite index as an input and outputs a bool with the value of the bite in the specified position, and similarly a way to set the value in a specific position.

Upvotes: 1

fadam
fadam

Reputation: 25

"On the other hand, bit access is significantly more time-consuming. Therefore, you should use the BIT data type only when you need to define data in a predefined format." https://content.helpme-codesys.com/en/CODESYS%20Development%20System/_cds_datatype_bit.html

BIT is a specific type to be used with care. You don't explain why you need your Array of BIT.If you don't need to store in a precise address, I suggest you use a bool array (coded on 8 bits). Else, follow Guiorgy's advice and use a byte or word and use "byte.1" to access directly to the bit you need.

If you need to arrange your data in a precise order, I suggest you also look at the alignment of the bytes in the structures. https://help.codesys.com/webapp/_cds_pragma_attribute_pack_mode;product=codesys;version=3.5.17.0

Upvotes: 0

Related Questions