Package jmri.jmrit

Class MemoryContents


  • public class MemoryContents
    extends java.lang.Object
    Models (and provides utility functions for) board memory as expressed in .hex files and .DMF files.

    Provides mechanisms to read and interpret firmware update files into an internal data structure. Provides mechanisms to in create firmware update files from an internal data structure. Provides mechanisms to allow other agents to access the data in the internal data structures for the purpose of sending the data to the device to be updated. Supports the Intel "I8HEX" file format and a derivative ".dmf" file format created by Digitrax.

    Support for the Intel "I8HEX" format includes support for record types "00" and "01". The "I8HEX" format implements records with a LOAD OFFSET field of 16 bits. To support the full 24-bit addressing range provided by the LocoNet messaging protocol for firmware updates, this class is able to interpret record type "04" (Extended Linear Address) records for input files with 16-bit LOAD OFFSET fields. Record type "04" are typically found in the Intel "I32HEX" 32-bit addressing format. Because the class supports only 24 bits of address, interpretation of the "04" record type requires that the upper 8 bits of the 16-bit data field be 0.

    Support for some .hex files emitted by some tool-sets requires support for the Extended Segment Address record type (record type "02"), which may be used in I16HEX format files. This version of the readHex(java.lang.String) method supports the Extended Segment Address record type ONLY when the segment specified in the data field is 0x0000.

    Support for the Digitrax ".DMF" format is an extension to the "I8HEX" support. This extension supports interpretation of the 24-bit LOAD OFFSET fields used in .DFM files. The class does not allow files with 24-bit LOAD OFFSET fields to use the "04" (Extended Linear Address) record type unless its data field is 0x0000.

    Support for the ".DMF" format allows capture of Key/Value pairs which may be embedded in special comments within a .DMF file. This support is enabled for I8HEX files.

    The class treats the information within a file's records as having "big-endian" address values in the record LOAD OFFSET field. The INFO or DATA field information is interpreted as 8-bit values, with the left-most value in the INFO or DATA field corresponding to the address specified by the record's LOAD OFFSET field plus the influence of the most recent previous Extended Linear Address record, if any.

    The INFO or DATA field for Extended Linear Address records is interpreted as a big-endian value, where bits 7 thru 0 of the data field value are used as bits 23 thru 16 of the effective address, while bits 15 thru 0 of the effective address are from the 16-bit LOAD OFFSET of each data record. Bits 15 thru 8 of the Extended Linear Address record INFO or DATA field must be 0 because of the 24-bit address limitation of this implementation.

    The class does not have to know anything about filenames or filename extensions. Instead, to read a file, an instantiating method will create a File object and pass that object to readHex(java.lang.String). Similarly, when writing the contents of data storage to a file, the instantiating method will create a File and an associated Writer and pass the Writer object to writeHex(java.io.Writer). The mechanisms implemented within this class do not know about or care about the filename or its extension and do not use that information as part of its file interpretation or file creation.

    The class is implemented with a maximum of 24 bits of address space, with up to 256 pages of up to 65536 bytes per page. A "sparse" implementation of memory is modeled, where only occupied pages are allocated within the Java system's memory.


    The Intel "Hexadecimal Object File Format File Format Specification" uses the following terms for the fields of the record:
    RECORD MARK
    first character of a record. ':'
    RECLEN
    a two-character specifier of the number of bytes of information in the "INFO or DATA" field. Immediately follows the RECORD MARK charcter. Since each byte within the "INFO or DATA" field is represented by two ASCII characters, the data field contains twice the RECLEN value number of ASCII characters.
    LOAD OFFSET
    specifies the 16-bit starting load offset of the data bytes. This applies only to "Data" records, so this class requires that this field must encode 0x0000 for all other record types. The LOAD OFFSET field immediately follows the RECLEN field.

    Note that for the 24-bit addressing format used with ".DMF" files, this field is a 24-bit starting load offset, represented by six ASCII characters, rather than the four ASCII characters specified in the Intel specification.

    RECTYP
    RECord TYPe - indicates the record type for this record. The RECTYPE field immediately follows the LOAD OFFSET field.
    INFO or DATA
    (Optional) field containing information or data which is appropriate to the RECTYP. Immediately follows the RECTYP field. contains RECLEN times 2 characters, where consecutive pairs of characters represent one byte of info or data.
    CHKSUM
    8-bit Checksum, computed using the hexadecimal byte values represented by the character pairs in RECLEN, LOAD OFFSET, RECTYP, and INFO or DATA fields, such that the computed sum, when added to the CKSUM value, sums to an 8-bit value of 0x00.
    This information based on the Intel document "Hexadecimal Object File Format Specification", Revision A, January 6, 1988.

    Mnemonically, a properly formatted record would appear as:

         :lloooott{dd}cc
     where:
          ':'     is the RECORD MARK
          "ll"    is the RECLEN
          "oooo"  is the 16-bit LOAD OFFSET
          "tt"    is the RECTYP
          "{dd}"  is the INFO or DATA field, containing zero or more pairs of 
                      characters of Info or Data associated with the record
          "cc"    is the CHKSUM
     

    and a few examples of complaint records would be:

    • :02041000FADE07
    • :020000024010AC
    • :00000001FF
    • Method Detail

      • writeHex

        public void writeHex​(java.io.Writer w)
                      throws java.io.IOException,
                             MemoryContents.MemoryFileAddressingFormatException
        Sends a character stream of an image of a programmatic representation of memory in the Intel "I8HEX" file format to a Writer.

        Number of bytes of data per data record is fixed at 16. Does not write any comment information to the file.

        This method generates only RECTYPs "00" and "01", and does not generate any comment lines in its output.

        Parameters:
        w - Writer to which the character stream is sent
        Throws:
        java.io.IOException - upon file access problem
        MemoryContents.MemoryFileAddressingFormatException - if unsupported addressing format
      • writeHex

        public void writeHex​(java.io.Writer writer,
                             boolean writeKeyVals,
                             int blockSize)
                      throws java.io.IOException,
                             MemoryContents.MemoryFileAddressingFormatException
        Sends a character stream of key/value pairs (if requested) and an image of a programmatic representation of memory in either the Intel "I8HEX" or Digitrax ".DMF" file format to a Writer.

        When selected for writing, the key/value pairs are provided at the beginning of the character stream. Note that comments of the key/value format implemented here is not in compliance with the "I8HEX" format.

        The "I8HEX" format is used when the loadOffsetFieldType is configured for 16-bit addresses in the record LOAD OFFSET field. The ".DMF" format is used when the loadOffsetFieldType is configured for 24-bit addresses in the record LOAD OFFSET field.

        The method generates only RECTYPs "00" and "01", and does not generate any comment lines in its output.

        Parameters:
        writer - Writer to which the character stream is sent
        writeKeyVals - determines whether key/value pairs (if any) are written at the beginning of the stream
        blockSize - is the maximum number of bytes defined in a data record
        Throws:
        java.io.IOException - upon file access problem
        MemoryContents.MemoryFileAddressingFormatException - if unsupported addressing format
      • nextContent

        public int nextContent​(int location)
        Return the address of the next location containing data, including the location in the argument
        Parameters:
        location - indicates the address from which the next location is determined
        Returns:
        the next location
      • setLocation

        public void setLocation​(int location,
                                int value)
        Modifies the programmatic representation of memory to reflect a specified value.
        Parameters:
        location - location within programmatic representation of memory to modify
        value - value to be placed at location within programmatic representation of memory
      • locationInUse

        public boolean locationInUse​(int location)
        Queries the programmatic representation of memory to determine if location is represented.
        Parameters:
        location - location within programmatic representation of memory to inspect
        Returns:
        true if location exists within programmatic representation of memory
      • getLocation

        public int getLocation​(int location)
        Returns the value from the programmatic representation of memory for the specified location. Returns -1 if the specified location is not currently represented in the programmatic representation of memory.
        Parameters:
        location - location within programmatic representation of memory to report
        Returns:
        value found at the specified location.
      • isEmpty

        public boolean isEmpty()
        Reports whether the object has not been initialized with any data.
        Returns:
        false if object contains data, true if no data stored in object.
      • extractValueOfKey

        public java.lang.String extractValueOfKey​(java.lang.String keyName)
        Finds the Value for a specified Key if that Key is found in the list of Key/Value pair comment lines. The list of Key/Value pair comment lines is created while the input file is processed.

        Key/value pair information is extractable only from comments of the form:

        ! Key/Value

        Parameters:
        keyName - Key/value comment line, including the leading "! "
        Returns:
        String containing Key name
      • addKeyValueComment

        public void addKeyValueComment​(java.lang.String keyName,
                                       java.lang.String value)
        Updates the internal key/value storage to reflect the parameters. If the key already exists, its value is updated based on the parameter. If the key does not exist, a new key/value pair comment is added to the key/value storage list.
        Parameters:
        keyName - key to use
        value - value to store
      • writeComments

        public void writeComments​(java.io.Writer writer)
                           throws java.io.IOException
        Writes key/data pair information to an output file

        Since the key/value metadata is typically presented at the beginning of a firmware file, the method would typically be invoked before invocation of the writeHex method.

        Parameters:
        writer - Writer to which the character stream is sent
        Throws:
        java.io.IOException - if problems writing data to file
      • toString

        public java.lang.String toString()
        Summarize contents
        Overrides:
        toString in class java.lang.Object
      • clear

        public void clear()
        Clear out an imported Firmware File. This may be used, when the instantiating object has evaluated the contents of a firmware file and found it to be inappropriate for updating to a device, to clear out the firmware image so that there is no chance that it can be updated to the device.