示例#1
0
        public static void SaveAsIntelHex(string fileName, BinaryBlock[] blocks)
        {
            using (StreamWriter writer = new StreamWriter(fileName))
            {
                foreach (BinaryBlock b in blocks)
                {
                    byte[] data = b.GetBytes();
                    ushort high = (ushort)(b.Address >> 16);
                    ushort low  = (ushort)(b.Address & 0xFFFF);

                    writer.WriteLine(IntelHexRecord.EncodeLine(eRecordType.ExtendedLinearAddress, 0, new byte[] { (byte)(high >> 8), (byte)high }));
                    /* Align the data start addrss to hexLineDataLen bytes */
                    int datalinelen = hexLineDataLen - (int)b.Address % hexLineDataLen;
                    writer.WriteLine(IntelHexRecord.EncodeLine(eRecordType.Data, low, data.SubArray(0, (datalinelen > data.Length)? data.Length : datalinelen)));

                    for (int i = datalinelen; i < data.Length;)
                    {
                        /*Add last value*/
                        low += (ushort)datalinelen;

                        datalinelen = ((data.Length - i) > hexLineDataLen) ? hexLineDataLen : (data.Length - i);

                        if (low == 0)
                        {
                            high++;
                            writer.WriteLine(IntelHexRecord.EncodeLine(eRecordType.ExtendedLinearAddress, 0, new byte[] { (byte)(high >> 8), (byte)high }));
                        }

                        writer.WriteLine(IntelHexRecord.EncodeLine(eRecordType.Data, low, data.SubArray(i, datalinelen)));

                        i += datalinelen;
                    }
                }
                /* Append end of file line */
                writer.WriteLine(IntelHexRecord.EncodeLine(eRecordType.EndOfFile, 0, null));
            }
        }
示例#2
0
        public void Load(string fileName, eHash hash = eHash.CRC32, bool append = false)
        {
            if (!append)
            {
                blocks.Clear();
            }

            using (StreamReader reader = new StreamReader(fileName))
            {
                UInt32      CurrentAddress = 0, LastAddress = 0xFFFFFFFF;
                BinaryBlock newblock = null;

                while (reader.Peek() > 0)
                {
                    IntelHexRecord record = new IntelHexRecord(reader.ReadLine());

                    /*
                     * I32HEX files use only record types 00, 01, 04, and 05 (32 bit addresses)
                     * 00 : Data
                     * 01 : End Of File
                     * 04 : Extended Linear Address
                     * 05 : Start Linear Address
                     */
                    switch (record.RecordType)
                    {
                    case eRecordType.ExtendedLinearAddress:
                        /*
                         * Allows for 32 bit addressing (up to 4GiB).
                         * The address field is ignored (typically 0000) and the byte count is always 02.
                         * The two encoded, big endian data bytes specify the upper 16 bits of the 32 bit absolute address for
                         * all subsequent type 00 records; these upper address bits apply until the next 04 record.
                         * If no type 04 record precedes a 00 record, the upper 16 address bits default to 0000.
                         * The absolute address for a type 00 record is formed by combining the upper 16 address bits of
                         * the most recent 04 record with the low 16 address bits of the 00 record.
                         */
                        CurrentAddress = (((UInt32)record.Bytes[0]) << 24) | (((UInt32)record.Bytes[1]) << 16);
                        break;

                    case eRecordType.Data:
                        /*
                         *  Contains data and a 16-bit starting address for the data.
                         *  The byte count specifies number of data bytes in the record.
                         */
                        CurrentAddress = CurrentAddress & 0xFFFF0000 | (UInt32)record.Address;

                        if (LastAddress != CurrentAddress)
                        {
                            if (newblock != null)
                            {
                                newblock.UpdateHash(hash);
                            }
                            newblock = new BinaryBlock(CurrentAddress);

                            int i = 0;
                            for (; i < blocks.Count; i++)
                            {
                                if (blocks[i].Address > CurrentAddress)
                                {
                                    break;
                                }
                            }

                            blocks.Insert(i, newblock);
                        }

                        newblock.Append(record.Bytes);
                        LastAddress = CurrentAddress + (UInt32)record.Bytes.Length;

                        break;

                    case eRecordType.EndOfFile:
                        /*
                         * Must occur exactly once per file in the last line of the file.
                         * The data field is empty (thus byte count is 00) and the address field is typically 0000.
                         */
                        if (newblock != null)
                        {
                            newblock.UpdateHash(hash);
                        }

                        return;

                    case eRecordType.StartLinearAddress:
                    case eRecordType.StartSegmentAddress:
                        /*
                         * The address field is 0000 (not used) and the byte count is 04.
                         * The four data bytes represent the 32-bit value loaded into the EIP register of the 80386 and higher CPU.
                         *
                         * We ignore the record
                         */
                        break;

                    default:
                        throw new NotSupportedException("Unsupported line present");
                    }
                }
            }
        }