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 bin
obj obj
bitstream

1
server/.gitignore vendored
View File

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

View File

@ -65,7 +65,11 @@ try
// Application Settings // Application Settings
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // 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. // 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.UseHsts();
app.UseHttpsRedirection(); app.UseHttpsRedirection();

View File

@ -139,6 +139,8 @@ public class UDPController : ControllerBase
[Route("api/[controller]")] [Route("api/[controller]")]
public class JtagController : ControllerBase public class JtagController : ControllerBase
{ {
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
/// <summary> /// <summary>
/// 页面 /// 页面
/// </summary> /// </summary>
@ -184,41 +186,80 @@ public class JtagController : ControllerBase
else { return TypedResults.InternalServerError(ret.Error); } 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> /// <summary>
/// 通过Jtag下载比特流文件 /// 通过Jtag下载比特流文件
/// </summary> /// </summary>
/// <param name="address"> 设备地址 </param> /// <param name="address"> 设备地址 </param>
/// <param name="port"> 设备端口 </param> /// <param name="port"> 设备端口 </param>
/// <param name="file">比特流文件最大32MB</param> [HttpPost("DownloadBitstream")]
[HttpGet("DownloadBitstream")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)] [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) var fileDir = Path.Combine(Environment.CurrentDirectory, $"bitstream/{address}");
throw new ArgumentException("Empty file", nameof(file)); if (!Directory.Exists(fileDir))
return TypedResults.BadRequest("Empty bitstream, Please upload it first");
// 定义缓冲区大小例如1MB try
const int bufferSize = 1024 * 1024; // 1MB {
byte[] buffer = new byte[bufferSize]; // 读取文件
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; long totalBytesRead = 0;
// 使用异步流读取文件 // 使用异步流读取文件
using (var memoryStream = new MemoryStream()) using (var memoryStream = new MemoryStream())
{
using (var stream = file.OpenReadStream())
{ {
int bytesRead; 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); await memoryStream.WriteAsync(buffer, 0, bytesRead);
totalBytesRead += bytesRead; totalBytesRead += bytesRead;
} }
}
// 将所有数据转换为字节数组(注意:如果文件非常大,可能不适合完全加载到内存) // 将所有数据转换为字节数组(注意:如果文件非常大,可能不适合完全加载到内存)
byte[] fileBytes = memoryStream.ToArray(); var fileBytes = memoryStream.ToArray();
// 下载比特流 // 下载比特流
var jtagCtrl = new JtagClient.Jtag(address, port); var jtagCtrl = new JtagClient.Jtag(address, port);
@ -228,4 +269,9 @@ public class JtagController : ControllerBase
else { return TypedResults.InternalServerError(ret.Error); } else { return TypedResults.InternalServerError(ret.Error); }
} }
} }
catch (Exception error)
{
return TypedResults.InternalServerError(error);
}
}
} }

View File

@ -287,11 +287,10 @@ class Jtag
if (!MsgBus.IsRunning) if (!MsgBus.IsRunning)
throw new Exception("Message bus not working!"); throw new Exception("Message bus not working!");
// Wait for Write Ack // Wait for Write Ack
{ var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port);
var udpResp = await MsgBus.UDPServer.WaitForAckAsync(address, port); if (!udpWriteAck.IsSuccessful) throw udpWriteAck.Error;
if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful) else if (!udpWriteAck.Value.IsSuccessful)
throw new Exception("Send address package failed"); throw new Exception("Send address package failed");
}
// Read Jtag State Register // Read Jtag State Register
opts.IsWrite = false; opts.IsWrite = false;
@ -299,13 +298,12 @@ class Jtag
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) throw new Exception("Send 2rd Address Package Failed!");
// Wait for Read Data // Wait for Read Data
{ var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port);
var udpResp = await MsgBus.UDPServer.WaitForDataAsync(address, port); if (!udpDataResp.IsSuccessful) throw udpDataResp.Error;
if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful) else if (!udpDataResp.Value.IsSuccessful)
throw new Exception("Send address package failed"); throw new Exception("Send address package failed");
return udpResp.Value; return udpDataResp.Value;
}
} }
public async ValueTask<Result<RecvDataPackage>> WriteFIFO(UInt32 devAddr, byte[] dataArray) public async ValueTask<Result<RecvDataPackage>> WriteFIFO(UInt32 devAddr, byte[] dataArray)
@ -342,12 +340,11 @@ class Jtag
if (!ret) throw new Exception("Send data package failed!"); if (!ret) throw new Exception("Send data package failed!");
// Wait for Write Ack // Wait for Write Ack
{ var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port);
var udpResp = await MsgBus.UDPServer.WaitForAckAsync(address, port); if (!udpWriteAck.IsSuccessful) throw udpWriteAck.Error;
if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful) else if (!udpWriteAck.Value.IsSuccessful)
throw new Exception("Send address package failed"); throw new Exception("Send address package failed");
} }
}
// Read Jtag State Register // Read Jtag State Register
opts.IsWrite = false; opts.IsWrite = false;
@ -356,13 +353,12 @@ class Jtag
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) throw new Exception("Send 2rd Address Package Failed!");
// Wait for Read Data // Wait for Read Data
{ var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port);
var udpResp = await MsgBus.UDPServer.WaitForDataAsync(address, port); if (!udpDataResp.IsSuccessful) throw udpDataResp.Error;
if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful) else if (!udpDataResp.Value.IsSuccessful)
throw new Exception("Send address package failed"); throw new Exception("Send address package failed");
return udpResp.Value; return udpDataResp.Value;
}
} }
public async ValueTask<Result<bool>> WriteFIFO public async ValueTask<Result<bool>> WriteFIFO
@ -370,6 +366,7 @@ class Jtag
{ {
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.Value.Options.Data is null) if (retPack.Value.Options.Data is null)
throw new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}"); throw new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}");
@ -507,27 +504,31 @@ class Jtag
// Clear Data // Clear Data
await MsgBus.UDPServer.ClearUDPData(this.address); await MsgBus.UDPServer.ClearUDPData(this.address);
{ Result<bool> ret;
var ret = await ClearAllRegisters();
ret = await ClearAllRegisters();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Clear All Registers Failed"); else if (!ret.Value) throw new Exception("Jtag Clear All Registers Failed");
}
{ ret = await RunTest();
var ret = await RunTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
}
{ ret = await ExecRDCmd(JtagCmd.JTAG_DR_IDCODE);
var ret = await ExecRDCmd(JtagCmd.JTAG_DR_IDCODE);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_IDCODE Failed"); else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_IDCODE Failed");
}
{ ret = await ClearWriteDataReg();
var ret = await ClearWriteDataReg();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Clear Write Registers Failed"); else if (!ret.Value) throw new Exception("Jtag Clear Write Registers Failed");
var retData = await LoadDRCareOutput(4);
if (!retData.IsSuccessful)
{
throw new Exception("Get ID Code Failed");
} }
return (await LoadDRCareOutput(1)).Value;
return retData.Value;
} }
public async ValueTask<Result<bool>> DownloadBitstream(byte[] bitstream) public async ValueTask<Result<bool>> DownloadBitstream(byte[] bitstream)
@ -535,66 +536,66 @@ class Jtag
// Clear Data // Clear Data
await MsgBus.UDPServer.ClearUDPData(this.address); await MsgBus.UDPServer.ClearUDPData(this.address);
{ Result<bool> ret;
var ret = await CloseTest();
ret = await CloseTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Close Test Failed"); else if (!ret.Value) throw new Exception("Jtag Close Test Failed");
}
{
var ret = await RunTest(); ret = await RunTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
}
{
var ret = await ExecRDCmd(JtagCmd.JTAG_DR_JRST); ret = await ExecRDCmd(JtagCmd.JTAG_DR_JRST);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JRST Failed"); else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JRST Failed");
}
{
var ret = await RunTest(); ret = await RunTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
}
{
var ret = await ExecRDCmd(JtagCmd.JTAG_DR_CFGI); ret = await ExecRDCmd(JtagCmd.JTAG_DR_CFGI);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_CFGI Failed"); else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_CFGI Failed");
}
{
var ret = await IdleDelay(75000); ret = await IdleDelay(75000);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed"); else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed");
}
{
var ret = await LoadDRCareInput(bitstream); ret = await LoadDRCareInput(bitstream);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Load Data Failed"); else if (!ret.Value) throw new Exception("Jtag Load Data Failed");
}
{
var ret = await CloseTest(); ret = await CloseTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Close Test Failed"); else if (!ret.Value) throw new Exception("Jtag Close Test Failed");
}
{
var ret = await RunTest(); ret = await RunTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
}
{
var ret = await ExecRDCmd(JtagCmd.JTAG_DR_JWAKEUP); ret = await ExecRDCmd(JtagCmd.JTAG_DR_JWAKEUP);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JWAKEUP Failed"); else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JWAKEUP Failed");
}
{
var ret = await IdleDelay(1000); ret = await IdleDelay(1000);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed"); else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed");
}
{
var ret = await CloseTest(); ret = await CloseTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) throw ret.Error;
else if (!ret.Value) throw new Exception("Jtag Close Test Failed"); else if (!ret.Value) throw new Exception("Jtag Close Test Failed");
}
return true; return true;
} }

View File

@ -136,11 +136,11 @@ public class UDPServer
using (await udpData.AcquireWriteLockAsync(timeleft)) 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 = dataQueue.Dequeue();
// data = dataList[0].DeepClone();
// dataList.RemoveAt(0);
logger.Debug($"Find UDP Data: {data.ToString()}"); logger.Debug($"Find UDP Data: {data.ToString()}");
break; break;
} }
@ -150,7 +150,7 @@ 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.None<UDPData>(); return Optional<UDPData>.None;
} }
else else
{ {
@ -179,7 +179,9 @@ public class UDPServer
using (await udpData.AcquireReadLockAsync(timeleft)) 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(); data = dataQueue.ToList();
logger.Debug($"Find UDP Data Array: {JsonConvert.SerializeObject(data)}"); logger.Debug($"Find UDP Data Array: {JsonConvert.SerializeObject(data)}");
@ -191,7 +193,7 @@ 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.None<List<UDPData>>(); return Optional<List<UDPData>>.None;
} }
else else
{ {
@ -214,7 +216,7 @@ public class UDPServer
throw new Exception("Get None even after time out!"); throw 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!"); throw new Exception("Receive Data From Wrong Board!");
var retPack = WebProtocol.RecvRespPackage.FromBytes(recvData.Data); var retPack = WebProtocol.RecvRespPackage.FromBytes(recvData.Data);
@ -305,19 +307,13 @@ public class UDPServer
using (udpData.AcquireWriteLock()) using (udpData.AcquireWriteLock())
{ {
// Record UDP Receive Data // Record UDP Receive Data
// if (udpData.ContainsKey(remoteAddress)) if (udpData.ContainsKey(remoteAddress) && udpData.TryGetValue(remoteAddress, out var dataQueue))
if (udpData.TryGetValue(remoteAddress, out var dataQueue))
{ {
// var listData = udpData[remoteAddress];
// listData.Add(data);
dataQueue.Enqueue(data); dataQueue.Enqueue(data);
logger.Trace("Receive data from old client"); logger.Trace("Receive data from old client");
} }
else else
{ {
// var list = new List<UDPData>();
// list.Add(data);
// udpData.Add(remoteAddress, list);
var queue = new Queue<UDPData>(); var queue = new Queue<UDPData>();
queue.Enqueue(data); queue.Enqueue(data);
udpData.Add(remoteAddress, queue); udpData.Add(remoteAddress, queue);
@ -401,7 +397,9 @@ public class UDPServer
{ {
using (await udpData.AcquireWriteLockAsync()) 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(); dataQueue.Clear();
} }