317 lines
9.4 KiB
C#
317 lines
9.4 KiB
C#
// UNCLASSIFIED
|
|
/*-------------------------------------------------------------------------
|
|
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
|
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
|
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
|
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
|
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
|
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
|
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
|
COMPANY.
|
|
|
|
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
|
GOVERNMENT.
|
|
|
|
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
|
-------------------------------------------------------------------------*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Raytheon.Common
|
|
{
|
|
/// <summary>
|
|
/// A class that reads a memory map upon construction and then serves up the fields of an entry upon request
|
|
/// </summary>
|
|
public class MemoryMap
|
|
{
|
|
#region PrivateClassMembers
|
|
public struct MemoryMapFields
|
|
{
|
|
public readonly uint _page;
|
|
public readonly uint _address;
|
|
public readonly int _startBit;
|
|
public readonly int _numBits;
|
|
public readonly uint _regDefault;
|
|
public readonly double _scaleFactor;
|
|
|
|
public MemoryMapFields(uint page, uint address, int startBit, int numBits, uint regDefault, double scaleFactor)
|
|
{
|
|
_page = page;
|
|
_address = address;
|
|
_startBit = startBit;
|
|
_numBits = numBits;
|
|
_regDefault = regDefault;
|
|
_scaleFactor = scaleFactor;
|
|
}
|
|
}
|
|
|
|
private struct BitInfo
|
|
{
|
|
public int _start;
|
|
public int _numOfBits;
|
|
}
|
|
|
|
private const string _NEWLINE = "\r\n";
|
|
private Dictionary<string, MemoryMapFields> _mapData;
|
|
private double _scaleFactor = 1.0;
|
|
#endregion
|
|
|
|
#region PrivateFuctions
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="fileLocation"></param>
|
|
/// <returns></returns>
|
|
private Dictionary<string, MemoryMapFields> CreateMemoryMapDictionary(string fileLocation)
|
|
{
|
|
Dictionary<string, MemoryMapFields> temp = new Dictionary<string, MemoryMapFields>();
|
|
|
|
//Open file for processing (read-only)
|
|
using (FileStream readStream = new FileStream(fileLocation, FileMode.Open, FileAccess.Read))
|
|
{
|
|
//Process the memmap
|
|
ProcessFile(readStream, temp);
|
|
}
|
|
|
|
return temp;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processes the memory map files into a data structure
|
|
/// </summary>
|
|
/// <param name="fs"></param>
|
|
/// <param name="memoryMap"></param>
|
|
private void ProcessFile(FileStream fs, Dictionary<string, MemoryMapFields> memoryMap)
|
|
{
|
|
uint page = 0;
|
|
uint address = 0;
|
|
uint regDefault = 0;
|
|
char[] delimit = { ' ' };
|
|
|
|
uint prevPage = 0;
|
|
uint prevAddress = 0;
|
|
uint parentRegDefault = 0;
|
|
|
|
using (StreamReader reader = new StreamReader(fs))
|
|
{
|
|
while (!reader.EndOfStream)
|
|
{
|
|
//Read a line from the file
|
|
string line = reader.ReadLine();
|
|
|
|
//Parse the line by spaces (remove empty entries)
|
|
string[] fields = line.Split(delimit, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
//If nothing to read, stop processing
|
|
if (fields.Length == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//Get the key (Register Name)
|
|
string key = fields[0].ToUpper();
|
|
|
|
//Check for duplicates
|
|
if (memoryMap.ContainsKey(key))
|
|
{
|
|
throw new Exception("Duplicate item found in file: " + fs.Name + ", Item key: " + key);
|
|
}
|
|
|
|
//Check if the register is a parent or child
|
|
//A child will use its parent address and gets it default value from its parent
|
|
if (line.StartsWith(" "))
|
|
{
|
|
regDefault = parentRegDefault;
|
|
page = prevPage;
|
|
address = prevAddress;
|
|
}
|
|
else
|
|
{
|
|
//Get the page number
|
|
page = ProcessPageNum(fields[1]);
|
|
|
|
//Get register address
|
|
address = ProcessDecimalHex(fields[1]);
|
|
|
|
//Get register default values
|
|
regDefault = ProcessDecimalHex(fields[5]);
|
|
|
|
//Get scale factor
|
|
_scaleFactor = ProcessScaleFactor(line);
|
|
}
|
|
|
|
//Process bits
|
|
BitInfo bitInfo = ProcessBitInfo(fields[3]);
|
|
|
|
double scaleFactor = _scaleFactor;
|
|
|
|
// parse out the default value for this child item
|
|
if (bitInfo._numOfBits < 32)
|
|
{
|
|
// clear the upper bits
|
|
int numBitsToClear = 32 - (bitInfo._start + bitInfo._numOfBits);
|
|
regDefault = regDefault << numBitsToClear;
|
|
|
|
// clear lower bits and place into position
|
|
int numBitsForPosition = bitInfo._start + numBitsToClear;
|
|
regDefault = regDefault >> numBitsForPosition;
|
|
}
|
|
else
|
|
{
|
|
parentRegDefault = regDefault;
|
|
}
|
|
|
|
memoryMap.Add(key, new MemoryMapFields(page, address, bitInfo._start, bitInfo._numOfBits, regDefault, scaleFactor));
|
|
|
|
// hold onto previous values for child items
|
|
prevPage = page;
|
|
prevAddress = address;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="pageNumber"></param>
|
|
/// <returns></returns>
|
|
private uint ProcessPageNum(string pageNumber)
|
|
{
|
|
//Delimiter used to parse string
|
|
char[] delimit = { '.' };
|
|
|
|
//Array of parsed string
|
|
string[] strPageValues = pageNumber.Split(delimit);
|
|
|
|
//Convert first array element
|
|
uint value = uint.Parse(strPageValues[0]);
|
|
|
|
//Return conversion
|
|
return value;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="address"></param>
|
|
/// <returns></returns>
|
|
private uint ProcessDecimalHex(string address)
|
|
{
|
|
//Delimiter used to parse string
|
|
char[] delimit = { '.' };
|
|
|
|
//Array of parsed string
|
|
string[] strValues = address.Split(delimit);
|
|
|
|
string strCombined = "";
|
|
|
|
//Address = 0.XXXX.XXXX, register values = XXXX.XXXX
|
|
if (strValues.Length == 3)
|
|
{
|
|
strCombined = strValues[1] + strValues[2];
|
|
}
|
|
else
|
|
{
|
|
strCombined = strValues[0] + strValues[1];
|
|
}
|
|
|
|
//Convert hex number to UInt
|
|
uint value = uint.Parse(strCombined, System.Globalization.NumberStyles.HexNumber);
|
|
|
|
//Return value
|
|
return value;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="bits"></param>
|
|
/// <returns></returns>
|
|
private BitInfo ProcessBitInfo(string bits)
|
|
{
|
|
//Structure for bit information
|
|
BitInfo temp;
|
|
|
|
//Delimiter used to parse string
|
|
char[] delimit = { ':' };
|
|
char[] trimChar = { '(', ')' };
|
|
|
|
string trimBits = bits.Trim(trimChar);
|
|
string[] values = trimBits.Split(delimit);
|
|
|
|
if (values.Length == 2)
|
|
{
|
|
//values represents a range of bits
|
|
int start = int.Parse(values[1]);
|
|
int end = int.Parse(values[0]);
|
|
|
|
//Add one for zero offset
|
|
temp._start = start;
|
|
temp._numOfBits = end - start + 1;
|
|
}
|
|
else
|
|
{
|
|
//Only a single bit
|
|
temp._numOfBits = 1;
|
|
temp._start = int.Parse(values[0]);
|
|
}
|
|
|
|
return temp;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="scaleFactor"></param>
|
|
/// <returns></returns>
|
|
private double ProcessScaleFactor(string scaleFactor)
|
|
{
|
|
const string PATTERN = @"[+-]?[0-9]{1,}\.[0-9]{1,}[e][+-]?[0-9]{1,}";
|
|
|
|
//Find Scale Factor (default = 1)
|
|
string sf = "1";
|
|
|
|
foreach (Match match in Regex.Matches(scaleFactor, PATTERN))
|
|
{
|
|
sf = match.Value;
|
|
}
|
|
|
|
double value = double.Parse(sf);
|
|
|
|
return value;
|
|
}
|
|
#endregion
|
|
|
|
#region PublicFuctions
|
|
|
|
/// <summary>
|
|
/// The constructor
|
|
/// </summary>
|
|
/// <param name="memMapLocation">The memory map file</param>
|
|
public MemoryMap(string memMapLocation)
|
|
{
|
|
_mapData = CreateMemoryMapDictionary(memMapLocation);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="registerName">The name of the register</param>
|
|
/// <returns></returns>
|
|
public MemoryMapFields GetRegisterInfoByString(string registerName)
|
|
{
|
|
if (_mapData.ContainsKey(registerName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("The requested register: " + registerName + " is not in the memory map");
|
|
}
|
|
|
|
return _mapData[registerName.ToUpper()];
|
|
}
|
|
#endregion
|
|
}
|
|
}
|