518 views
in System Integration by
Hallo all,

in my GUI/Cora code I store information in a class object (e.g. Cooking Program Settings of an Oven). Now I need to pass this class / object to the Device in order to store this information in NVM and recall it later at next power up. The representation of this class is a C structure in native code. I'm struggling now how to copy resp. convert the contents of the Cora Object to the native C stucture and vice versa, since I can't access the native C struct in Cora and I also can't access the Object members inside the "native (..) { }" section.

Passing simple data types like int32 and string etc is described in "Device Integration" examples, but how can this be done with classes resp. structs without passing every single class or struct member one by one?

Thanks in advance

Jens

1 Answer

0 votes
by

Hello Jens,

in the typical application it is usually not necessary to save complete configuration objects. Instead, the values are stored just in the moment when they are changed. For example, you can have an object with properties for the current temperature, timer, etc. Every time the GUI application changes such property, the associated OnSet method is invoked. Within the onset method you can update the value in NVM. In this manner the NVM stays in sync with the values used in the GUI application. Have you seen the chapter Device Class and Device Driver? It describes the concepts.

Anyway, classes defined/implemented in Chora are converted in C code. Each Chora class is in fact a ANSI C 'struct'. Each Chora object is an instance of the respective C struct. Knowing this you are able to use Chora objects at C level similarly as you do with regular C data members. For example, the following code copies the entire content of an Chora object to some RAM and also accesses some members of the object:

var Example::YourClass obj = ...

native ( obj )
{
  void* strPtr  = obj;
  void* destPtr = ...
  int   size    = sizeof( *obj );

  /* Copy the entire object */
  memcpy( destPtr, srcPtr, size );

  /* or access just a member 'Temperature' (assuming the object contains such variable) */
  StoreInNVM( offsetInNVM, obj->Temperature, sizeof ( obj->Temperature ));
}

Doing this you have to be very careful because Embedded Wizard implements special data management for its data. For example, if the copied object contains references to other objects, references to strings, references to slots, properties or it has been overriden by a variant - the corresponding members can't be copied. Well, you can copy them, but when you later try to restore the values of those members, these values are not valid for Embedded Wizard and will cause the application to crash. Therefore, the above approach is officially not the recommended way.

If you are 100% sure, your object contains only integer (int8..uint32), bool, float or char types -> you can copy the data. Otherwise you will need to handle the data members individually. For example, if your object contains a string, you will need to create a copy of the entire string and store it in NVM together with all other data members of the object. Storing just the pointer to the string will not work. More complicated will be if the object contains references to other objects. In such case it would be necessary to stora all affected objects - the entire network.

Thus even if you have many values in the object to store, I would follow the approach explained in the Integrating with the device chapter. For example:

var Example::YourClass obj = ...
var int32    value_1 = obj.Value_1;
var int32    value_2  = obj.Value_2;
[...]
var int32    value_N  = obj.Value_N;
var int32    string_1 = obj.String_1;
var int32    string_2 = obj.String_2;
[...]
var int32    string_N = obj.String_N;

native ( value_1, value_2, [...] value_N, string_1, string_2, [...] string_N )
{
  int offsetInNVM = ...
  int len;

  StoreInYourNVM( offsetInNVM, &value_1, sizeof( value_1 );
  offsetInNVM += sizeof( value_1 );

  StoreInYourNVM( offsetInNVM, &value_2, sizeof( value_2 );
  offsetInNVM += sizeof( value_2 );

  [...]

  StoreInYourNVM( offsetInNVM, &value_N, sizeof( value_N );
  offsetInNVM += sizeof( value_N );

  /* Store a copy of the string. For this purpose ask the length of the string */
  len = EwGetStringLength( string_1 );

  StoreInYourNVM( offsetInNVM, &len, sizeof( len );
  offsetInNVM += sizeof( len );

  /* Copy the string comntent */
  if ( len )
  {
    StoreInYourNVM( offsetInNVM, string_1, len * sizeof( XChar ));
    offsetInNVM += len * sizeof( XChar );
  }
  
  /* Store a copy of the string. For this purpose ask the length of the string */
  len = EwGetStringLength( string_2 );

  StoreInYourNVM( offsetInNVM, &len, sizeof( len );
  offsetInNVM += sizeof( len );

  /* Copy the string comntent */
  if ( len )
  {
    StoreInYourNVM( offsetInNVM, string_2, len * sizeof( XChar ));
    offsetInNVM += len * sizeof( XChar );
  }
  
  [...]  

  /* Store a copy of the string. For this purpose ask the length of the string */
  len = EwGetStringLength( string_N );

  StoreInYourNVM( offsetInNVM, &len, sizeof( len );
  offsetInNVM += sizeof( len );

  /* Copy the string comntent */
  if ( len )
  {
    StoreInYourNVM( offsetInNVM, string_N, len * sizeof( XChar ));
    offsetInNVM += len * sizeof( XChar );
  }
}

If you are not sure how to implement some operation in C -> just implement this operation in Chora, generate code and analyse the resulting C code.

Does it help you?

Best regards

Paul Banach

Embedded Wizard Website | Privacy Policy | Imprint

...