Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
using CommandLine;
using Hast.Communication.Exceptions;
using Hast.Layer;
using Hast.Transformer.Abstractions.SimpleMemory;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hast.Communication.Tester
{
partial class Program
{
public const string DefaultHexdumpFileName = "dump.txt";
public const string DefaultBinaryFileName = "dump.bin";
public const int HexDumpBlocksPerLine = 8;
private static async Task MainTask(Options configuration)
{
using (var hastlayer = await Hastlayer.Create(new HastlayerConfiguration { Flavor = HastlayerFlavor.Developer }))
{
// Get devices and if asked exit with the device list.
var devices = await hastlayer.GetSupportedDevices();
if (devices == null || !devices.Any()) throw new Exception("No devices are available!");
if (configuration.ListDevices)
{
foreach (var d in devices) Console.WriteLine(d.Name);
return;
}
// If there is an output file name, then the file type can not be None.
if (configuration.OutputFileType == OutputFileType.None && !string.IsNullOrEmpty(configuration.OutputFileName))
configuration.OutputFileType = OutputFileType.Hexdump;
// Try to load selected device or pick the first available if none were selected.
if (string.IsNullOrEmpty(configuration.DeviceName)) configuration.DeviceName = devices.First().Name;
var selectedDevice = devices.FirstOrDefault(device => device.Name == configuration.DeviceName);
if (selectedDevice == null) throw new Exception($"Target device '{configuration.DeviceName}' not found!");
var channelName = selectedDevice.DefaultCommunicationChannelName;
var (memory, accessor) = GenerateMemory(configuration.PayloadType,
configuration.PayloadLengthCells, configuration.InputFileName);
// Save input to file using the format of the output file type.
SaveFile(configuration.OutputFileType, configuration.PayloadType, configuration.InputFileName, true, memory);
// Create reference copy of input to compare against output.
var referenceMemory = configuration.NoCheck ? null : SimpleMemoryAccessor.Create(accessor.Get());
Console.WriteLine("Starting hardware execution.");
var communicationService = await hastlayer.GetCommunicationService(channelName);
communicationService.TesterOutput = Console.Out;
var executionContext = new BasicExecutionContext(hastlayer, selectedDevice.Name,
selectedDevice.DefaultCommunicationChannelName);
var info = await communicationService.Execute(memory, configuration.MemberId, executionContext);
Console.WriteLine("Executing test on hardware took {0:0.##}ms (net) {1:0.##}ms (all together)",
info.HardwareExecutionTimeMilliseconds, info.FullExecutionTimeMilliseconds);
// Save output to file.
SaveFile(configuration.OutputFileType, configuration.PayloadType, configuration.OutputFileName, false, memory);
if (!string.IsNullOrWhiteSpace(configuration?.JsonOutputFileName))
{
var json = JsonConvert.SerializeObject(new { Success = true, Result = info });
File.WriteAllText(configuration.JsonOutputFileName, json);
}
// Verify results if wanted.
if (!configuration.NoCheck) Verify(memory, referenceMemory);
}
}
private static (SimpleMemory, SimpleMemoryAccessor) GenerateMemory(PayloadType type, int cellCount, string inputFileName)
{
Console.WriteLine("Generating memory.");
var memory = new SimpleMemory(cellCount);
var accessor = new SimpleMemoryAccessor(memory);
switch (type)
{
case PayloadType.ConstantIntOne:
for (int i = 0; i < memory.CellCount; i++) memory.WriteInt32(i, 1);
break;
case PayloadType.Counter:
for (int i = 0; i < memory.CellCount; i++) memory.WriteInt32(i, i);
break;
case PayloadType.Random:
var random = new Random();
for (int i = 0; i < memory.CellCount; i++)
memory.WriteInt32(i, random.Next(int.MinValue, int.MaxValue));
break;
case PayloadType.BinaryFile:
using (var fileStream = File.OpenRead(inputFileName))
{
int prefixBytes = 4 * SimpleMemory.MemoryCellSizeBytes;
var data = new byte[fileStream.Length + prefixBytes];
fileStream.Read(data, prefixBytes, (int)fileStream.Length);
accessor.Set(data, 4);
}
break;
default:
throw new ArgumentException($"Unknown payload type: {type}.");
}
return (memory, accessor);
}
private static void SaveFile(OutputFileType fileType,
PayloadType payloadType,
string fileName,
bool isInput,
SimpleMemory memory)
{
var fileNamePrefix = isInput ? "in-" : "out-";
var direction = isInput ? "input" : "output";
switch (fileType)
{
case OutputFileType.None: return;
case OutputFileType.Hexdump:
if (string.IsNullOrEmpty(fileName)) fileName = fileNamePrefix + DefaultHexdumpFileName;
Console.WriteLine("Saving {0} hexdump to '{1}'...", direction, fileName);
if (fileName == Options.OutputFileNameConsole)
{
WriteHexdump(Console.Out, memory);
}
else
{
using (var streamWriter = new StreamWriter(fileName, false, Encoding.UTF8))
{
WriteHexdump(streamWriter, memory);
}
}
break;
case OutputFileType.Binary:
if (payloadType != PayloadType.BinaryFile)
{
if (string.IsNullOrEmpty(fileName)) fileName = fileNamePrefix + DefaultBinaryFileName;
Console.WriteLine("Saving {0} binary file to '{1}'...", direction, fileName);
using (var fileStream = File.OpenWrite(fileName))
{
var accessor = new SimpleMemoryAccessor(memory);
var segment = accessor.Get().GetUnderlyingArray();
fileStream.Write(segment.Array, segment.Offset, memory.ByteCount);
}
}
break;
default:
throw new ArgumentException(string.Format("Unknown {0} file type: {1}", direction, fileType));
}
Console.WriteLine("File saved.");
}
private static void Verify(SimpleMemory memory, SimpleMemory referenceMemory)
{
var mismatches = new List<HardwareExecutionResultMismatchException.Mismatch>();
for (int i = 0; i < memory.CellCount && i < referenceMemory.CellCount; i++)
{
if (!memory.Read4Bytes(i).SequenceEqual(referenceMemory.Read4Bytes(i)))
{
mismatches.Add(new HardwareExecutionResultMismatchException.Mismatch(
i, memory.Read4Bytes(i), referenceMemory.Read4Bytes(i)));
}
}
if (mismatches.Count > 0)
{
Console.WriteLine("MISMATCH:");
Console.WriteLine(new HardwareExecutionResultMismatchException(mismatches));
}
if (memory.CellCount != referenceMemory.CellCount)
{
Console.WriteLine("MISMATCH IN LENGTH:{0}Hardware: {1}{0}Software: {2}",
Environment.NewLine, memory.CellCount, referenceMemory.CellCount);
}
else if (mismatches.Count == 0)
{
Console.WriteLine("Verification passed!");
}
}
public static void WriteHexdump(TextWriter writer, SimpleMemory memory)
{
for (int i = 0; i < memory.CellCount; i += HexDumpBlocksPerLine)
{
for (int j = 0; j < HexDumpBlocksPerLine && i + j < memory.CellCount; j++)
{
writer.Write("{0}{1:X8}", j == 0 ? "" : " ", memory.ReadUInt32(i + j));
}
writer.WriteLine();
}
}
private static void Main(string[] args)
{
Options configuration = null;
try
{
Parser.Default.ParseArguments<Options>(args).WithParsed(o => { configuration = o; });
if (configuration == null) throw new ArgumentNullException(nameof(configuration));
MainTask(configuration).Wait();
}
catch (Exception ex)
{
Console.WriteLine(ex);
if (!string.IsNullOrWhiteSpace(configuration?.JsonOutputFileName))
{
var json = JsonConvert.SerializeObject(new { Success = false, Exception = ex });
File.WriteAllText(configuration.JsonOutputFileName, json);
}
}
if (Debugger.IsAttached) Console.ReadKey();
}
}
}
25e4499d9This file is pinned to the selected release. Download the original to open it in your design tool.