# A C-Based Framework for Low-Cost Real-Time Embedded Systems
## 6 System Configuration
### Data Structure Synthesis  
As mentioned previously, RTFw configuration files are parsed at configuration time by the C preprocessor, in one or two passes, in order to transform them into data structures that RTFw will use later at runtime. This approach enables RTFw to generate memory and CPU-efficient data structures, shifting most of the execution time overhead from runtime to configuration time, without sacrificing the expressive power of configuration statements.  
The need for a second pass stems from the fact that the C macro preprocessor does not allow a macro to be defined during the expansion of a macro body [20]. On the contrary, when parsing configuration files, RTFw needs to generate multiple excerpts of C code based on the expansion of the macros cited in the configuration files in order to define and fill different parts of the data structures that represent the system configuration. These excerpts of code must be strategically placed within more elaborate definitions, and hence, the most natural choice is to enclose them into macro bodies for delayed expansion.  
To circumvent this issue, the body of the macros that need to define other macros introduce those definitions with the special token __define__ rather than the usual #define that would trigger a preprocessor error. Then, a sed script translates the first token into the second, and the output is fed to the C preprocessor once more. This approach has been chosen because, although it somewhat lacks generality, it is straightforward to implement and able to fulfill all RTFw requirements.  
Figure 7 contains a simplified view of the data structures that RTFw synthesizes for input PI variable int br, declared as listed in Figure 6. Output PI variables are handled similarly. The tree-like data structure is rooted at the PI variables table, depicted at the bottom left of the figure. It has one element for each variable, which points to the description of the variable itself. Through a set of pointers, summarized near the top of the figure, RTFw can access other board-related data structures to retrieve the raw value of the variable from the device it resides on during the I phase of the control cycle. More specifically, the available information specifies which board the value comes from, as well as its bus address and registered address range.  
Referring back to the PI variable descriptor, other pointers locate the converter function that RTFw also invokes during the I phase (Rtfw_bit_range in this case) and its parameters  
Figure 7: RTFw-generated data structures for variable br of Figure 6.  
(the integers 8 and 16). Finally, RTFW can also access the PI variable storage space through the descriptor in order to store the converted value where the user-written control function can use it.  
The choice of adopting a tree-like data structure in which the various nodes are linked by means of pointers instead of a monolithic structure has two distinct advantages:  
* It becomes possible to save memory by sharing common information. For instance, all variable descriptors pertaining to variables whose value originates from the same board point to the same board descriptor.
* Most data can be stored in read-only Flash memory, reserving RAM (that is often a precious resource in low-cost embedded systems) for the actual read-write portions of the data structure. Referring back to Figure 7, the only read-write structures--to be stored in RAM--are the dark-gray-colored ones.  
As shown in the figure, there are three main kinds of RAM-based information:  
* The value of PI variables, br in this case.
* Status information about them, for instance, the outcome of the last I/O operation involving them.
* Status information about boards as a whole, for instance, the actual Modbus address of a board that has more than one possible configured address.