High Performance OPC UA Server SDK
1.5.0.296
|
The xml2c
tool can be used to generate static information model files from XML NodeSet files. These models are generated in form of C code which gets compiled into the firmware.
All the node tables, string tables and value tables are generated as C constants, so thats this information can stay in ROM and doesn't need to be copied to RAM at startup.
Calling xml2c
works very similar to invoking xml2bin
, but requires some additional arguments. To get an overview about the available options call it with option -h
, which displays the built-in help.
Example:
$> mkdir -p output $> ./xml2c -n di -i2:di:12 -o output Opc.Ua.NodeSet2.xml Opc.Ua.Di.NodeSet2.xml
The main difference to xml2bin
is that this tool not only generate the address spaces, but also C Header and Source files for all types defined in the information model. It also creates a CMakeLists.txt which will create a complete C library for that information model. If the model contains datatypes this will get registered automatically at the SDK's generic encoder/decoder, so that the SDK is able to encode/decode those datatypes. This works out-of-the-box, the only thing you need to to in your application is to linked against this library and call the generated function <prefix>_register_static_addressspace
.
Options:
Option | Description |
---|---|
-n | Specifies the library name used in the generated CMakeLists.txt |
-i | Selects the SDK Index to export, the prefix, and the alternate store index |
-o | Selects the output folder where the source files should be generated. |
The example command above will generate the following files.
The table below describes the purpose of the different generated files.
File/Folder | Description |
---|---|
CMakeLists.txt | CMake project to compile the 'DI' library. |
di/ | Folder containing all sources for the DI model. |
ns2.c | The constant address space tables. |
identifier.h | Defines with NodeId identifiers. |
type_* | Type table code for generic encoder/decoder. |
*type.[c,h] | Generated code for DI datatypes. |
The library will contain all the code to for datatypes and the generic encoder/decoder, but does not include ns2.c! This will needs to be included directly by your provider code as shown in the example Sensor Model Server.
The library gets linked with the application and can be used with static address spaces as well as with dynamic address spaces loaded from file.
When the XML file contains a <Value>
tag for a certain variable, xml2c
will add this value to the generated value store (which is a static store) and will connect the variable with this value. The rule for this is that xml2c
uses the store_index=nsidx+1
for this (0 is not a valid store index). This means for the SDK NsIdx 2 the store index 3 will get assigned.
Variables with no value will be connected to the "alternate store". You are assigning the alternate store index at the command line like e.g. -i2:demo:12
, which means: "Export nsidx 2 with prefix 'demo' and the alternate store index 12". In the code you need to register a store at this index, which can be a writable store. This way values are read- and writable, even though the namespace is static.
Summary: When generating C code you need to specify a 3-tuple separated by ':' for each namespace that should be generated: e.g. -i2:demo:12
Tuple value | Meaning |
---|---|
2 | SDK NSIdx to export |
demo | Prefix for generated code |
12 | The alterante store index. All variables without a <Value> tag will get connected with this store by default. |
When the default value handling is not sufficient, e.g. if you need more than one alternate store, or if you want to make variable values writable, even though a value was already defined in XML, then you can specify an address mapping file using the option -M <file>
. This file is a simple plaintext file that contains a list of NodeIds with the address mapping you want to use.
File format properties:
xml2c
to automatically assign unique value index values.Example:
This example (from demoserver) assigns two variables to another store with store index 13, which is used for pointerstore in the demoserver. The value indices are assigned automatically.
To illustrate this the following example ...
... would be equivalent with this manual configuration:
As you can see each store index gets assigned its own unique value index range. The tool can auto-assign value indices for store index 0..255, which should be sufficient for most cases.
XML NodeSet files contain LocalizedText elements for different languages which can have different formats.
Description elements (and other localized texts) with no Locale
attribute or empty Locale
attribute are treated the same way. Then you might have elements with valid Locale
attributes which define what language this string belongs to. xml2c
only use one of the specified languages. You can choose the locale to use by specifying the option -l <locale>
, e.g. -l en-US
. When the option is not specified the default locale is "auto", which is a special value telling xml2c
, that it should automatically select the first found valid (non-empty) locale.
Background: Most existing companion specifications don't specify any locale, but the models use English as the language if they are international specifications. Some newer information models specify Locale="en"
. In both cases the "auto" keyword will extract the strings as expected.
Only when your model contains more than one locale, it might be necessary to specify the locale to use explicitly.
UA values in XML may contain locals as XML elements like this:
Invalid locale:
In this case xml2c
will issue warnings, because the locale is invalid. The example above contains a locale "\n "
, which is not a valid locale. xml2c
will trim leading and trailing white spaces to make this working as expected, but actually this XML is invalid, because Locale elements are defined as xsd:string which preserves all whitespaces.
The warning will look like this:
The location info of the warning tells you exactly where in the XML the invalid locale was found.
Correct would be to remove all white spaces between opening and closing tag, or simply use an empty tag like <Locale/>
. You should report such issues to the working group responsible for this model.
Correct locale:
If you plan to mix static generated address spaces with dynamic address spaces you need to use placeholder files. A placeholder file is a plaintext file with NodeIds, where xml2c
will create placeholder references, which allows you to add references at runtime.
All node tables and reference tables are C constants which cannot be modified at runtime. Placeholder references are located in RAM reference tables, and the last entry of a node's reference list is connected with such a placeholder reference. This allows you to added new references at runtime to nodes, which are actually static. See Mixed Address Space for more information on how this works.
Placeholder example file:
See also bin/placeholders.txt
for a more realistic example.
File format properties:
The placeholder file can be specified using the option -P
. This option can be specified multiple times, so that you can put placeholders for each namespace into a separate file.