Merge branch 'csharp'

This commit is contained in:
SikongJueluo 2025-04-23 13:43:42 +08:00
commit 7f99a5be24
No known key found for this signature in database
6 changed files with 169 additions and 122 deletions

View File

@ -3,6 +3,12 @@
pwd pwd
echo echo
clean:
rm -rf "server/bin"
rm -rf "server/obj"
rm -rf "server.test/bin"
rm -rf "server.test/obj"
[working-directory: "server"] [working-directory: "server"]
publish: _show-dir publish: _show-dir
dotnet publish --self-contained false -t:PublishAllRids dotnet publish --self-contained false -t:PublishAllRids

View File

@ -18,10 +18,10 @@ namespace Common
{ {
if (length > 8) if (length > 8)
{ {
throw new ArgumentException( return new(new ArgumentException(
"Unsigned long number can't over 8 bytes(64 bits).", "Unsigned long number can't over 8 bytes(64 bits).",
nameof(length) nameof(length)
); ));
} }
var arr = new byte[length]; var arr = new byte[length];
@ -53,10 +53,10 @@ namespace Common
{ {
if (bytes.Length > 8) if (bytes.Length > 8)
{ {
throw new ArgumentException( return new(new ArgumentException(
"Unsigned long number can't over 8 bytes(64 bits).", "Unsigned long number can't over 8 bytes(64 bits).",
nameof(bytes) nameof(bytes)
); ));
} }
ulong num = 0; ulong num = 0;
@ -106,7 +106,7 @@ namespace Common
/// <returns>[TODO:return]</returns> /// <returns>[TODO:return]</returns>
public static Result<ulong> MultiBitsToNumber(ulong bits1, uint bits1Len, ulong bits2, uint bits2Len) public static Result<ulong> MultiBitsToNumber(ulong bits1, uint bits1Len, ulong bits2, uint bits2Len)
{ {
if (bits1Len + bits2Len > 64) throw new ArgumentException("Two Bits is more than 64 bits"); if (bits1Len + bits2Len > 64) return new(new ArgumentException("Two Bits is more than 64 bits"));
ulong num = (bits1 << Convert.ToInt32(bits2Len)) | bits2; ulong num = (bits1 << Convert.ToInt32(bits2Len)) | bits2;
return num; return num;
@ -122,7 +122,7 @@ namespace Common
/// <returns>[TODO:return]</returns> /// <returns>[TODO:return]</returns>
public static Result<uint> MultiBitsToNumber(uint bits1, uint bits1Len, uint bits2, uint bits2Len) public static Result<uint> MultiBitsToNumber(uint bits1, uint bits1Len, uint bits2, uint bits2Len)
{ {
if (bits1Len + bits2Len > 64) throw new ArgumentException("Two Bits is more than 64 bits"); if (bits1Len + bits2Len > 64) return new(new ArgumentException("Two Bits is more than 64 bits"));
uint num = (bits1 << Convert.ToInt32(bits2Len)) | bits2; uint num = (bits1 << Convert.ToInt32(bits2Len)) | bits2;
return num; return num;

View File

@ -1,5 +1,6 @@
using System.Net; using System.Net;
using Common; using Common;
using DotNext;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json; using Newtonsoft.Json;
using WebProtocol; using WebProtocol;
@ -149,6 +150,7 @@ public class JtagController : ControllerBase
{ {
return "This is Jtag Controller"; return "This is Jtag Controller";
} }
/// <summary> /// <summary>
/// 执行一个Jtag命令 /// 执行一个Jtag命令
/// </summary> /// </summary>
@ -182,8 +184,16 @@ public class JtagController : ControllerBase
var jtagCtrl = new JtagClient.Jtag(address, port); var jtagCtrl = new JtagClient.Jtag(address, port);
var ret = await jtagCtrl.ReadIDCode(); var ret = await jtagCtrl.ReadIDCode();
if (ret.IsSuccessful) { return TypedResults.Ok(ret.Value); } if (ret.IsSuccessful)
else { return TypedResults.InternalServerError(ret.Error); } {
logger.Info($"Get device {address} ID code: 0x{ret.Value:X4}");
return TypedResults.Ok(ret.Value);
}
else
{
logger.Error(ret.Error);
return TypedResults.InternalServerError(ret.Error);
}
} }
/// <summary> /// <summary>
@ -217,7 +227,8 @@ public class JtagController : ControllerBase
await file.CopyToAsync(stream); await file.CopyToAsync(stream);
} }
return TypedResults.Ok("文件上传成功"); logger.Info($"Device {address} Upload Bitstream Successfully");
return TypedResults.Ok("Bitstream Upload Successfully");
} }
/// <summary> /// <summary>
@ -265,8 +276,16 @@ public class JtagController : ControllerBase
var jtagCtrl = new JtagClient.Jtag(address, port); var jtagCtrl = new JtagClient.Jtag(address, port);
var ret = await jtagCtrl.DownloadBitstream(fileBytes); var ret = await jtagCtrl.DownloadBitstream(fileBytes);
if (ret.IsSuccessful) { return TypedResults.Ok(ret.Value); } if (ret.IsSuccessful)
else { return TypedResults.InternalServerError(ret.Error); } {
logger.Info($"Device {address} dowload bitstream successfully");
return TypedResults.Ok(ret.Value);
}
else
{
logger.Error(ret.Error);
return TypedResults.InternalServerError(ret.Error);
}
} }
} }
catch (Exception error) catch (Exception error)

View File

@ -213,23 +213,34 @@ public static class JtagCmd
public const UInt32 CMD_JTAG_IDLE_DELAY = 0b0101; public const UInt32 CMD_JTAG_IDLE_DELAY = 0b0101;
} }
class Jtag /// <summary>
/// Jtag控制器
/// </summary>
public class Jtag
{ {
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
readonly int timeout; readonly int timeout;
readonly int port; readonly int port;
readonly string address; readonly string address;
private IPEndPoint ep; private IPEndPoint ep;
public Jtag(string address, int port, int outTime = 2000) /// <summary>
/// Jtag构造函数
/// </summary>
/// <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; this.address = address;
this.port = port; this.port = port;
this.ep = new IPEndPoint(IPAddress.Parse(address), port); this.ep = new IPEndPoint(IPAddress.Parse(address), port);
this.timeout = outTime; this.timeout = timeout;
} }
public async ValueTask<Result<uint>> ReadFIFO(uint devAddr) async ValueTask<Result<uint>> ReadFIFO(uint devAddr)
{ {
var ret = false; var ret = false;
var opts = new SendAddrPackOptions(); var opts = new SendAddrPackOptions();
@ -242,23 +253,23 @@ class Jtag
// Read Jtag State Register // Read Jtag State Register
opts.IsWrite = false; opts.IsWrite = false;
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
if (!ret) throw new Exception("Send Address Package Failed!"); if (!ret) return new(new Exception("Send Address Package Failed!"));
// Wait for Read Ack // Wait for Read Ack
if (!MsgBus.IsRunning) if (!MsgBus.IsRunning)
throw new Exception("Message Bus not Working!"); return new(new Exception("Message Bus not Working!"));
var retPack = await MsgBus.UDPServer.WaitForDataAsync(address, port); var retPack = await MsgBus.UDPServer.WaitForDataAsync(address, port);
if (!retPack.IsSuccessful || !retPack.Value.IsSuccessful) if (!retPack.IsSuccessful || !retPack.Value.IsSuccessful)
throw new Exception("Send address package failed"); return new(new Exception("Send address package failed"));
var retPackOpts = retPack.Value.Options; var retPackOpts = retPack.Value.Options;
if (retPackOpts.Data is null) if (retPackOpts.Data is null)
throw new Exception($"Data is Null, package: {retPackOpts.ToString()}"); return new(new Exception($"Data is Null, package: {retPackOpts.ToString()}"));
var retPackLen = retPackOpts.Data.Length; var retPackLen = retPackOpts.Data.Length;
if (retPackLen != 4) if (retPackLen != 4)
throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"); return new(new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"));
return Convert.ToUInt32(Common.Number.BytesToNumber(retPackOpts.Data).Value); return Convert.ToUInt32(Common.Number.BytesToNumber(retPackOpts.Data).Value);
} }
@ -277,36 +288,36 @@ class Jtag
// Write Jtag State Register // Write Jtag State Register
opts.IsWrite = true; opts.IsWrite = true;
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
if (!ret) throw new Exception("Send 1st address package failed!"); if (!ret) return new(new Exception("Send 1st address package failed!"));
// Send Data Package // Send Data Package
ret = await UDPClientPool.SendDataPackAsync(ep, ret = await UDPClientPool.SendDataPackAsync(ep,
new SendDataPackage(Common.Number.NumberToBytes(data, 4).Value)); new SendDataPackage(Common.Number.NumberToBytes(data, 4).Value));
if (!ret) throw new Exception("Send data package failed!"); if (!ret) return new(new Exception("Send data package failed!"));
// Check Msg Bus // Check Msg Bus
if (!MsgBus.IsRunning) if (!MsgBus.IsRunning)
throw new Exception("Message bus not working!"); return new(new Exception("Message bus not working!"));
// Wait for Write Ack // Wait for Write Ack
var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port); var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port);
if (!udpWriteAck.IsSuccessful) throw udpWriteAck.Error; if (!udpWriteAck.IsSuccessful) return new(udpWriteAck.Error);
else if (!udpWriteAck.Value.IsSuccessful) else if (!udpWriteAck.Value.IsSuccessful)
throw new Exception("Send address package failed"); return new(new Exception("Send address package failed"));
// Read Jtag State Register // Read Jtag State Register
opts.IsWrite = false; opts.IsWrite = false;
opts.Address = JtagAddr.STATE; opts.Address = JtagAddr.STATE;
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
if (!ret) throw new Exception("Send 2rd Address Package Failed!"); if (!ret) return new(new Exception("Send 2rd Address Package Failed!"));
// Wait for Read Data // Wait for Read Data
var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port); var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port);
if (!udpDataResp.IsSuccessful) throw udpDataResp.Error; if (!udpDataResp.IsSuccessful) return new(udpDataResp.Error);
else if (!udpDataResp.Value.IsSuccessful) else if (!udpDataResp.Value.IsSuccessful)
throw new Exception("Send address package failed"); return new(new Exception("Send address package failed"));
return udpDataResp.Value; return udpDataResp.Value;
} }
public async ValueTask<Result<RecvDataPackage>> WriteFIFO(UInt32 devAddr, byte[] dataArray) async ValueTask<Result<RecvDataPackage>> WriteFIFO(UInt32 devAddr, byte[] dataArray)
{ {
var ret = false; var ret = false;
var opts = new SendAddrPackOptions(); var opts = new SendAddrPackOptions();
@ -318,7 +329,7 @@ class Jtag
// Check Msg Bus // Check Msg Bus
if (!MsgBus.IsRunning) if (!MsgBus.IsRunning)
throw new Exception("Message bus not working!"); return new(new Exception("Message bus not working!"));
var writeTimes = dataArray.Length / (256 * (32 / 8)) + 1; var writeTimes = dataArray.Length / (256 * (32 / 8)) + 1;
for (var i = 0; i < writeTimes; i++) for (var i = 0; i < writeTimes; i++)
@ -328,7 +339,7 @@ class Jtag
opts.IsWrite = true; opts.IsWrite = true;
opts.BurstLength = isLastData ? (byte)(dataArray.Length - i * (256 * (32 / 8)) - 1) : (byte)255; opts.BurstLength = isLastData ? (byte)(dataArray.Length - i * (256 * (32 / 8)) - 1) : (byte)255;
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
if (!ret) throw new Exception("Send 1st address package failed!"); if (!ret) return new(new Exception("Send 1st address package failed!"));
// Send Data Package // Send Data Package
ret = await UDPClientPool.SendDataPackAsync(ep, ret = await UDPClientPool.SendDataPackAsync(ep,
new SendDataPackage( new SendDataPackage(
@ -337,13 +348,13 @@ class Jtag
dataArray[(i * (256 * (32 / 8)))..((i + 1) * (256 * (32 / 8)) - 1)] dataArray[(i * (256 * (32 / 8)))..((i + 1) * (256 * (32 / 8)) - 1)]
) )
); );
if (!ret) throw new Exception("Send data package failed!"); if (!ret) return new(new Exception("Send data package failed!"));
// Wait for Write Ack // Wait for Write Ack
var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port); var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port);
if (!udpWriteAck.IsSuccessful) throw udpWriteAck.Error; if (!udpWriteAck.IsSuccessful) return new(udpWriteAck.Error);
else if (!udpWriteAck.Value.IsSuccessful) else if (!udpWriteAck.Value.IsSuccessful)
throw new Exception("Send address package failed"); return new(new Exception("Send address package failed"));
} }
// Read Jtag State Register // Read Jtag State Register
@ -351,29 +362,29 @@ class Jtag
opts.BurstLength = 0; opts.BurstLength = 0;
opts.Address = JtagAddr.STATE; opts.Address = JtagAddr.STATE;
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
if (!ret) throw new Exception("Send 2rd Address Package Failed!"); if (!ret) return new(new Exception("Send 2rd Address Package Failed!"));
// Wait for Read Data // Wait for Read Data
var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port); var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port);
if (!udpDataResp.IsSuccessful) throw udpDataResp.Error; if (!udpDataResp.IsSuccessful) return new(udpDataResp.Error);
else if (!udpDataResp.Value.IsSuccessful) else if (!udpDataResp.Value.IsSuccessful)
throw new Exception("Send address package failed"); return new(new Exception("Send address package failed"));
return udpDataResp.Value; return udpDataResp.Value;
} }
public async ValueTask<Result<bool>> WriteFIFO async ValueTask<Result<bool>> WriteFIFO
(UInt32 devAddr, UInt32 data, UInt32 result, UInt32 resultMask = 0xFF_FF_FF_FF) (UInt32 devAddr, UInt32 data, UInt32 result, UInt32 resultMask = 0xFF_FF_FF_FF)
{ {
var ret = false; var ret = false;
var retPack = await WriteFIFO(devAddr, data); var retPack = await WriteFIFO(devAddr, data);
if (!retPack.IsSuccessful) throw retPack.Error; if (!retPack.IsSuccessful) return new(retPack.Error);
if (retPack.Value.Options.Data is null) if (retPack.Value.Options.Data is null)
throw new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}"); return new(new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}"));
var retPackLen = retPack.Value.Options.Data.Length; var retPackLen = retPack.Value.Options.Data.Length;
if (retPackLen != 4) if (retPackLen != 4)
throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"); return new(new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"));
if (Common.Number.BitsCheck( if (Common.Number.BitsCheck(
Common.Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask)) Common.Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask))
@ -382,18 +393,18 @@ class Jtag
return ret; return ret;
} }
public async ValueTask<Result<bool>> WriteFIFO async ValueTask<Result<bool>> WriteFIFO
(UInt32 devAddr, byte[] data, UInt32 result, UInt32 resultMask = 0xFF_FF_FF_FF) (UInt32 devAddr, byte[] data, UInt32 result, UInt32 resultMask = 0xFF_FF_FF_FF)
{ {
var ret = false; var ret = false;
var retPack = await WriteFIFO(devAddr, data); var retPack = await WriteFIFO(devAddr, data);
if (retPack.Value.Options.Data is null) if (retPack.Value.Options.Data is null)
throw new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}"); return new(new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}"));
var retPackLen = retPack.Value.Options.Data.Length; var retPackLen = retPack.Value.Options.Data.Length;
if (retPackLen != 4) if (retPackLen != 4)
throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"); return new(new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"));
if (Common.Number.BitsCheck( if (Common.Number.BitsCheck(
Common.Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask)) Common.Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask))
@ -431,7 +442,7 @@ class Jtag
async ValueTask<Result<bool>> IdleDelay(UInt32 milliseconds) async ValueTask<Result<bool>> IdleDelay(UInt32 milliseconds)
{ {
if (milliseconds > Math.Pow(2, 28)) throw new Exception("Timespan is over 2^28 milliseconds"); if (milliseconds > Math.Pow(2, 28)) return new(new Exception("Timespan is over 2^28 milliseconds"));
return await WriteFIFO( return await WriteFIFO(
JtagAddr.WRITE_CMD, JtagAddr.WRITE_CMD,
@ -446,8 +457,8 @@ class Jtag
JtagAddr.WRITE_DATA, JtagAddr.WRITE_DATA,
Common.Number.MultiBitsToNumber(0, 22, command, JtagCmd.LEN_JTAG_DR).Value, 0, 0); Common.Number.MultiBitsToNumber(0, 22, command, JtagCmd.LEN_JTAG_DR).Value, 0, 0);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Write JTAG_DR_IDCODE Failed"); else if (!ret.Value) return new(new Exception("Write JTAG_DR_IDCODE Failed"));
} }
{ {
var ret = await WriteFIFO( var ret = await WriteFIFO(
@ -455,8 +466,8 @@ class Jtag
Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_IR, JtagCmd.LEN_CMD_JTAG, 10, 28).Value, Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_IR, JtagCmd.LEN_CMD_JTAG, 10, 28).Value,
0x01_00_00_00, JtagState.CMD_EXEC_FINISH); 0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Write CMD_JTAG_LOAD_IR Failed"); else if (!ret.Value) return new(new Exception("Write CMD_JTAG_LOAD_IR Failed"));
} }
return await ClearWriteDataReg(); return await ClearWriteDataReg();
} }
@ -464,7 +475,7 @@ class Jtag
async ValueTask<Result<bool>> LoadDRCareInput(byte[] bytesArray) async ValueTask<Result<bool>> LoadDRCareInput(byte[] bytesArray)
{ {
var bytesLen = ((uint)(bytesArray.Length * 8)); var bytesLen = ((uint)(bytesArray.Length * 8));
if (bytesLen > Math.Pow(2, 28)) throw new Exception("Length is over 2^(28 - 3)"); if (bytesLen > Math.Pow(2, 28)) return new(new Exception("Length is over 2^(28 - 3)"));
{ {
var ret = await WriteFIFO( var ret = await WriteFIFO(
@ -472,21 +483,21 @@ class Jtag
Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_DR_CAREI, JtagCmd.LEN_CMD_JTAG, bytesLen, 28).Value, Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_DR_CAREI, JtagCmd.LEN_CMD_JTAG, bytesLen, 28).Value,
0x01_00_00_00, JtagState.CMD_EXEC_FINISH); 0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Write CMD_JTAG_LOAD_DR_CAREI Failed"); else if (!ret.Value) return new(new Exception("Write CMD_JTAG_LOAD_DR_CAREI Failed"));
} }
{ {
var ret = await WriteFIFO(JtagAddr.WRITE_DATA, bytesArray, 0x01_00_00_00, JtagState.CMD_EXEC_FINISH); var ret = await WriteFIFO(JtagAddr.WRITE_DATA, bytesArray, 0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Write Data Failed"); else if (!ret.Value) return new(new Exception("Write Data Failed"));
} }
return true; return true;
} }
async ValueTask<Result<UInt32>> LoadDRCareOutput(UInt32 bytesLen) async ValueTask<Result<UInt32>> LoadDRCareOutput(UInt32 bytesLen)
{ {
if (bytesLen > Math.Pow(2, 28)) throw new Exception("Length is over 2^(28 - 3)"); if (bytesLen > Math.Pow(2, 28)) return new(new Exception("Length is over 2^(28 - 3)"));
var ret = await WriteFIFO( var ret = await WriteFIFO(
JtagAddr.WRITE_CMD, JtagAddr.WRITE_CMD,
@ -496,7 +507,7 @@ class Jtag
if (ret.Value) if (ret.Value)
return await ReadFIFO(JtagAddr.READ_DATA); return await ReadFIFO(JtagAddr.READ_DATA);
else else
throw new Exception("LoadDRCareo Failed!"); return new(new Exception("LoadDRCareo Failed!"));
} }
public async ValueTask<Result<uint>> ReadIDCode() public async ValueTask<Result<uint>> ReadIDCode()
@ -504,28 +515,30 @@ class Jtag
// Clear Data // Clear Data
await MsgBus.UDPServer.ClearUDPData(this.address); await MsgBus.UDPServer.ClearUDPData(this.address);
logger.Trace($"Clear up udp server {this.address} receive data");
Result<bool> ret; Result<bool> ret;
ret = await ClearAllRegisters(); ret = await ClearAllRegisters();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Clear All Registers Failed"); else if (!ret.Value) return new(new Exception("Jtag Clear All Registers Failed"));
ret = await RunTest(); ret = await RunTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Run Test Failed"));
ret = await ExecRDCmd(JtagCmd.JTAG_DR_IDCODE); ret = await ExecRDCmd(JtagCmd.JTAG_DR_IDCODE);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_IDCODE Failed"); else if (!ret.Value) return new(new Exception("Jtag Execute Command JTAG_DR_IDCODE Failed"));
ret = await ClearWriteDataReg(); ret = await ClearWriteDataReg();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Clear Write Registers Failed"); else if (!ret.Value) return new(new Exception("Jtag Clear Write Registers Failed"));
var retData = await LoadDRCareOutput(4); var retData = await LoadDRCareOutput(4);
if (!retData.IsSuccessful) if (!retData.IsSuccessful)
{ {
throw new Exception("Get ID Code Failed"); return new(new Exception("Get ID Code Failed"));
} }
return retData.Value; return retData.Value;
@ -536,66 +549,66 @@ class Jtag
// Clear Data // Clear Data
await MsgBus.UDPServer.ClearUDPData(this.address); await MsgBus.UDPServer.ClearUDPData(this.address);
logger.Trace($"Clear up udp server {this.address} receive data");
Result<bool> ret; Result<bool> ret;
ret = await CloseTest(); ret = await CloseTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Close Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Close Test Failed"));
ret = await RunTest(); ret = await RunTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Run Test Failed"));
logger.Trace("Jtag initialize");
ret = await ExecRDCmd(JtagCmd.JTAG_DR_JRST); ret = await ExecRDCmd(JtagCmd.JTAG_DR_JRST);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JRST Failed"); else if (!ret.Value) return new(new Exception("Jtag Execute Command JTAG_DR_JRST Failed"));
ret = await RunTest(); ret = await RunTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Run Test Failed"));
ret = await ExecRDCmd(JtagCmd.JTAG_DR_CFGI); ret = await ExecRDCmd(JtagCmd.JTAG_DR_CFGI);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_CFGI Failed"); else if (!ret.Value) return new(new Exception("Jtag Execute Command JTAG_DR_CFGI Failed"));
logger.Trace("Jtag ready to write bitstream");
ret = await IdleDelay(75000); ret = await IdleDelay(75000);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed"); else if (!ret.Value) return new(new Exception("Jtag IDLE Delay Failed"));
ret = await LoadDRCareInput(bitstream); ret = await LoadDRCareInput(bitstream);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Load Data Failed"); else if (!ret.Value) return new(new Exception("Jtag Load Data Failed"));
logger.Trace("Jtag write bitstream");
ret = await CloseTest(); ret = await CloseTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Close Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Close Test Failed"));
ret = await RunTest(); ret = await RunTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Run Test Failed"));
ret = await ExecRDCmd(JtagCmd.JTAG_DR_JWAKEUP); ret = await ExecRDCmd(JtagCmd.JTAG_DR_JWAKEUP);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JWAKEUP Failed"); else if (!ret.Value) return new(new Exception("Jtag Execute Command JTAG_DR_JWAKEUP Failed"));
logger.Trace("Jtag reset device");
ret = await IdleDelay(1000); ret = await IdleDelay(1000);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed"); else if (!ret.Value) return new(new Exception("Jtag IDLE Delay Failed"));
ret = await CloseTest(); ret = await CloseTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Close Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Close Test Failed"));
logger.Trace("Jtag download bitstream successfully");
return true; return true;
} }

View File

@ -5,6 +5,7 @@ using System.Text;
using DotNext; using DotNext;
using DotNext.Threading; using DotNext.Threading;
using Newtonsoft.Json; using Newtonsoft.Json;
using WebProtocol;
/// <summary> UDP接受数据包格式 </summary> /// <summary> UDP接受数据包格式 </summary>
public class UDPData public class UDPData
@ -58,9 +59,6 @@ public class UDPData
} }
} }
/// <summary>
/// UDP Server
/// </summary>
/// <summary> /// <summary>
/// UDP 服务器 /// UDP 服务器
/// </summary> /// </summary>
@ -80,6 +78,15 @@ public class UDPServer
/// </summary> /// </summary>
public bool IsRunning { get { return isRunning; } } public bool IsRunning { get { return isRunning; } }
/// <summary> UDP 服务器的错误代码 </summary>
public enum ErrorCode
{
Success = 0,
GetNoneAfterTimeout,
ResponseWrong,
NotRecvDataPackage,
}
/// <summary> /// <summary>
/// Construct a udp server with fixed port /// Construct a udp server with fixed port
/// </summary> /// </summary>
@ -132,8 +139,9 @@ public class UDPServer
{ {
var elapsed = DateTime.Now - startTime; var elapsed = DateTime.Now - startTime;
isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout); isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout);
timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed; if (isTimeout) break;
timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed;
using (await udpData.AcquireWriteLockAsync(timeleft)) using (await udpData.AcquireWriteLockAsync(timeleft))
{ {
if (udpData.ContainsKey(ipAddr) && if (udpData.ContainsKey(ipAddr) &&
@ -150,11 +158,11 @@ public class UDPServer
if (data is null) if (data is null)
{ {
logger.Trace("Get nothing even after time out"); logger.Trace("Get nothing even after time out");
return Optional<UDPData>.None; return new(null);
} }
else else
{ {
return Optional.Some((UDPData)data.DeepClone()); return new(data.DeepClone());
} }
} }
@ -175,8 +183,9 @@ public class UDPServer
{ {
var elapsed = DateTime.Now - startTime; var elapsed = DateTime.Now - startTime;
isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout); isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout);
timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed; if (isTimeout) break;
timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed;
using (await udpData.AcquireReadLockAsync(timeleft)) using (await udpData.AcquireReadLockAsync(timeleft))
{ {
if (udpData.ContainsKey(ipAddr) && if (udpData.ContainsKey(ipAddr) &&
@ -193,11 +202,11 @@ public class UDPServer
if (data is null) if (data is null)
{ {
logger.Trace("Get nothing even after time out"); logger.Trace("Get nothing even after time out");
return Optional<List<UDPData>>.None; return new(null);
} }
else else
{ {
return Optional.Some((List<UDPData>)data); return new(data);
} }
} }
@ -213,15 +222,15 @@ public class UDPServer
{ {
var data = await FindDataAsync(address, timeout); var data = await FindDataAsync(address, timeout);
if (!data.HasValue) if (!data.HasValue)
throw new Exception("Get None even after time out!"); return new(new Exception("Get None even after time out!"));
var recvData = data.Value; var recvData = data.Value;
if (recvData.Address != address || (port > 0 && recvData.Port != port)) if (recvData.Address != address || (port > 0 && recvData.Port != port))
throw new Exception("Receive Data From Wrong Board!"); return new(new Exception("Receive Data From Wrong Board!"));
var retPack = WebProtocol.RecvRespPackage.FromBytes(recvData.Data); var retPack = WebProtocol.RecvRespPackage.FromBytes(recvData.Data);
if (!retPack.IsSuccessful) if (!retPack.IsSuccessful)
throw new Exception("Not RecvDataPackage!", retPack.Error); return new(new Exception("Not RecvDataPackage!", retPack.Error));
return retPack.Value; return retPack.Value;
} }
@ -233,20 +242,20 @@ public class UDPServer
/// <param name="port">UDP 端口</param> /// <param name="port">UDP 端口</param>
/// <param name="timeout">超时时间范围</param> /// <param name="timeout">超时时间范围</param>
/// <returns>接收数据包</returns> /// <returns>接收数据包</returns>
public async ValueTask<Result<WebProtocol.RecvDataPackage>> WaitForDataAsync public async ValueTask<Result<RecvDataPackage>> WaitForDataAsync
(string address, int port = -1, int timeout = 1000) (string address, int port = -1, int timeout = 1000)
{ {
var data = await FindDataAsync(address, timeout); var data = await FindDataAsync(address, timeout);
if (!data.HasValue) if (!data.HasValue)
throw new Exception("Get None even after time out!"); return new(new Exception("Get None even after time out!"));
var recvData = data.Value; var recvData = data.Value;
if (recvData.Address != address || (port >= 0 && recvData.Port != port)) if (recvData.Address != address || (port >= 0 && recvData.Port != port))
throw new Exception("Receive Data From Wrong Board!"); return new(new Exception("Receive Data From Wrong Board!"));
var retPack = WebProtocol.RecvDataPackage.FromBytes(recvData.Data); var retPack = WebProtocol.RecvDataPackage.FromBytes(recvData.Data);
if (!retPack.IsSuccessful) if (!retPack.IsSuccessful)
throw new Exception("Not RecvDataPackage!", retPack.Error); return new(new Exception("Not RecvDataPackage!", retPack.Error));
return retPack.Value; return retPack.Value;
} }

View File

@ -234,18 +234,18 @@ namespace WebProtocol
{ {
if (bytes.Length != 8) if (bytes.Length != 8)
{ {
throw new ArgumentException( return new(new ArgumentException(
"Bytes are not equal to 8 bytes.", "Bytes are not equal to 8 bytes.",
nameof(bytes) nameof(bytes)
); ));
} }
if (checkSign && bytes[0] != (byte)PackSign.SendAddr) if (checkSign && bytes[0] != (byte)PackSign.SendAddr)
{ {
throw new ArgumentException( return new(new ArgumentException(
"The sign of bytes is not SendAddr Package, but you can disable it by set checkSign false.", "The sign of bytes is not SendAddr Package, but you can disable it by set checkSign false.",
nameof(bytes) nameof(bytes)
); ));
} }
var address = Common.Number.BytesToNumber(bytes[4..]).Value; var address = Common.Number.BytesToNumber(bytes[4..]).Value;
@ -377,10 +377,10 @@ namespace WebProtocol
public static Result<RecvDataPackage> FromBytes(byte[] bytes) public static Result<RecvDataPackage> FromBytes(byte[] bytes)
{ {
if (bytes[0] != (byte)PackSign.RecvData) if (bytes[0] != (byte)PackSign.RecvData)
throw new ArgumentException( return new(new ArgumentException(
$"The sign of bytes is not RecvData Package, Sign: 0x{BitConverter.ToString([bytes[0]])}", $"The sign of bytes is not RecvData Package, Sign: 0x{BitConverter.ToString([bytes[0]])}",
nameof(bytes) nameof(bytes)
); ));
return new RecvDataPackage(bytes[1], bytes[2], bytes[4..]); return new RecvDataPackage(bytes[1], bytes[2], bytes[4..]);
} }
@ -480,10 +480,10 @@ namespace WebProtocol
public static Result<RecvRespPackage> FromBytes(byte[] bytes) public static Result<RecvRespPackage> FromBytes(byte[] bytes)
{ {
if (bytes[0] != (byte)PackSign.RecvResp) if (bytes[0] != (byte)PackSign.RecvResp)
throw new ArgumentException( return new(new ArgumentException(
$"The sign of bytes is not RecvResp Package, Sign: 0x{BitConverter.ToString([bytes[0]])}", $"The sign of bytes is not RecvResp Package, Sign: 0x{BitConverter.ToString([bytes[0]])}",
nameof(bytes) nameof(bytes)
); ));
return new RecvRespPackage(bytes[1], bytes[2]); return new RecvRespPackage(bytes[1], bytes[2]);
} }