Defining custom tokens
Mechanics
Custom application tokens are defined in a header file. The header
file can be specific to each project, and is defined by the
preprocessor variable APPLICATION_TOKEN_HEADER. More information about preprocessor variables and how they can be configured is available.
The APPLICATION_TOKEN_HEADER file should have the following structure:
/** * Custom Application Tokens */ // Define token names here #ifdef DEFINETYPES // Include or define any typedef for tokens here #endif //DEFINETYPES #ifdef DEFINETOKENS // Define the actual token storage information here #endif //DEFINETOKENS
Please note: the header files
does not have #ifndef HEADER_FILE / #define HEADER_FILE sequence at the
top. This is important because this header file is included several
times for different purposes.
Custom Tokens
Adding a custom token to this file is easy. It involves three steps:
- Define the token name
- Add any typedef needed for the token, if it is using an application-defined type
- Define the token storage
We will define the token examples from the previous page to give a good idea of how to use each of the three types of tokens.
Define the Token Name
We need three token names. When defining the name, we do not prepend the word TOKEN. Instead, use the word CREATOR:
/** * Custom Application Tokens */ // Define token names here #define CREATOR_DEVICE_INSTALL_DATA (0x000A) #define CREATOR_HOURLY_TEMPERATURES (0x000B) #define CREATOR_LIFETIME_HEAT_CYCLES (0x000C)
This is defining the token key and linking it to a programmatic variable. The token names are
actually DEVICE_INSTALL_DATA, HOURLY_TEMPERATURES, and
LIFETIME_HEAT_CYCLES, with different tags prepended to the beginning
depending on the usage. Thus we refer to them in the example code as
TOKEN_DEVICE_INSTALL_DATA, and so on.
The token key is a 16-bit
value that must be unique within this device. The first-bit is
reserved for manufacturing and stack tokens, so all of your custom
tokens should have a token key less than 0xA000.
The token key
is critical to linking application usage with the proper data and as
such a unique key should always be used when defining a new token or
even changing the structure of an existing token. Always using a
unique key will guarantee a proper link between application and data.
Define the Token Type
Each token in this case is a different type; however, the
HOURLY_TEMPERATURES and LIFETIME_HEAT_CYCLES types are built-in types
in C. Only the DEVICE_INSTALL_DATA type is a custom data structure.
We
define it the same way as in the previous example. Note that it must
only be defined in one place, as the compiler will complain if the same
data structure is defined twice.
#ifdef DEFINETYPES
// Include or define any typedef for tokens here
typedef struct {
int8u room_number; /** The room where this device is installed */
int8u install_date[11] /** YYYY-mm-dd + NULL */
} InstallationData_t;
#endif //DEFINETYPES
Define the Token Storage
This part is the key to tying it all together. This actually informs
the token management software about the tokens you are defining. Each
token gets its own entry in this part:
#ifdef DEFINETOKENS
// Define the actual token storage information here
DEFINE_BASIC_TOKEN(DEVICE_INSTALL_DATA,
InstallationData_t,
{0, {0,...}})
DEFINE_INDEXED_TOKEN(HOURLY_TEMPERATURES, int16u, HOURS_IN_DAY, {0,...})
DEFINE_COUNTER_TOKEN(LIFETIME_HEAT_CYCLES, int32u, 0}
#endif //DEFINETOKENS
This is a little complicated, so let's dissect it piece by piece:
DEFINE_BASIC_TOKEN(DEVICE_INSTALL_DATA,
InstallationData_t,
{0, {0,...}})
DEFINE_BASIC_TOKEN takes three arguments: the name
(DEVICE_INSTALL_DATA), the data type (InstallationData_t), and the
default value of the token if it has never been written by the
application ({0, {0,...}}).
The
default value takes the same syntax as C default initializers; while it
may appear complicated, many examples are floating around on the web.
In this case, the first value (room_number) is initialized to 0, and
the next value (installation_date) is set to all 0's because the
{0,...} syntax fills the remainder of the array with 0.
The
other two definitions should now make sense. The only difference is
that DEFINE_INDEXED_TOKEN requires, as you might expect, a length of
the array -- in this case, HOURS_IN_DAY, or 24. The final argument to
it is the default value of every element in the array. Again, in this
case it is initialized to all 0.
The syntax of DEFINE_COUNTER_TOKEN is identical to DEFINE_BASIC_TOKEN.
- Login to post comments








