Table of Contents Previous Chapter ACIS

21.0 IPCL Code-Generator (36-53232.01 01)

21.1 Purpose

The purpose of the IPCL Code-Generator is to interpret the command and telemetry structure definitions provided in the "ACIS Instrument Program and Command List" (MIT3601410) database and produce C++ source code to read fields from command and parameter block buffers, and to format data into telemetry packet buffers.

21.2 Uses

  1. Write C++ classes which read fields from command packet buffers

  2. Write C++ classes which write fields into telemetry packet buffers

21.3 Organization

The IPCL Code-Generator is written entirely in Perl and is contained in within three files: ipcl_gen.pl, ipcl_reader.pl, and ipcl_writer.pl. The code-generator reads in the IP&CL structures definition from a file containing lists of tab-separated values, with newlines separating entries in the database. The format of the IP&CL structures is described in Section 21.4 . The output of the code-generator is a set of C++ header and source files, one for each structure being read or written. Templates for the generated C++ files are described in Section 22.0 and Section 23.0 .

Figure 93 illustrates the main inputs and outputs of the IP&CL code-generator.

FIGURE 93. IPCL Generator Context Diagram


The user invokes the Perl IP&CL Code-Generator script passing it the name of the IP&CL Structures table file, input filename. The code generator opens and reads all of the field entries from the Input File. It then parses the field entries, and produces a series of C++ header and source files, one for each record structure defined in the input file. Each record structure is represented by a C++ class. The header files will contain the class definitions for the defined classes, and the source files contain the member function implementations for these classes.

Figure 94 illustrates the Level-1 data flow of the IP&CL code-generator.

FIGURE 94. IPCL Generator Level-1 Data Flow Diagram


The following describes each data element illustrated in Figure 93 and Figure 94:

input filename - This identifies the file which contains the IP&CL Structure records to process.

field entries - These are the field definitions read from the IP&CL input file. Each entry contains a list of tab-separated ASCII elements, and ends with a newline character. See Section Section 21.4.2 for a description of the format of a field entry.

class definitions - These are the definitions for each generated C++ class.

member function implementations - These are the implementations for each member function of a class.

record name - This is the ASCII name of a record as defined in the IP&CL database. All fields belong to one record or another, and each field entry contains the name of the record to which it belongs. The code-generator uses the record name as part of a database key when indexing field entries. The code-generator includes a modified form of the record name when generating class names, and C++ header and source code filenames.

field index - Each field within a record is numbered. The code-generator uses the field index in its database key when indexing field entries.

%ipcl - This is a Perl associative array of IP&CL field entry counts and field entries. Array elements keyed using a record name alone return the number of fields defined for the named record. Elements which are keyed using a record name and field index, separated by the value of the Perl variable, $;, contain the field entry string, as read from the IP&CL input file.

$ipcl{record name} = count of fields for the named record
$ipcl{record name, field index} = field entry string

list of stored record names - This list is generated by asking Perl to produce an array of all database keys, and then sorts the list and prunes out any key containing the value of the $; Perl variable.

initial position - This item represents the initial bit-position of the current record being produced. This item's value is always 0.

count of fields - This represents the number of fields defined for a given record. It's value for a given record is contained in $ipcl{record name}.

current position - This item represents the current bit-position within a given record definition. It is used to compute the bit-position of a field or record, and to determine the need for padding if a field has a bit alignment requirement.

field name - This is the name of a field defined in the IP&CL database. The code-generator includes a modified form of the field name when generating member function names. NOTE KLUDGE: On occasion, the generator also uses this name to identify fields which are intended to be grouped into an array. A set of two or more adjacent fields, which have the same base name, and whose names end with incrementing numbers starting from 0, may be treated as elements of an array by the code-generator.

field mnemonic - This is an 8-character mnemonic for the field in the IP&CL.NOTE KLUDGE: The code-generator uses the mnemonic of the first field of a record to determine whether the record defines a command packet structure, a telemetry packet structure or is an internal structure. If the last two characters of the mnemonic are "CI," then the code generator treats the record as a command packet. If the last two characters are "XF," then it treats the record as a telemetry packet. All others are treated as internal structures, and are ignored by the code-generator.

field type - This identifies the data type of the field. For ACIS software structures, a field has one of the following types:

int8 - signed, 8-bit integer
uint8 - unsigned, 8-bit integer
int16 - signed, 16-bit integer
uint16 - unsigned, 16-bit integer
int32 - signed, 32-bit integer
uint32 - unsigned, 32-bit integer
bit - bit-field where field dimension determines the number of bits 
in the field. 
record name - The name of another record definition. The data type 
of the field is defined by the referenced record.

field dimension - This specifies the number of elements of field type in the field. If the field dimension is not 1, then the field represents an array of elements. If the field dimension is a constant expression, then the array is of fixed length. If the value of the dimension relies the value of another field within the record, then the field has a variable number of elements. Fields representing variable length arrays must always appear at the end of the record definitions. No other fields may appear after the variable array within the record. field dimension may be expressed as formula. The formula parsing rules are as follows:

DECIMAL = [0-9]+
OCTAL = 0[0-7]*
HEXADECIMAL = 0x[0-9, a-f, A-F]+
NUMBER = DECIMAL | OCTAL | HEXADECIMAL
VARIABLE = field name
OPERATOR= `*'|`DIV'|`+'|`-'|`bitoffset'|`bitsize(record name)'
TERM = NUMBER | VARIABLE | TERM OPERATOR TERM | `(' TERM `)'
For example, a common dimension formula for a command packet field is:
((command length * 16) - bitoffset) DIV bitsize(field type)

field range - This specifies the lowest and highest acceptable value for the field, and is used by the code-generator when producing sanity checks of input arguments or read field values.

field alignment - This specifies the bit-alignment requirement of the field. The code-generator may add pad bits between the previous field and the current field to satisfy the alignment requirement.

variable width - This is the computed number of bits within one element of a variable length array. This width includes any pad bits needed to satisfy alignment requirements of the array elements.

variable offset - This is computed bit offset of the start of a variable length array.

parsed records - This represents the parsed record structure used by the code-generators to produce C++ class definitions and implementations. It consists of an array of keywords and values and has the following form:

parsed records = RECORD
TERM = RECORD | FIXED | VARIABLE | FIELD
RECORD = `record' recordname curoffset TERM* `endrecord'
FIXED = `fixed' fieldname curoffset width dimension TERM* `endfixed'
VARIABLE = `variable' fieldname curoffset width dimension TERM* `endvariable'
FIELD = `field' fieldname curoffset width sign srange erange `endfield'
where curoffset is the bit-position of the element, width is the number of 
bits within the field or 1 element of a fixed or variable length array, dimen
sion is the formula for the number of elements in the array, sign is 0 if the 
field is unsigned and 1 of the field is signed, srange is the lowest value 
that the field supports, and erange is the largest value the field supports.

21.4 IP&CL Structures Database

21.4.1 File format

NOTE: The IP&CL structures definitions table format is still being design Final definition of the fields is TBD.

The code-generator reads the IP&CL information from an ASCII file. The file contains one line per record field entry, each ending in a newline character. Each entry contains the same number of elements, each separated by a tab character.

21.4.2 Entry Format

Each field entry consists of the following elements, in the listed order:

TABLE 23. IP&CL Field Entry Format

------------------------------------------------------------------------------------------------------
Element               Description                                                                       
------------------------------------------------------------------------------------------------------
Record Text           This describes the record defining the field                                      
Record Name           This is the name of the record defining the field                                 
Field Number          This is the field position within the record                                      
Subfield Number       This is the subfield position within the record                                   
Owner                 This identifies the owner of the record. For ACIS it is always `ACIS'             
Field Name            This is the name of the field                                                     
Mnemonic              This is the field's 8-character mnemonic. For ACIS software, the mne              
                      monic has the following structure: 1rrffAss, where `1' identifies the mne         
                      monic as an ACIS field, `rr' is the record number in hexadecimal, `ff' is         
                      the field number in hexadecimal, `A' specifies the port side, and `ss' is         
                      used to identify the type of record being defined. If `ss' is CI, the record is   
                      a command packet definition. If it is `XF', it is a telemetry packet, and if      
                      it is `IT', it is an interal record.                                              
Data Type             This specifies the data type of the field. This may have the following val        
                      ues: int8, uint8, int16, uint16, int32, uint32, bit, or the name of a record.     
Dimension             If the field defines an array, this specifies the number of elements in the       
                      array. The dimension statement may consist of a formula, which may                
                      refer to fields within the record, may contain parenthesized expressions,         
                      and which uses the following operators and keywords: +, -, *, DIV, bitoff         
                      set, bitsize(`record name')                                                       
Maximum Dimension     This specifies the maximum number of elements that can be held by the             
                      field.                                                                            
Variable Record Flag  This indicates whether the fields in the record have constant or variable         
                      values                                                                            
Field Description     This describes the field                                                          
Byte Size             This is the number of bytes in 1 element of the field. Its value is computed      
                      by TRW.                                                                           
Total Size            This is the total number of bytes being defined by the field. Its value is        
                      computed by TRW.                                                                  
Start Range           This is the minimum value the field can have.                                     
End Range             This is the maximum value the field can have.                                     
Units                 This specifies the units of the field                                             
Value                 If the field has constant value, this specifies the value.                        
Format                This identifies the printing format to use for the field                          
Question              This entry is TBD.                                                                
Alignment             This specifies the bit-alignment requirements of the field.                       
Command Time-out      This specifies the command time-out period, if the field is part of a com         
                      mand packet record definition.                                                    
------------------------------------------------------------------------------------------------------

21.5 Script Structure

21.5.1 ipcl_gen.pl

This section illustrates the structure of the main portion of the code-generator script, ipcl_gen.pl. The unshaded functions are contained within ipcl_gen.pl and the shaded functions are provided by either ipcl_reader.pl or ipcl_writer.pl.

FIGURE 95. ipcl_gen.pl Structure


rtext - Description of the record rname - Record name fnum - Field index subf - Subfield index owner - Record owner, always `ACIS' fname - Field name mnem - Field mnemonic type - Field type dim - Field dimension maxdim - Maximum dimension var - Variable record ftext - Field description sizeb - Size of field in bytes tsize - Total size of field in bytes srange - Lowest value contained in field erange - Highest value contained in field units - Units of value contained in field value - Fixed value of field fmt - Printing format for field quest - Questions??? align - Bit-alignment requirements of field cmdto - Command Timeout requirements for command records RECORD = `record' recordname curoffset TERM* `endrecord' FIXED = `fixed' fieldname curoffset width dimension TERM* `endfixed' VARIABLE = `variable' fieldname curoffset width dimension TERM* `endvariable' FIELD = `field' fieldname curoffset width sign srange erange `endfield' basetype - Indicates if field type refers to an integer or bit-field isvararray- Indicates if field defines a variable length array isfixedarray - Indicates if field defines a fixed length array bitwidth - For integer/bit types, contains the bit-width of the field limit - For arrays, defines the number of elements in the array sign - For integer types, indicates if field is unsigned or signed srange - For integer/bit types, indicates lowest value of field erange - For integer/bit types, indicates largest value of field arraywidth - For arrays, contains bit-width of 1 element in the array ((length * 16) - 11) / 9 / - * #length# 16 11 9

21.5.2 ipcl_reader.pl

This section illustrates the structure of the command packet reader portion of the code-generator script, ipcl_reader.pl.

FIGURE 96. ipcl_reader.pl structure


$cfg{inputbits} - Number of bits in command buffer word = 16 $cfg{inputname} - Variable name of command buffer "inputbuf" class class_name : public parent name { public: unsigned get_CountOf_fieldname() const; ((#field_name# * 16) - 32)/14 ((get_field_name() * 16) - 32)/14 unsigned classname::get_CountOf_fieldname() const { return array limit expression; }; unsigned get_field_name(unsigned index) const; unsigned record_name::get_field_name (unsigned index) const { // ---- Range check index argument ---- assert (index < 10) // ---- Offset = 5, Width = 3, Structure = 17---- unsigned out = getField (5, 3, 0x7, index, 17); out = unsigned(int(out << 30) >> 30); // ---- Value range checks ---- assert (out >= 1); assert (out <= 5); return int(out); };

21.5.3 ipcl_writer.pl

This section illustrates the structure of the telemetry packet writer portion of the code-generator script, ipcl_writer.pl.

FIGURE 97. ipcl_writer.pl structure


$cfg{outputbits} - # of bits in word of the telemetry buffer = 32 $cfg{ouptputname} - Variable name of telemetry buffer "outputbuf" $cfg{buflimit} - Max. words in telemetry buffer = 1024 * 32 class class_name : public parent name { public: unsigned getWordCount() const - Get number of words in packet buffer void setEmpty() - Set the number of appended items in the packet to 0 Boolean isFull() const - Determine if packet buffer is full Boolean hasData() const - Determine if packet has any appended data void append_field_name(unsigned index, unsigned subfield); void record_name::append_field_name (unsigned index, unsigned subfield) { // ---- Range check index argument ---- assert (index < 10) // ---- Value range checks ---- assert (input >= 1); assert (input <= 5); // ---- Offset = 5, Width = 3, Structure = 17---- putField (input, 5, 3, 0x7, index, 17); return; }; { // ---- Range check index argument ---- assert (isFull() == BoolFalse); // ---- sub 1 :: Offset = 12, Width = 10 ---- appendField (sub_1, 12, 10, 0x3ff, _appended, 26); // ---- sub 2 :: Offset = 22, Width = 4 ---- appendField (sub_2, 4, 22, 0x0f, _appended, 26); return; }; argument string<field count offset width sign srange erange> const unsigned or int basename[field count] unsigned class_name::getWordCount (void) const { // ---- Offset 10, Element Size 20 ---- unsigned wordcnt = 10 + (_appended * 20); wordcnt = (wordcnt + 31) / 32; return wordcnt; }; Boolean class_name::isFull (void) const { // ---- Offset 11, Element Size 10 ---- unsigned offset = 11 + ((_appended + 1) * 10); return (offset > 4096) ? BoolTrue : BoolFalse; }; Boolean class_name::hasData (void) const { return (_appended != 0) ? BoolTrue : BoolFalse; }; void class_name::setEmpty (void) { _appended = 0; };

Table of Contents Next Chapter