try to fix server bug: couldn't download bitstream

This commit is contained in:
SikongJueluo 2025-04-22 17:24:46 +08:00
parent 442e40d87a
commit 98a5dbe7f3
No known key found for this signature in database
6 changed files with 192 additions and 141 deletions

View File

@ -1,2 +1,3 @@
bin
obj
bitstream

1
server/.gitignore vendored
View File

@ -1,3 +1,4 @@
obj
bin
bitstream

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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();
}