LoginSignup
0
0

More than 1 year has passed since last update.

cscの作法 その46 intelHEX

Last updated at Posted at 2021-01-11

概要

cscの作法、調べてみた。
intelHEXやってみた。

参考にしたページ

サンプルコード


using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

public class HexFileParser {
    class HexFileData {
        private int offset;
        public int Offset {
            get { 
                return offset; 
            }
            set { 
                offset = value; 
            }
        }
        private int length;
        public int Length {
            get { 
                return length; 
            }
            set { 
                length = value; 
            }
        }
        private string recType;
        public string RecType {
            get { 
                return recType; 
            }
            set { 
                recType = value; 
            }
        }
        // レコード種別 2byte
        // 00 データレコード
        // 01 ファイル終了レコード
        // 02 拡張セグメントアドレスレコード
        // 03 スタートセグメントアドレスレコード
        // 04 拡張リニアアドレスレコード
        // 05 スタートリニアアドレスレコード
        private string data;
        public string Data {
            get { 
                return data; 
            }
            set { 
                data = value; 
            }
        }
    }
    public int StartAddr {
        get {
            return startAddr;
        }
    }
    public int EndAddr {
        get {
            return endAddr;
        }
    }
    public List<string>ParseErrorInfo {
        get {
            return parseErrorInfo;
        }
    }
    private string defaultValue;
    public string DefaultValue {
        get { 
            return defaultValue; 
        }
        set { 
            defaultValue = value; 
        }
    }
    private int startAddr;
    private int endAddr;
    private List<HexFileData> hexFileList = new List<HexFileData>();
    private List<string> parseErrorInfo = new List<string>();
    public HexFileParser() {
        DefaultValue = "00";
        clearParseInfo();
    }
    public void clearParseInfo() {
        startAddr = 0xFFFF;
        endAddr = 0x0000;
        parseErrorInfo.Clear();
        hexFileList.Clear();
    }
    public void parseLine(int lineNo, string inData) {
        string startMark;
        // 1byte    スタートマーク(":"固定)
        string byteCount;
        // 2byte    データ長
        string offsetAddress;
        // 4byte    データオフセット(開始位置)
        string recType;
        // 2byte    レコード種別 00:データ
        string data;
        // variable データ
        string checkSum;
        // 2byte    チェックサム
        if (inData.Length < 11)
        {
            parseErrorInfo.Add("行:" + lineNo + " レコード長が不正です");
            return;
        }
        startMark = inData.Substring(0, 1);
        byteCount = inData.Substring(1, 2);
        offsetAddress = inData.Substring(3, 4);
        recType = inData.Substring(7, 2);
        data = inData.Substring(9, inData.Length - 11);
        checkSum = inData.Substring(inData.Length - 2);
        if (!startMark.Equals(":"))
        {
            parseErrorInfo.Add("行:" + lineNo + " スタートマークが':'では有りません[data=" + startMark + "]");
            return;
        }
        if (!isHexaDecimal(byteCount))
        {
            parseErrorInfo.Add("行:" + lineNo + " バイトカウントが16進文字列では有りません[data=" + byteCount + "]");
            return;
        }
        if (!isHexaDecimal(offsetAddress))
        {
            parseErrorInfo.Add("行:" + lineNo + " オフセットアドレスが16進文字列では有りません[data=" + offsetAddress + "]");
            return;
        }
        if (!isHexaDecimal(recType))
        {
            parseErrorInfo.Add("行:" + lineNo + " レコード種別が16進文字列では有りません[data=" + recType + "]");
            return;
        }
        if (!recType.Equals("00") && !recType.Equals("01") && !recType.Equals("02") && !recType.Equals("03") && !recType.Equals("04") && !recType.Equals("05"))
        {
            parseErrorInfo.Add("行:" + lineNo + " レコード種別が00~05以外の値です[data=" + recType + "]");
            return;
        }
        if (!isHexaDecimal(data))
        {
            parseErrorInfo.Add("行:" + lineNo + " データが16進文字列では有りません[data=" + data + "]");
            return;
        }
        if (!isHexaDecimal(checkSum))
        {
            parseErrorInfo.Add("行:" + lineNo + " チェックサムが16進文字列では有りません[data=" + checkSum + "]");
            return;
        }
        uint calcValue = 0;
        for (int loop = 1; loop < inData.Length - 2; loop +=2)
        {
            string curValue = inData.Substring(loop, 2);
            calcValue += (uint) Convert.ToInt32(curValue, 16);
        }
        calcValue = (~calcValue) + 1;
        // 2の補数を取る
        calcValue &= 0x000000FF;
        // 下位16ビット分だけを抽出
        if (Convert.ToInt32(checkSum, 16) != calcValue)
        {
            parseErrorInfo.Add("行:" + lineNo + " チェックサムが一致しません[calc=" + calcValue.ToString() + ", data=" + checkSum + "]");
            return;
        }
        int start = Convert.ToInt32(offsetAddress, 16);
        int len = Convert.ToInt32(byteCount, 16);
        storeValue(start, len, recType, data);
    }
    public string getValue(int address) {
        HexFileData targetData = null;
        foreach (HexFileData curData in hexFileList)
        {
            if (curData.Offset <= address && curData.Offset + curData.Length > address)
            {
                targetData = curData;
                break;
            }
        }
        if (targetData == null)
        {
            int wordLen = DefaultValue.Length / 2;
            // 1ワードの長さを求める
            int wordPos = address % wordLen;
            // 要求されたアドレスが、ワード中のどこにあたるかかのoffsetを求める
            return DefaultValue.Substring(wordPos * 2, 2);
        }
        int pos = address - targetData.Offset;
        return targetData.Data.Substring(pos * 2, 2);
    }
    private void storeValue(int start, int len, string recType, string data) {
        if (!recType.Equals("00"))
        {
             return;
        }
        if (start < startAddr)
        {
            startAddr = start;
        }
        if (start + len > endAddr)
        {
            endAddr = start + len;
        }
        HexFileData hexFileData = new HexFileData();
        hexFileData.Offset = start;
        hexFileData.Length = len;
        hexFileData.RecType = recType;
        hexFileData.Data = data;
        hexFileList.Add(hexFileData);
    }
    private bool isHexaDecimal(string inData) {
        foreach (Char data in inData)
        {
            if ((data >= '0' && data <= '9') || (data >= 'A' && data <= 'F'))
            {
                continue;
            }
            return false;
        }
        return true;
    }
}
public class Hex0 {
    static void Main() {
        string fileName = "c:\\avr\\a0.hex";
        HexFileParser parser = new HexFileParser();
        //parser.DefaultValue = "FF3F";
        using (StreamReader reader = new StreamReader(fileName)) {
            int lineNo = 0;
            while (true)
            {
                string line = reader.ReadLine();
                if (line == null)
                {
                    break;
                }
                parser.parseLine(lineNo, line);
                Console.WriteLine(line + Environment.NewLine);
                lineNo++;
            }
        }
        //txtHexDump.Text = "";
        int loopCol = 0;
        int startAddr = parser.StartAddr;
        int endAddr = parser.EndAddr;
        for (int curAddr = startAddr; curAddr < endAddr; curAddr++)
        {
            string mCode = parser.getValue(curAddr);
            Console.WriteLine(mCode + " ");
            if (loopCol++ >= 16)
            {
                loopCol = 0;
                Console.WriteLine(Environment.NewLine);
            }
        }
    }
}




以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0