0

I'm new to PLC programming and we need to create a library for a project. We need dynamically created function block instances during the runtime. There is a concept described on the codesys homepage: https://help.codesys.com/webapp/fb_factory;product=LibDevSummary;version=3.5.15.0

We tried to implement the example but without success. Unfortunately, there is no further information about the concept on the codesys homepage. Has anybody some advice how to dynamically create fb instances during the runtime on a plc?

Jkirchho
  • 3
  • 1

2 Answers2

1

When you want to create an instance of an FB dynamically you need first to put the following attribute above the FB-Declaration:

{attribute 'enable_dynamic_creation'}

Then you must make sure you are not calling __NEW(FB_NAME) cyclically.

Then you assign the result of __NEW(FB_NAME) to a pointer:

//Put this is the declaration section   
pfbName : POINTER TO FB_NAME;
//Your call to create a dynamic instance
pfbName := __NEW(FB_NAME);

If your pointer = 0 after __NEW returns, it means __NEW failed to allocate memory.

Filippo Boido
  • 1,136
  • 7
  • 11
  • What do you mean with method B? – Filippo Boido Sep 06 '20 at 07:13
  • Link provided by author of the question. __NEW is methor A to dynamicaly create FB, there is method B described. – Sergey Romanov Sep 07 '20 at 13:26
  • OK, now I get it..Can't tell, never used the FBFactory. But never had issues with __NEW either.The link provided says though, that there is a test project you can download to find out how FBFactory works if you are interested. – Filippo Boido Sep 07 '20 at 15:25
  • 1
    A few point to note when using __NEW: First of all, compatibility wise not all PLCs support this, though most modern probably will, but I only use a handful, so your mileage may vary. Secondly, you have to enable dynamic allocation in your application, and you must define a set size of memory that will be allocated for dynamic use. This means that that space will be unavailable for the rest of your app, and should your dynamic allocations exceed the predefined size, the allocations will fail. This is not ideal when working with devices with small memory size. – Guiorgy Sep 08 '20 at 12:44
  • And lastly, you will either have to use __DELETE to free memory when no longer needed, or force the PLC to reboot frequently (this frees all allocated memory), or both to keep your memory 'clean'. Thus, with all this in mind, unless absolutely necessary, I suggest avoiding dynamic allocation. Another alternative is to use references/pointers to FB/INTERFACE and have the initialization be done outside your library, where the user will provide that ref/pointer to you only when/if they need that FB. This is our preferred method btw – Guiorgy Sep 08 '20 at 12:44
  • In Beckhoff PLCs the standard amount of memory dedicated to dynamic memory is 32MB.This value can be easily changed in the project configurations.32MB of memory should be enough in most cases anyway though.. – Filippo Boido Sep 08 '20 at 13:41
  • Why I asked because in the same document method A is reffered as not ideal and method recommended. I also never used FBF would be mice to find an article with examples for that. – Sergey Romanov Sep 09 '20 at 04:24
  • I believe dynamic memory allocation differs between Beckhoff and Codesys. In Beckhoff, the dynamic memory is allocated from the memory pool of the AMS router which is a component unique to Beckhoff systems.The Dymanic memory available can be expanded to a maximum of 1024MB as of today.There is also no hint of memory fragmentation when using __New correctly in the Beckhoff documentation.By using it correctly I mean deleting the memory no longer needed with __Delete. – Filippo Boido Sep 09 '20 at 06:04
  • @FilippoBoido, support for the dynamic memory allocation, and the size allowed is PLC hardware and Firmware dependent as far as I know, at least that is true for Schneider (older PLC models, and those with small memory don't support it). As for __DELETE, programmers wouldn't be facing so many memory leaks if it was an easy thing to do, whether it is codesys or other languages. That's why languages like C# or Java with their Garbage Collectors are so popular for reliable applications, as they do all that memory management for you. Remember "whatever can go wrong, will go wrong." - Murphy's law – Guiorgy Sep 09 '20 at 10:46
  • @SergeyRomanov, [an example is available in the documentation](https://help.codesys.com/api-content/2/CAA_FBFactory/3.5.16.0/en/_downloads/FBFactoryTest.projectarchive). Though I haven't tried running it, after looking through the code, I think it just hides a lot of the memory management you would have to do, and does additional checks at every step to keep the memory 'clean'. You could probably just copy the code and avoid the Factory pattern, though you may have to write more code for each FB – Guiorgy Sep 09 '20 at 11:03
  • @Guiorgy you are right, but I'm obviously talking about plcs that can do dynamic memory creation and my two comments above specifically referred to Beckhoff Plc's (Twincat3).I also think that dynamic memory creation should be avoided when programming Plc's, also because you don't need it most of the times.For some tasks dynamic memory or instance creation is the more efficient and elegant solution though. – Filippo Boido Sep 09 '20 at 11:06
  • Example is onr thing, explanation of how it works another. – Sergey Romanov Sep 10 '20 at 13:30
0

I made a simple classic OOP Person, Teacher, Student example, here's a project file, or PLCOpenXML file. Basically, changing the value of numberOfTeachers inside PLC_PRG will cause the reinitializarion of the array people with the first numberOfTeachers entries being Teachers, and the rest being Students. You can look at the Device Logs where I write messages for creation/destruction of Teacher/Studemt.

PS. I am myself still exploring the possibilities of the Factory Design in CODESYS, so excuse me if I made any mistakes!

Update 23-03-16: Incorporated the suggested changes by ohraaa

Guiorgy
  • 1,405
  • 9
  • 26