概要
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);
}
}
}
}
以上。