Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

Union and Function Block

2018-05-19
2018-06-06
  • Hello,

    i am trying using a union of function block. I had some trouble accessing a function block (among the union) using pointer.

    I wonder if this is possible to use a union of function block (as it is not in the IEC 61131 standard)...

    Thank in advance for any help
    Sébastien

     
  • Anonymous - 2018-05-28

    Originally created by: scott_cunningham

    Can you explain what you are really trying to do that you feel a union of FB is the solution?

     
  • MarcDeOliveira - 2018-05-29

    Hello, I am working with Sebastien on this problem.

    We are currently dealing with a huge amount of Function blocks in our project. Indeed, We have an global array of STRUCT (5000 rows) and this STRUCT is made of 8 Function blocks. We would like to use a UNION instead of STRUCT to save memory space.
    Then we use POINTER on these STRUCT in the program to access the rows of the global array. But whenever we change the STRUCT into UNION, Codesys doesn't allow us to access the Function block.

    Here is an example of POINTER TO UNION that doesn't work on Codesys. Do you have any idea why it is not working ?

    FUNCTION_BLOCK Fb_Test_Union   //Empty Function block
    TYPE STR_Union_FB :
    UNION
       fb : Fb_Test_Union;
       i : INT;
    END_UNION
    END_TYPE
    VAR_GLOBAL
       str_TestUnion : STR_Union_FB;
       pt_TestUnion : POINTER TO STR_Union_FB;
    END_VAR
    pt_TestUnion := ADR(str_TestUnion);
    str_TestUnion.i := 5;      //OK
    str_TestUnion.fb();      //OK
    pt_TestUnion^.i := 5;      //OK
    pt_TestUnion^.fb();      //Cannot access the Function Block from the POINTER
    
     
  • Anonymous - 2018-05-29

    Originally created by: rickj

    Are you trying to overload FB of different types and then select 1 of the 8 types at runtime?

    I don't know for certain but I would expect that when an FB instance is created, some internal data is initialized. In which case the overlaying of multiple instances, into the same memory area, wouldn't work.

    If you want to save memory why not just have one instance of each different FB type and pass a reference to your data structure to the blocks?

     
  • MarcDeOliveira - 2018-05-30

    Yes I am overloading FB of different types in the same UNION and I select 1 of 8 types at runtime.
    But I only use one of these types at runtime so there is no memory area problem. Codesys can handle an UNION of FB.

    The problem happens whenever I use POINTER on this UNION. How is that different from no POINTER at all ?.
    If it's working without POINTER, it should work with POINTER as well. There might be something I missed in the understanding of UNION or POINTER.

     
  • Anonymous - 2018-05-30

    Originally created by: rickj

    I don't know why it wouldn't work different with pointer and no pointer, but I have a couple of ideas you could try.

    1. Use REFERENCE TO instead of POINTER TO. They are essentially the same thing but the compiler may see be more strict with one than the other.

    2. Create a base class FB and derive the other 8 from the base. If I remember correctly, the compiler will allow a pointer to the base type to be used with derived types. This may be enough persuade the compiler to cooperate.

    Let us know how it turns out.

     
  • MarcDeOliveira - 2018-05-31

    I tried to use REFERENCE TO but it is exactly the same problem as for POINTER TO.

    Then for the base class FB, I am not sure to quite understand what you mean. Because the 8 FB I use are not 8 instances from the same FB (They are different FB type). And how do I keep my 8 FB ? Still in a union or in another FB that derive a base class FB ?
    I am not that comfortable with Object oriented programming in Codesys, so if you could explain a little bit further.

    Thanks

     
  • Anonymous - 2018-05-31

    Originally created by: rickj

    You would create an empty FB; let's call it FbBase. Then when you declare your 8 function blocks add "EXTENDS FbBase" to the end of the declaration statement. Methods and parameters defined in FbBase will now be available to each of your 8 FBs.

    The compiler also now knows that it is intended for the 8 FBs to have some commonality. I don't know if this is enough to allow you to make a union with FB types. From my point of view, I would be concerned that overlaid function block instances would over-write internal data when instantiated. My approach would be to pass in a data structure and then call 1 of 8 methods to operate on that structure.

    Awhile back I wrote an article that explains some aspects of OOP. It may help you accomplish some of what you are attempting.

    PLC object-oriented programming benefits

     
  • MarcDeOliveira - 2018-06-05

    I tried what you advised me to do but the problem remains the same ...
    The data structure takes too much memory space so we would prefer avoiding it.
    Another solution would be the use of dynamic memory allocation right ?

     
  • Anonymous - 2018-06-06

    Originally created by: rickj

    Zitat:
    The data structure takes too much memory space so we would prefer avoiding it.

    I'm not sure what you are doing. I suggested that you create a data structure array containing the data on which you wish to operate, and passing that to a FB that determines for each element of the array which of the eight FBs should be used to process the element.

    If you don't have enough memory to hold the data upon which you wish to operate then the platform you have chosen would seem to be inadequate for your purpose.

    It's not necessary to create a FB instance for each element in the array as long as static data is stored in the data structure rather than in the FB itself. Specifically, variables declared within the main body of the FB are static in that they retain their values from execution cycle to execution cycle. If the FB is to be called for multiple elements in your data array then any such variables must be initialized or written before being used.

    Further, a function block doesn't make a copy of code; it only allocates memory for static variables and any internal system data needed to manage the FB at runtime.

     

Log in to post a comment.