add home view and reverse 4 bytes order to send
This commit is contained in:
@@ -85,11 +85,11 @@ namespace Common
|
||||
/// <summary>
|
||||
/// 比特合并成二进制字节
|
||||
/// </summary>
|
||||
/// <param name="bits1">[TODO:parameter]</param>
|
||||
/// <param name="bits1Len">[TODO:parameter]</param>
|
||||
/// <param name="bits2">[TODO:parameter]</param>
|
||||
/// <param name="bits2Len">[TODO:parameter]</param>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <param name="bits1">第一个比特值</param>
|
||||
/// <param name="bits1Len">第一个比特值的长度(位数)</param>
|
||||
/// <param name="bits2">第二个比特值</param>
|
||||
/// <param name="bits2Len">第二个比特值的长度(位数)</param>
|
||||
/// <returns>合并后的二进制字节数组</returns>
|
||||
public static Result<byte[]> MultiBitsToBytes(ulong bits1, uint bits1Len, ulong bits2, uint bits2Len)
|
||||
{
|
||||
return NumberToBytes(MultiBitsToNumber(bits1, bits1Len, bits2, bits2Len).Value,
|
||||
@@ -99,11 +99,11 @@ namespace Common
|
||||
/// <summary>
|
||||
/// 比特合并成整型
|
||||
/// </summary>
|
||||
/// <param name="bits1">[TODO:parameter]</param>
|
||||
/// <param name="bits1Len">[TODO:parameter]</param>
|
||||
/// <param name="bits2">[TODO:parameter]</param>
|
||||
/// <param name="bits2Len">[TODO:parameter]</param>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <param name="bits1">第一个比特值</param>
|
||||
/// <param name="bits1Len">第一个比特值的长度(位数)</param>
|
||||
/// <param name="bits2">第二个比特值</param>
|
||||
/// <param name="bits2Len">第二个比特值的长度(位数)</param>
|
||||
/// <returns>合并后的整型值</returns>
|
||||
public static Result<ulong> MultiBitsToNumber(ulong bits1, uint bits1Len, ulong bits2, uint bits2Len)
|
||||
{
|
||||
if (bits1Len + bits2Len > 64) return new(new ArgumentException("Two Bits is more than 64 bits"));
|
||||
@@ -115,11 +115,11 @@ namespace Common
|
||||
/// <summary>
|
||||
/// 比特合并成整型
|
||||
/// </summary>
|
||||
/// <param name="bits1">[TODO:parameter]</param>
|
||||
/// <param name="bits1Len">[TODO:parameter]</param>
|
||||
/// <param name="bits2">[TODO:parameter]</param>
|
||||
/// <param name="bits2Len">[TODO:parameter]</param>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <param name="bits1">第一个比特值</param>
|
||||
/// <param name="bits1Len">第一个比特值的长度(位数)</param>
|
||||
/// <param name="bits2">第二个比特值</param>
|
||||
/// <param name="bits2Len">第二个比特值的长度(位数)</param>
|
||||
/// <returns>合并后的整型值</returns>
|
||||
public static Result<uint> MultiBitsToNumber(uint bits1, uint bits1Len, uint bits2, uint bits2Len)
|
||||
{
|
||||
if (bits1Len + bits2Len > 64) return new(new ArgumentException("Two Bits is more than 64 bits"));
|
||||
@@ -131,10 +131,10 @@ namespace Common
|
||||
/// <summary>
|
||||
/// 比特位检查
|
||||
/// </summary>
|
||||
/// <param name="srcBits">[TODO:parameter]</param>
|
||||
/// <param name="dstBits">[TODO:parameter]</param>
|
||||
/// <param name="mask">[TODO:parameter]</param>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <param name="srcBits">源比特值</param>
|
||||
/// <param name="dstBits">目标比特值</param>
|
||||
/// <param name="mask">掩码(默认为全1)</param>
|
||||
/// <returns>检查结果(是否匹配)</returns>
|
||||
public static bool BitsCheck(ulong srcBits, ulong dstBits, ulong mask = 0xFFFF_FFFF_FFFF_FFFF)
|
||||
{
|
||||
return (srcBits & mask) == dstBits;
|
||||
@@ -143,10 +143,10 @@ namespace Common
|
||||
/// <summary>
|
||||
/// 比特位检查
|
||||
/// </summary>
|
||||
/// <param name="srcBits">[TODO:parameter]</param>
|
||||
/// <param name="dstBits">[TODO:parameter]</param>
|
||||
/// <param name="mask">[TODO:parameter]</param>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <param name="srcBits">源比特值</param>
|
||||
/// <param name="dstBits">目标比特值</param>
|
||||
/// <param name="mask">掩码(默认为全1)</param>
|
||||
/// <returns>检查结果(是否匹配)</returns>
|
||||
public static bool BitsCheck(uint srcBits, uint dstBits, uint mask = 0xFFFF_FFFF)
|
||||
{
|
||||
return (srcBits & mask) == dstBits;
|
||||
@@ -156,9 +156,9 @@ namespace Common
|
||||
/// <summary>
|
||||
/// 字符串转二进制字节数组
|
||||
/// </summary>
|
||||
/// <param name="str">[TODO:parameter]</param>
|
||||
/// <param name="numBase">[TODO:parameter]</param>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <param name="str">输入的字符串</param>
|
||||
/// <param name="numBase">进制(默认为16进制)</param>
|
||||
/// <returns>转换后的二进制字节数组</returns>
|
||||
public static byte[] StringToBytes(string str, int numBase = 16)
|
||||
{
|
||||
var len = str.Length;
|
||||
@@ -173,10 +173,52 @@ namespace Common
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反转字节数组中的子数组
|
||||
/// </summary>
|
||||
/// <param name="srcBytes">源字节数组</param>
|
||||
/// <param name="distance">子数组的长度(反转的步长)</param>
|
||||
/// <returns>反转后的字节数组</returns>
|
||||
public static Result<byte[]> ReverseBytes(byte[] srcBytes, int distance)
|
||||
{
|
||||
if (distance <= 0)
|
||||
return new(new ArgumentException("Distance can't be negetive", nameof(distance)));
|
||||
|
||||
var srcBytesLen = srcBytes.Length;
|
||||
if (distance > srcBytesLen)
|
||||
return new(new ArgumentException(
|
||||
"Distance is larger than bytesArray", nameof(distance)));
|
||||
if (srcBytesLen % distance != 0)
|
||||
return new(new ArgumentException(
|
||||
"The length of bytes can't be divided by 2 without reminder", nameof(distance)));
|
||||
|
||||
var dstBytes = new byte[srcBytesLen];
|
||||
var buffer = new byte[distance];
|
||||
|
||||
for (int i = 0; i < srcBytesLen; i += distance)
|
||||
{
|
||||
var end = i + distance;
|
||||
buffer = srcBytes[i..end];
|
||||
Array.Reverse(buffer);
|
||||
Array.Copy(buffer, 0, dstBytes, i, distance);
|
||||
}
|
||||
|
||||
return dstBytes;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字符串处理工具
|
||||
/// </summary>
|
||||
public class String
|
||||
{
|
||||
/// <summary>
|
||||
/// 反转字符串
|
||||
/// </summary>
|
||||
/// <param name="s">输入的字符串</param>
|
||||
/// <returns>反转后的字符串</returns>
|
||||
public static string Reverse(string s)
|
||||
{
|
||||
char[] charArray = s.ToCharArray();
|
||||
|
@@ -323,7 +323,11 @@ public class JtagController : ControllerBase
|
||||
int bytesRead;
|
||||
while ((bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
||||
{
|
||||
await memoryStream.WriteAsync(buffer, 0, bytesRead);
|
||||
var revBuffer = Common.Number.ReverseBytes(buffer, 4);
|
||||
if (!revBuffer.IsSuccessful)
|
||||
return TypedResults.InternalServerError(revBuffer.Error);
|
||||
|
||||
await memoryStream.WriteAsync(revBuffer.Value, 0, bytesRead);
|
||||
totalBytesRead += bytesRead;
|
||||
}
|
||||
|
||||
@@ -360,97 +364,19 @@ public class JtagController : ControllerBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 日志控制器
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class Log : ControllerBase
|
||||
{
|
||||
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// 日志文件路径
|
||||
/// </summary>
|
||||
private readonly string _logFilePath = Directory.GetFiles(Directory.GetCurrentDirectory())[0];
|
||||
|
||||
[EnableCors("Development")]
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
if (!System.IO.File.Exists(_logFilePath))
|
||||
{
|
||||
Problem("日志文件不存在");
|
||||
}
|
||||
|
||||
// 请求头
|
||||
Response.Headers.Add("Content-Type", "text/event-stream");
|
||||
Response.Headers.Add("Cache-Control", "no-cache");
|
||||
Response.Headers.Add("Connection", "keep-alive");
|
||||
|
||||
long position = 0;
|
||||
while (!HttpContext.RequestAborted.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (System.IO.File.Exists(_logFilePath))
|
||||
{
|
||||
using (var stream = new FileStream(_logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
stream.Position = position;
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
string? line;
|
||||
while ((line = await reader.ReadLineAsync()) != null)
|
||||
{
|
||||
// await WriteEvent(line);
|
||||
await Response.WriteAsync($"data: {line}\n\n");
|
||||
await Response.Body.FlushAsync();
|
||||
position = stream.Position;
|
||||
}
|
||||
if (line is null) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await WriteEvent("日志文件被删除");
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await WriteEvent($"错误: {ex.Message}");
|
||||
}
|
||||
|
||||
await Task.Delay(1000, HttpContext.RequestAborted); // 每秒检查一次
|
||||
}
|
||||
|
||||
// 结束
|
||||
return new EmptyResult();
|
||||
}
|
||||
|
||||
private async Task WriteEvent(string message)
|
||||
{
|
||||
await Response.WriteAsync($"data: {message}\n\n");
|
||||
await Response.Body.FlushAsync();
|
||||
}
|
||||
|
||||
// [EnableCors("Development")]
|
||||
// [HttpGet("example")]
|
||||
// public async Task<IActionResult> SseExample(HttpContext ctx, ItemService service, CancellationToken ct)
|
||||
// {
|
||||
// // 请求头
|
||||
// ctx.Response.Headers.Add("Content-Type", "text/event-stream");
|
||||
// // Response.Headers.Add("Content-Type", "text/event-stream");
|
||||
// // Response.Headers.Add("Cache-Control", "no-cache");
|
||||
// // Response.Headers.Add("Connection", "keep-alive");
|
||||
//
|
||||
// while (!ct.IsCancellationRequested)
|
||||
// {
|
||||
// var item = await service.WaitForNewItem();
|
||||
//
|
||||
// await ctx.Response.WriteAsync($"data: ");
|
||||
// await JsonSerializer.SerializeAsync(ctx.Response.Body, item);
|
||||
// await ctx.Response.WriteAsync($"\n\n");
|
||||
// await ctx.Response.Body.FlushAsync();
|
||||
//
|
||||
// service.Reset();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
@@ -229,11 +229,11 @@ public class Jtag
|
||||
private IPEndPoint ep;
|
||||
|
||||
/// <summary>
|
||||
/// Jtag构造函数
|
||||
/// Jtag 构造函数
|
||||
/// </summary>
|
||||
/// <param name="address">目标IP地址</param>
|
||||
/// <param name="port">目标UDP端口</param>
|
||||
/// <param name="timeout">超时时间</param>
|
||||
/// <param name="address">目标 IP 地址</param>
|
||||
/// <param name="port">目标 UDP 端口</param>
|
||||
/// <param name="timeout">超时时间(毫秒)</param>
|
||||
public Jtag(string address, int port, int timeout = 2000)
|
||||
{
|
||||
this.address = address;
|
||||
@@ -276,6 +276,13 @@ public class Jtag
|
||||
return Convert.ToUInt32(Common.Number.BytesToNumber(retPackOpts.Data).Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向指定的 JTAG 设备地址写入数据到 FIFO
|
||||
/// </summary>
|
||||
/// <param name="devAddr">目标设备地址</param>
|
||||
/// <param name="data">要写入的数据</param>
|
||||
/// <param name="delayMilliseconds">写入后的延迟时间(毫秒)</param>
|
||||
/// <returns>包含接收数据包的异步结果</returns>
|
||||
public async ValueTask<Result<RecvDataPackage>> WriteFIFO(UInt32 devAddr, UInt32 data, UInt32 delayMilliseconds = 0)
|
||||
{
|
||||
var ret = false;
|
||||
@@ -462,16 +469,28 @@ public class Jtag
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有 JTAG 寄存器
|
||||
/// </summary>
|
||||
/// <returns>指示清除是否成功的异步结果</returns>
|
||||
async ValueTask<Result<bool>> ClearAllRegisters()
|
||||
{
|
||||
return await WriteFIFO(JtagAddr.STATE, 0xFF_FF_FF_FF, 0x01_02_02_02, JtagState.ALL_REG);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除 JTAG 写数据寄存器
|
||||
/// </summary>
|
||||
/// <returns>指示清除是否成功的异步结果</returns>
|
||||
async ValueTask<Result<bool>> ClearWriteDataReg()
|
||||
{
|
||||
return await WriteFIFO(JtagAddr.STATE, 0x00_00_11_00, 0x01_00_02_00, JtagState.WRITE_DATA_FIFO | JtagState.CMD_EXEC_FINISH);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭 JTAG 测试模式
|
||||
/// </summary>
|
||||
/// <returns>指示操作是否成功的异步结果</returns>
|
||||
async ValueTask<Result<bool>> CloseTest()
|
||||
{
|
||||
return await WriteFIFO(
|
||||
@@ -480,6 +499,10 @@ public class Jtag
|
||||
0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动 JTAG 测试模式
|
||||
/// </summary>
|
||||
/// <returns>指示操作是否成功的异步结果</returns>
|
||||
async ValueTask<Result<bool>> RunTest()
|
||||
{
|
||||
return await WriteFIFO(
|
||||
@@ -488,6 +511,11 @@ public class Jtag
|
||||
0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置 JTAG 空闲延迟时间
|
||||
/// </summary>
|
||||
/// <param name="milliseconds">延迟时间(毫秒)</param>
|
||||
/// <returns>指示操作是否成功的异步结果</returns>
|
||||
async ValueTask<Result<bool>> IdleDelay(UInt32 milliseconds)
|
||||
{
|
||||
if (milliseconds > Math.Pow(2, 28)) return new(new Exception("Timespan is over 2^28 milliseconds"));
|
||||
@@ -562,6 +590,10 @@ public class Jtag
|
||||
return new(new Exception("LoadDRCareo Failed!"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取 JTAG 设备的 ID 代码
|
||||
/// </summary>
|
||||
/// <returns>包含 ID 代码的异步结果</returns>
|
||||
public async ValueTask<Result<uint>> ReadIDCode()
|
||||
{
|
||||
// Clear Data
|
||||
@@ -596,6 +628,10 @@ public class Jtag
|
||||
return retData.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取 JTAG 设备的状态寄存器
|
||||
/// </summary>
|
||||
/// <returns>包含状态寄存器值的异步结果</returns>
|
||||
public async ValueTask<Result<uint>> ReadStatusReg()
|
||||
{
|
||||
// Clear Data
|
||||
@@ -630,6 +666,11 @@ public class Jtag
|
||||
return retData.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载比特流到 JTAG 设备
|
||||
/// </summary>
|
||||
/// <param name="bitstream">比特流数据</param>
|
||||
/// <returns>指示下载是否成功的异步结果</returns>
|
||||
public async ValueTask<Result<bool>> DownloadBitstream(byte[] bitstream)
|
||||
{
|
||||
// Clear Data
|
||||
@@ -663,7 +704,7 @@ public class Jtag
|
||||
|
||||
logger.Trace("Jtag ready to write bitstream");
|
||||
|
||||
ret = await IdleDelay(75000);
|
||||
ret = await IdleDelay(100000);
|
||||
if (!ret.IsSuccessful) return new(ret.Error);
|
||||
else if (!ret.Value) return new(new Exception("Jtag IDLE Delay Failed"));
|
||||
|
||||
@@ -687,7 +728,7 @@ public class Jtag
|
||||
|
||||
logger.Trace("Jtag reset device");
|
||||
|
||||
ret = await IdleDelay(1000);
|
||||
ret = await IdleDelay(10000);
|
||||
if (!ret.IsSuccessful) return new(ret.Error);
|
||||
else if (!ret.Value) return new(new Exception("Jtag IDLE Delay Failed"));
|
||||
|
||||
|
@@ -81,9 +81,13 @@ public class UDPServer
|
||||
/// <summary> UDP 服务器的错误代码 </summary>
|
||||
public enum ErrorCode
|
||||
{
|
||||
/// <summary> [TODO:description] </summary>
|
||||
Success = 0,
|
||||
/// <summary> [TODO:description] </summary>
|
||||
GetNoneAfterTimeout,
|
||||
/// <summary> [TODO:description] </summary>
|
||||
ResponseWrong,
|
||||
/// <summary> [TODO:description] </summary>
|
||||
NotRecvDataPackage,
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user