Frequently Asked Questions

TSN.1 Compiler FAQs

TSN.1 Compiler - Performance and Code Size

Q: My application runs on an ARM-based embedded target. What compile flags should I use?

A: On an embedded target with limited resources, you want to maximize performance while minimizing the code size. Normally on such a target, only the essential functions (pack, unpack, and perhaps sizeof) are required.

If you only need the pack function for some messages and unpack for others, then it is recommended to group your messages into TSN.1 files according to this distinction. Once you've done that, compile the files that only require the pack function with the "-pack" flag and compile the other files with the "-unpack" flags. If your messages always start at fixed byte boundary, make sure to turn on the "-byte-aligned" flag. This produces very efficient pack and unpack code using bit shifts and bit masks.

If pack, unpack, and sizeof are all you need, then you can leave out most of the source files from the Runtime Library build. The only two files required are "tsnc_msg.c" and "tsnc_buf.c", which is about 6K in object code size.

Q: I don't care about code size. I want maximum performance and all the functions. What compile flags should I use?

A: Use the "-all" flags. If your messages are byte aligned, then use the "-byte-aligned" flag as well.

Q: I want to avoid dynamic memory allocation. What compile flags should I use?

A: Use the "-static" flag. If all of your messages are byte aligned, then use the "-byte-aligned" flag as well. If your target language is C, you can also use the "-static-union" flag. This will generate message types that uses no dynamic memory. When you use the "-static" flag, however, make sure you don't have arrays that are too large. Please refer to this question for ideas on how to restrict the size of an array.

TSN.1 Compiler - Customization

Q: How do I customize the generated code?

A: You can customize the TSN.1 Compiler output by either using compile flags, which apply globally to the TSN.1 file, or annotating your TSN.1 file with XML tags, which gives you finer control and more options. For example, if you want to use automatic storage for your messages fields, i.e. no pointers, compile your TSN.1 file with the "-static" flag. However, if you only want automatic storage for a particular field, annotate that field with the XML element "<storage>static</storage>". Please refer to the User's Manual for other ways to customize the generated code.

Q: How do I display a field in a format other than decimal?

A: Annotate the field with the "<display>" tag. For example, to display a field as an IPv4 address:

    SourceAddress  32; <display>ipv4</display>

Other display formats supported are: "oct" for octal, "hex" for hexadecimal, "ipv6" for an IPv6 address, and "ascii" for an ASCII string.

Q: I have a message with a very special encoding scheme that can't be described in TSN.1. What do I do?

A: You could of course always treat it as a special case and use your own parsing functions for this message. However, if you still want to use the standard pack and unpack functions in the Runtime Library for this message so that this is transparent to your application, you can use the <pack> and the <unpack> tags to replace the generated pack and unpack functions with your own functions. Please refer to the the "Pack" and "Unpack" sections in the "Extensions" Chapter of the User's Manual for details.

Q: Can I add my own code into the generated code?

A: Yes. Use the <code> tag to add arbitrary code into the generated files. The <code> tag contains attributes that allows you to specify the target language, the file, and the message for which the code is intended. For example, you can add additional fields into a generated message type. Please refer to the section "Code" in the "Extensions" Chapter of the User's Manual for details.

Q: How do I restrict the size of an array?

A: When you have an array in TSN.1, whose size depends on the value of another field, the generated array type reserves the maximum size for that array. For example, the TSN.1 code below

     Size  8;
     Elements[Size]  : SomeMessageType;

is generated as:

     uint8            Size;
     SomeMessageType *Elements[255];

The size of "Elements" is 255 because the maximum value of "Size" is 255. If you know the maximum size cannot exceed, say 100, you can restrict the array size by specifying a range for "Size":

     Size  8  (0..100);
     Elements[Size]  : SomeMessageType;

In this case, the generated code returns an error if the array size ever exceeds 100.

Q: Can I use my own data structures for arrays?

A: Yes. If you don't want to use the default array type, you can override it and supply your own container type by annotating the array with "<type>MyContainer</type>", where "MyContainer" is the type name of your data structure such as a linked list, a hash table, and etc. In order for this to work, your custom container type must implement the container API as specified in the "Type" section in the "Extensions" Chapter of the User's Manual. The generated code uses this API to create and delete the container and iterate over its members.

TSN.1 Compiler - Miscellaneous

Q: Can I document my TSN.1 files?

A: Yes. You can document your TSN.1 files using the Doxygen style comments, then compile your files with "-doxygen" flag. The TSN.1 Compiler will preserve your Doxygen comments into the generated files. You can then run doxygen as usual to generate source code documentation. Please refer to the "Doc" section in the "Extensions" Chapter of the User's Manual for details.

Q: Does the generated parser perform range checking on field values?

A: By default, the generated code does not check if field values are out of range. This allows users to create invalid messages for testing purposes. If you wish to perform this check, simply turn on the "-check-range" flag.

Q: I thought the generated code is endianness independent. What does the "-little-endian" flag do then?

A: The generated code is indeed independent of the endianness of your target platform. That is to say you don't need to recompile your TSN.1 files for different platforms. The "-little-endian" flag, on the other hand, is used to indicate the endianness of the encoded data, not your underlying platform. According to the TSN.1 specification, multibyte fields are packed in network byte order (big endian) by default. If you want to change this default and pack these fields in little endian, then use the "-little-endian" flag to compiler your TSN.1 files. In other words, if "-little-endian" flag is used, the generated code will always pack multibyte fields in little endian regardless if the code run on big or little endian machines.