try to fix server bug: couldn't download bitstream
This commit is contained in:
parent
442e40d87a
commit
98a5dbe7f3
|
@ -1,2 +1,3 @@
|
|||
bin
|
||||
obj
|
||||
bitstream
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
obj
|
||||
bin
|
||||
bitstream
|
||||
|
||||
|
|
|
@ -65,7 +65,11 @@ try
|
|||
// Application Settings
|
||||
var app = builder.Build();
|
||||
// Configure the HTTP request pipeline.
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
// app.UseExceptionHandler(new ExceptionHandlerOptions()
|
||||
// {
|
||||
// AllowStatusCode404Response = true,
|
||||
// ExceptionHandlingPath = "/error"
|
||||
// });
|
||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
app.UseHsts();
|
||||
app.UseHttpsRedirection();
|
||||
|
|
|
@ -139,6 +139,8 @@ public class UDPController : ControllerBase
|
|||
[Route("api/[controller]")]
|
||||
public class JtagController : ControllerBase
|
||||
{
|
||||
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// 页面
|
||||
/// </summary>
|
||||
|
@ -184,48 +186,92 @@ public class JtagController : ControllerBase
|
|||
else { return TypedResults.InternalServerError(ret.Error); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传比特流文件
|
||||
/// </summary>
|
||||
/// <param name="address"> 设备地址 </param>
|
||||
/// <param name="file">比特流文件</param>
|
||||
[HttpPost("UploadBitstream")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public async ValueTask<IResult> UploadBitstream(string address, IFormFile file)
|
||||
{
|
||||
if (file == null || file.Length == 0)
|
||||
return TypedResults.BadRequest("未选择文件");
|
||||
|
||||
// 生成安全的文件名(避免路径遍历攻击)
|
||||
var fileName = Path.GetRandomFileName();
|
||||
var uploadsFolder = Path.Combine(Environment.CurrentDirectory, $"bitstream/{address}");
|
||||
|
||||
// 如果存在文件,则删除原文件再上传
|
||||
if (Directory.Exists(uploadsFolder))
|
||||
{
|
||||
Directory.Delete(uploadsFolder, true);
|
||||
}
|
||||
Directory.CreateDirectory(uploadsFolder);
|
||||
|
||||
var filePath = Path.Combine(uploadsFolder, fileName);
|
||||
|
||||
using (var stream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
await file.CopyToAsync(stream);
|
||||
}
|
||||
|
||||
return TypedResults.Ok("文件上传成功");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过Jtag下载比特流文件
|
||||
/// </summary>
|
||||
/// <param name="address"> 设备地址 </param>
|
||||
/// <param name="port"> 设备端口 </param>
|
||||
/// <param name="file">比特流文件(最大32MB)</param>
|
||||
[HttpGet("DownloadBitstream")]
|
||||
[HttpPost("DownloadBitstream")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
public async ValueTask<IResult> DownloadBitstream(string address, int port, IFormFile file)
|
||||
public async ValueTask<IResult> DownloadBitstream(string address, int port)
|
||||
{
|
||||
// 检查文件
|
||||
if (file is null || file.Length <= 0)
|
||||
throw new ArgumentException("Empty file", nameof(file));
|
||||
var fileDir = Path.Combine(Environment.CurrentDirectory, $"bitstream/{address}");
|
||||
if (!Directory.Exists(fileDir))
|
||||
return TypedResults.BadRequest("Empty bitstream, Please upload it first");
|
||||
|
||||
// 定义缓冲区大小(例如:1MB)
|
||||
const int bufferSize = 1024 * 1024; // 1MB
|
||||
byte[] buffer = new byte[bufferSize];
|
||||
long totalBytesRead = 0;
|
||||
|
||||
// 使用异步流读取文件
|
||||
using (var memoryStream = new MemoryStream())
|
||||
try
|
||||
{
|
||||
using (var stream = file.OpenReadStream())
|
||||
// 读取文件
|
||||
var filePath = Directory.GetFiles(fileDir)[0];
|
||||
var fileStream = System.IO.File.Open(filePath, System.IO.FileMode.Open);
|
||||
if (fileStream is null || fileStream.Length <= 0)
|
||||
return TypedResults.BadRequest("Wrong bitstream, Please upload it again");
|
||||
|
||||
// 定义缓冲区大小: 32KB
|
||||
byte[] buffer = new byte[32 * 1024];
|
||||
long totalBytesRead = 0;
|
||||
|
||||
// 使用异步流读取文件
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
int bytesRead;
|
||||
while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
||||
while ((bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
||||
{
|
||||
await memoryStream.WriteAsync(buffer, 0, bytesRead);
|
||||
totalBytesRead += bytesRead;
|
||||
}
|
||||
|
||||
// 将所有数据转换为字节数组(注意:如果文件非常大,可能不适合完全加载到内存)
|
||||
var fileBytes = memoryStream.ToArray();
|
||||
|
||||
// 下载比特流
|
||||
var jtagCtrl = new JtagClient.Jtag(address, port);
|
||||
var ret = await jtagCtrl.DownloadBitstream(fileBytes);
|
||||
|
||||
if (ret.IsSuccessful) { return TypedResults.Ok(ret.Value); }
|
||||
else { return TypedResults.InternalServerError(ret.Error); }
|
||||
}
|
||||
|
||||
// 将所有数据转换为字节数组(注意:如果文件非常大,可能不适合完全加载到内存)
|
||||
byte[] fileBytes = memoryStream.ToArray();
|
||||
|
||||
// 下载比特流
|
||||
var jtagCtrl = new JtagClient.Jtag(address, port);
|
||||
var ret = await jtagCtrl.DownloadBitstream(fileBytes);
|
||||
|
||||
if (ret.IsSuccessful) { return TypedResults.Ok(ret.Value); }
|
||||
else { return TypedResults.InternalServerError(ret.Error); }
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
return TypedResults.InternalServerError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -287,11 +287,10 @@ class Jtag
|
|||
if (!MsgBus.IsRunning)
|
||||
throw new Exception("Message bus not working!");
|
||||
// Wait for Write Ack
|
||||
{
|
||||
var udpResp = await MsgBus.UDPServer.WaitForAckAsync(address, port);
|
||||
if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful)
|
||||
throw new Exception("Send address package failed");
|
||||
}
|
||||
var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port);
|
||||
if (!udpWriteAck.IsSuccessful) throw udpWriteAck.Error;
|
||||
else if (!udpWriteAck.Value.IsSuccessful)
|
||||
throw new Exception("Send address package failed");
|
||||
|
||||
// Read Jtag State Register
|
||||
opts.IsWrite = false;
|
||||
|
@ -299,13 +298,12 @@ class Jtag
|
|||
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
|
||||
if (!ret) throw new Exception("Send 2rd Address Package Failed!");
|
||||
// Wait for Read Data
|
||||
{
|
||||
var udpResp = await MsgBus.UDPServer.WaitForDataAsync(address, port);
|
||||
if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful)
|
||||
throw new Exception("Send address package failed");
|
||||
var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port);
|
||||
if (!udpDataResp.IsSuccessful) throw udpDataResp.Error;
|
||||
else if (!udpDataResp.Value.IsSuccessful)
|
||||
throw new Exception("Send address package failed");
|
||||
|
||||
return udpResp.Value;
|
||||
}
|
||||
return udpDataResp.Value;
|
||||
}
|
||||
|
||||
public async ValueTask<Result<RecvDataPackage>> WriteFIFO(UInt32 devAddr, byte[] dataArray)
|
||||
|
@ -342,11 +340,10 @@ class Jtag
|
|||
if (!ret) throw new Exception("Send data package failed!");
|
||||
|
||||
// Wait for Write Ack
|
||||
{
|
||||
var udpResp = await MsgBus.UDPServer.WaitForAckAsync(address, port);
|
||||
if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful)
|
||||
throw new Exception("Send address package failed");
|
||||
}
|
||||
var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port);
|
||||
if (!udpWriteAck.IsSuccessful) throw udpWriteAck.Error;
|
||||
else if (!udpWriteAck.Value.IsSuccessful)
|
||||
throw new Exception("Send address package failed");
|
||||
}
|
||||
|
||||
// Read Jtag State Register
|
||||
|
@ -356,13 +353,12 @@ class Jtag
|
|||
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
|
||||
if (!ret) throw new Exception("Send 2rd Address Package Failed!");
|
||||
// Wait for Read Data
|
||||
{
|
||||
var udpResp = await MsgBus.UDPServer.WaitForDataAsync(address, port);
|
||||
if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful)
|
||||
throw new Exception("Send address package failed");
|
||||
var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port);
|
||||
if (!udpDataResp.IsSuccessful) throw udpDataResp.Error;
|
||||
else if (!udpDataResp.Value.IsSuccessful)
|
||||
throw new Exception("Send address package failed");
|
||||
|
||||
return udpResp.Value;
|
||||
}
|
||||
return udpDataResp.Value;
|
||||
}
|
||||
|
||||
public async ValueTask<Result<bool>> WriteFIFO
|
||||
|
@ -370,6 +366,7 @@ class Jtag
|
|||
{
|
||||
var ret = false;
|
||||
var retPack = await WriteFIFO(devAddr, data);
|
||||
if (!retPack.IsSuccessful) throw retPack.Error;
|
||||
|
||||
if (retPack.Value.Options.Data is null)
|
||||
throw new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}");
|
||||
|
@ -507,27 +504,31 @@ class Jtag
|
|||
// Clear Data
|
||||
await MsgBus.UDPServer.ClearUDPData(this.address);
|
||||
|
||||
Result<bool> ret;
|
||||
|
||||
ret = await ClearAllRegisters();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Clear All Registers Failed");
|
||||
|
||||
ret = await RunTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
|
||||
|
||||
ret = await ExecRDCmd(JtagCmd.JTAG_DR_IDCODE);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_IDCODE Failed");
|
||||
|
||||
ret = await ClearWriteDataReg();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Clear Write Registers Failed");
|
||||
|
||||
var retData = await LoadDRCareOutput(4);
|
||||
if (!retData.IsSuccessful)
|
||||
{
|
||||
var ret = await ClearAllRegisters();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Clear All Registers Failed");
|
||||
throw new Exception("Get ID Code Failed");
|
||||
}
|
||||
{
|
||||
var ret = await RunTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
|
||||
}
|
||||
{
|
||||
var ret = await ExecRDCmd(JtagCmd.JTAG_DR_IDCODE);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_IDCODE Failed");
|
||||
}
|
||||
{
|
||||
var ret = await ClearWriteDataReg();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Clear Write Registers Failed");
|
||||
}
|
||||
return (await LoadDRCareOutput(1)).Value;
|
||||
|
||||
return retData.Value;
|
||||
}
|
||||
|
||||
public async ValueTask<Result<bool>> DownloadBitstream(byte[] bitstream)
|
||||
|
@ -535,66 +536,66 @@ class Jtag
|
|||
// Clear Data
|
||||
await MsgBus.UDPServer.ClearUDPData(this.address);
|
||||
|
||||
{
|
||||
var ret = await CloseTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Close Test Failed");
|
||||
}
|
||||
{
|
||||
var ret = await RunTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
|
||||
}
|
||||
{
|
||||
var ret = await ExecRDCmd(JtagCmd.JTAG_DR_JRST);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JRST Failed");
|
||||
}
|
||||
{
|
||||
var ret = await RunTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
|
||||
}
|
||||
{
|
||||
var ret = await ExecRDCmd(JtagCmd.JTAG_DR_CFGI);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_CFGI Failed");
|
||||
}
|
||||
{
|
||||
var ret = await IdleDelay(75000);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed");
|
||||
}
|
||||
{
|
||||
var ret = await LoadDRCareInput(bitstream);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Load Data Failed");
|
||||
}
|
||||
{
|
||||
var ret = await CloseTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Close Test Failed");
|
||||
}
|
||||
{
|
||||
var ret = await RunTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
|
||||
}
|
||||
{
|
||||
var ret = await ExecRDCmd(JtagCmd.JTAG_DR_JWAKEUP);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JWAKEUP Failed");
|
||||
}
|
||||
{
|
||||
var ret = await IdleDelay(1000);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed");
|
||||
}
|
||||
{
|
||||
var ret = await CloseTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Close Test Failed");
|
||||
}
|
||||
Result<bool> ret;
|
||||
|
||||
ret = await CloseTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Close Test Failed");
|
||||
|
||||
|
||||
ret = await RunTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
|
||||
|
||||
|
||||
ret = await ExecRDCmd(JtagCmd.JTAG_DR_JRST);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JRST Failed");
|
||||
|
||||
|
||||
ret = await RunTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
|
||||
|
||||
|
||||
ret = await ExecRDCmd(JtagCmd.JTAG_DR_CFGI);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_CFGI Failed");
|
||||
|
||||
|
||||
ret = await IdleDelay(75000);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed");
|
||||
|
||||
|
||||
ret = await LoadDRCareInput(bitstream);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Load Data Failed");
|
||||
|
||||
|
||||
ret = await CloseTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Close Test Failed");
|
||||
|
||||
|
||||
ret = await RunTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
|
||||
|
||||
|
||||
ret = await ExecRDCmd(JtagCmd.JTAG_DR_JWAKEUP);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JWAKEUP Failed");
|
||||
|
||||
|
||||
ret = await IdleDelay(1000);
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed");
|
||||
|
||||
|
||||
ret = await CloseTest();
|
||||
if (!ret.IsSuccessful) throw ret.Error;
|
||||
else if (!ret.Value) throw new Exception("Jtag Close Test Failed");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -136,11 +136,11 @@ public class UDPServer
|
|||
|
||||
using (await udpData.AcquireWriteLockAsync(timeleft))
|
||||
{
|
||||
if (udpData.TryGetValue(ipAddr, out var dataQueue) && dataQueue != null && dataQueue.Count > 0)
|
||||
if (udpData.ContainsKey(ipAddr) &&
|
||||
udpData.TryGetValue(ipAddr, out var dataQueue) &&
|
||||
dataQueue.Count > 0)
|
||||
{
|
||||
data = dataQueue.Dequeue();
|
||||
// data = dataList[0].DeepClone();
|
||||
// dataList.RemoveAt(0);
|
||||
logger.Debug($"Find UDP Data: {data.ToString()}");
|
||||
break;
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ public class UDPServer
|
|||
if (data is null)
|
||||
{
|
||||
logger.Trace("Get nothing even after time out");
|
||||
return Optional.None<UDPData>();
|
||||
return Optional<UDPData>.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -179,7 +179,9 @@ public class UDPServer
|
|||
|
||||
using (await udpData.AcquireReadLockAsync(timeleft))
|
||||
{
|
||||
if (udpData.TryGetValue(ipAddr, out var dataQueue) && dataQueue != null && dataQueue.Count > 0)
|
||||
if (udpData.ContainsKey(ipAddr) &&
|
||||
udpData.TryGetValue(ipAddr, out var dataQueue) &&
|
||||
dataQueue.Count > 0)
|
||||
{
|
||||
data = dataQueue.ToList();
|
||||
logger.Debug($"Find UDP Data Array: {JsonConvert.SerializeObject(data)}");
|
||||
|
@ -191,7 +193,7 @@ public class UDPServer
|
|||
if (data is null)
|
||||
{
|
||||
logger.Trace("Get nothing even after time out");
|
||||
return Optional.None<List<UDPData>>();
|
||||
return Optional<List<UDPData>>.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -214,7 +216,7 @@ public class UDPServer
|
|||
throw new Exception("Get None even after time out!");
|
||||
|
||||
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!");
|
||||
|
||||
var retPack = WebProtocol.RecvRespPackage.FromBytes(recvData.Data);
|
||||
|
@ -305,19 +307,13 @@ public class UDPServer
|
|||
using (udpData.AcquireWriteLock())
|
||||
{
|
||||
// Record UDP Receive Data
|
||||
// if (udpData.ContainsKey(remoteAddress))
|
||||
if (udpData.TryGetValue(remoteAddress, out var dataQueue))
|
||||
if (udpData.ContainsKey(remoteAddress) && udpData.TryGetValue(remoteAddress, out var dataQueue))
|
||||
{
|
||||
// var listData = udpData[remoteAddress];
|
||||
// listData.Add(data);
|
||||
dataQueue.Enqueue(data);
|
||||
logger.Trace("Receive data from old client");
|
||||
}
|
||||
else
|
||||
{
|
||||
// var list = new List<UDPData>();
|
||||
// list.Add(data);
|
||||
// udpData.Add(remoteAddress, list);
|
||||
var queue = new Queue<UDPData>();
|
||||
queue.Enqueue(data);
|
||||
udpData.Add(remoteAddress, queue);
|
||||
|
@ -401,7 +397,9 @@ public class UDPServer
|
|||
{
|
||||
using (await udpData.AcquireWriteLockAsync())
|
||||
{
|
||||
if (udpData.TryGetValue(ipAddr, out var dataQueue) && dataQueue.Count > 0)
|
||||
if (udpData.ContainsKey(ipAddr) &&
|
||||
udpData.TryGetValue(ipAddr, out var dataQueue) &&
|
||||
dataQueue.Count > 0)
|
||||
{
|
||||
dataQueue.Clear();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue