Custom Data Types

I have been wanting to add custom data types to the system since the day I started working on it. I never worked on it because I wanted to get it functioning first. I have a friend that may start working on the HMI module and before he gets started on that monster, I wanted to make sure that most of the low level stuff was working. At least defined. The earlier these things are done the less stuff we'll have to change to add them later.

Right now I have a few functions inside the server that allow adding the datatype and adding members to the datatype. The members are allowed to be any of the base datatypes that are included in opendax as well as other custom data types. There aren't any messages yet and I haven't started on the library code.

In some ways this whole thing is far more complex than I thought it would be and in other ways it is simpler. I decided to use a linked list of datatype members and that turned out to be quite simple. I've also decided that all the logic to figure out where the information is inside the actual data area will reside in the library. This makes it simpler but will use up memory storing the datatype definitions in each module's RAM.

The datatype is defined by a linked list of members. These members can be any datatype, including other custom types. They can be arrays as well. I didn't want to have any limits on this. There is no built in limit for how deeply these can be nested or how large the arrays can be (well except for the 'int' used as the index. Is couple of Billion okay?).

Once the datatype is built it will be used as a template for defining tags based on that datatype. The tag will have a 'void *data' pointer to an area of memory that will be large enough to contain the whole tag. The data will be packed as well as it can be and I plan to have a #define for the byte alignment. I'm not sure that byte alignment will matter with most modern compilers but I may be getting into something that will cause me some portability issues. We'll see. Anyway it will be beneficial to put BOOLs together for instance, because they can all get packed into the same byte. It will be up to the module to use the datatype definition to determine where in the *data buffer the information is, and retrieve it. I decided to put all this in the library because i couldn't figure out a way to pass all the information back and forth to locate the member data within the main buffer, without the messaging getting complicated.

With the code in the library it helps take advantage of concurrency to help share the load. It will also make the socket messages simpler. It will cost us a little bit of RAM for the definitions to be stored in each modules data space, but there shouldn't be that many datatypes and eventually we can pursue a shared memory alternative for memory starved applications.

I wrote a function that serializes the definition of the custom datatype into a string. I decided to use a string to pass the definition to the modules. It will not be very efficient, but there shouldn't be that much traffic passing these definitions back and forth, and it should make a lot easier. Since most of the data is strings anyway it seemed to make sense.

Right now I just have the code written to create a new datatype, add members to an existing datatype and to convert from datatype names to the integer that represents them and back. I also wrote the serialization function.

Editing datatypes after tags have been created will be a problem. Currently, I am not allowing the members to be moved around or deleted within the datatype at runtime. I don't see any good reasons to do otherwise. Since the order of the members won't change I should be able to loop through all the tags and increase the size of the data buffer, when the definition has been changed. I'll have to see how efficient this will be. I may set some flags in the tag instead and then let the tag reading/writing logic grow the data area when the tag is accessed.

Eventually I could allow the datatype to be manipulated but then there will have to be some pretty smart code to make sure that the integrity of the data is maintained. There will also have to be a way to warn all the modules that the datatype has changed. It's never simple. Regardless, this will have to wait, I have enough to do simply getting it to work.