add some doc and jtag controller

This commit is contained in:
SikongJueluo 2025-04-02 21:51:20 +08:00
parent 0da5b85173
commit 2af0986d67
No known key found for this signature in database
7 changed files with 232 additions and 43 deletions

View File

@ -1,16 +1,26 @@
using System.Net;
using System.Reflection;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
builder.Services.AddSwaggerGen(options =>
{
c.SwaggerDoc("v1", new OpenApiInfo
options.SwaggerDoc("v1", new OpenApiInfo
{
Title = "FPGA Web Lab API",
Description = "Use FPGA in the cloud",
Version = "v1"
});
// Generate Doc and Exam
var executingAssembly = Assembly.GetExecutingAssembly();
var xmlFilename = $"{executingAssembly.GetName().Name}.xml";
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
var referencedProjectsXmlDocPaths =
executingAssembly.GetReferencedAssemblies()
.Where(assembly => assembly.Name != null && assembly.Name.StartsWith("server", StringComparison.InvariantCultureIgnoreCase))
.Select(assembly => Path.Combine(AppContext.BaseDirectory, $"{assembly.Name}.xml"))
.Where(path => File.Exists(path));
foreach (var xmlDocPath in referencedProjectsXmlDocPaths) options.IncludeXmlComments(xmlDocPath);
});
var app = builder.Build();

View File

@ -4,13 +4,14 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DotNext" Version="5.19.1" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.23" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,69 @@
using System.Net;
using Common;
using DotNext;
using WebProtocol;
namespace JtagController;
/// <summary>
/// Global Constant Jtag Address
/// </summary>
public static class JtagAddr
{
/// <summary>
/// Jtag State Reg
/// </summary>
public const UInt32 STATE = 0x10_00_00_00;
/// <summary>
/// Jtag Read Reg
/// </summary>
public const UInt32 READ_DATA = 0x10_00_00_01;
/// <summary>
/// Jtag Write Reg
/// </summary>
public const UInt32 WRITE_DATA = 0x10_00_00_02;
/// <summary>
/// Jtag Write Command
/// </summary>
public const UInt32 WRITE_CMD = 0x10_00_00_03;
}
class Jtag
{
readonly int port;
readonly string address;
private IPEndPoint ep;
public Jtag(string address, int port)
{
this.address = address;
this.port = port;
this.ep = new IPEndPoint(IPAddress.Parse(address), port);
}
public async ValueTask<Result<bool>> ClearRegisters()
{
var ret = true;
var opts = new SendAddrPackOptions();
opts.burstType = BurstType.FixedBurst;
opts.burstLength = 4;
opts.commandID = 0;
opts.address = JtagAddr.STATE;
// Write Jtag State Register
opts.isWrite = true;
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
if (!ret) throw new Exception("Send 1st Address Package Failed!");
ret = await UDPClientPool.SendDataPackAsync(ep,
new SendDataPackage(NumberProcessor.NumberToBytes(0xFF_FF_FF_FF, 4).Value));
if (!ret) throw new Exception("Send Data Package Failed!");
// Read Jtag State Register
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
if (!ret) throw new Exception("Send 2rd Address Package Failed!");
return ret;
}
}

View File

@ -1,41 +1,68 @@
using System.Net;
using Common;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Router
{
/// <summary>
/// Web API
/// </summary>
class API
{
public static void SendString(string address, int port, string text)
/// <summary>
/// Send some String
/// </summary>
/// <param name="address">IP V4/V6 address</param>
/// <param name="port">Device UDP port</param>
/// <param name="text">Text for send</param>
/// <returns>Json: true or false</returns>
public static async ValueTask<IResult> SendString(string address, int port, string text)
{
var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
UDPClientPool.AsyncSendString(endPoint, [text]);
var ret = await UDPClientPool.SendStringAsync(endPoint, [text]);
if (ret) { return Results.Json(true); }
else { return Results.Json(false); }
}
public static void SendAddrPackage(
[HttpPost]
public static async ValueTask<IResult> SendAddrPackage(
string address,
int port,
WebProtocol.BurstType burstType,
byte commandID,
bool isWrite,
byte burstLength,
UInt32 devAddress)
// WebProtocol.BurstType burstType,
// byte commandID,
// bool isWrite,
// byte burstLength,
// UInt32 devAddress)
WebProtocol.SendAddrPackOptions opts)
{
WebProtocol.SendAddrPackOptions opts;
opts.burstType = burstType;
opts.commandID = commandID;
opts.isWrite = isWrite;
opts.burstLength = burstLength;
opts.address = devAddress;
// WebProtocol.SendAddrPackOptions opts;
// opts.burstType = burstType;
// opts.commandID = commandID;
// opts.isWrite = isWrite;
// opts.burstLength = burstLength;
// opts.address = devAddress;
var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
UDPClientPool.SendAddrPack(endPoint, new WebProtocol.SendAddrPackage(opts));
var ret = await UDPClientPool.SendAddrPackAsync(endPoint, new WebProtocol.SendAddrPackage(opts));
if (ret) { return Results.Json(true); }
else { return Results.Json(false); }
}
public static void SendDataPackage(string address, int port, string data)
public static async ValueTask<IResult> SendDataPackage(string address, int port, string data)
{
var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
UDPClientPool.SendDataPack(endPoint,
var ret = await UDPClientPool.SendDataPackAsync(endPoint,
new WebProtocol.SendDataPackage(NumberProcessor.StringToBytes(data).Value));
if (ret) { return Results.Json(true); }
else { return Results.Json(false); }
}
public static async ValueTask<IResult> GetDeviceIDCode(string address, int port)
{
}
}
}

View File

@ -6,61 +6,73 @@ class UDPClientPool
{
private static IPAddress localhost = IPAddress.Parse("127.0.0.1");
public static void SendString(IPEndPoint endPoint, string[] stringArray)
public static bool SendString(IPEndPoint endPoint, string[] stringArray)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
byte[] sendbuf = Encoding.ASCII.GetBytes(stringArray[0]);
socket.SendTo(sendbuf, endPoint);
var sendLen = socket.SendTo(sendbuf, endPoint);
if (sendLen == stringArray[0].Length) { return true; }
else { return false; }
}
public async static void AsyncSendString(IPEndPoint endPoint, string[] stringArray)
public async static ValueTask<bool> SendStringAsync(IPEndPoint endPoint, string[] stringArray)
{
await Task.Run(() => { SendString(endPoint, stringArray); });
return await Task.Run(() => { return SendString(endPoint, stringArray); });
}
public static void SendBytes(IPEndPoint endPoint, byte[] buf)
public static bool SendBytes(IPEndPoint endPoint, byte[] buf)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.SendTo(buf, endPoint);
var sendLen = socket.SendTo(buf, endPoint);
if (sendLen == buf.Length) { return true; }
else { return false; }
}
public async static void AsyncSendBytes(IPEndPoint endPoint, byte[] buf)
public async static ValueTask<bool> SendBytesAsync(IPEndPoint endPoint, byte[] buf)
{
await Task.Run(() => { SendBytes(endPoint, buf); });
return await Task.Run(() => { return SendBytes(endPoint, buf); });
}
public static void SendAddrPack(IPEndPoint endPoint, WebProtocol.SendAddrPackage pkg)
public static bool SendAddrPack(IPEndPoint endPoint, WebProtocol.SendAddrPackage pkg)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.SendTo(pkg.ToBytes(), endPoint);
var sendBytes = pkg.ToBytes();
var sendLen = socket.SendTo(sendBytes, endPoint);
if (sendLen == sendBytes.Length) { return true; }
else { return false; }
}
public async static void AsyncSendAddrPack(IPEndPoint endPoint, WebProtocol.SendAddrPackage pkg)
public async static ValueTask<bool> SendAddrPackAsync(IPEndPoint endPoint, WebProtocol.SendAddrPackage pkg)
{
await Task.Run(() => { SendAddrPack(endPoint, pkg); });
return await Task.Run(() => { return SendAddrPack(endPoint, pkg); });
}
public static void SendDataPack(IPEndPoint endPoint, WebProtocol.SendDataPackage pkg)
public static bool SendDataPack(IPEndPoint endPoint, WebProtocol.SendDataPackage pkg)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.SendTo(pkg.ToBytes(), endPoint);
var sendBytes = pkg.ToBytes();
var sendLen = socket.SendTo(sendBytes, endPoint);
if (sendLen == sendBytes.Length) { return true; }
else { return false; }
}
public async static void AsyncSendDataPack(IPEndPoint endPoint, WebProtocol.SendDataPackage pkg)
public async static ValueTask<bool> SendDataPackAsync(IPEndPoint endPoint, WebProtocol.SendDataPackage pkg)
{
await Task.Run(() => { SendDataPack(endPoint, pkg); });
return await Task.Run(() => { return SendDataPack(endPoint, pkg); });
}
public static void SendLocalHost(int port, string[] stringArray)
public static bool SendLocalHost(int port, string[] stringArray)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
byte[] sendbuf = Encoding.ASCII.GetBytes(stringArray[0]);
byte[] sendBytes = Encoding.ASCII.GetBytes(stringArray[0]);
IPEndPoint ep = new IPEndPoint(localhost, port);
socket.SendTo(sendbuf, ep);
var sendLen = socket.SendTo(sendBytes, ep);
if (sendLen == sendBytes.Length) { return true; }
else { return false; }
}
public static void CycleSendLocalHost(int times, int sleepMilliSeconds, int port, string[] stringArray)

View File

@ -2,12 +2,29 @@ using System.Net;
using System.Net.Sockets;
using System.Text;
public struct UDPData
{
public DateTime datetime;
public string addr;
public int port;
public byte[] data;
}
/// <summary>
/// UDP Server
/// </summary>
public class UDPServer
{
private int listenPort;
private UdpClient listener;
private IPEndPoint groupEP;
private Dictionary<string, UDPData> udpData = new Dictionary<string, UDPData>();
/// <summary>
/// Construct a udp server with fixed port
/// </summary>
/// <param name="port"> Device UDP Port </param>
/// <returns> UDPServer class </returns>
public UDPServer(int port)
{
// Construction
@ -31,9 +48,31 @@ public class UDPServer
{
var remoteEP = new IPEndPoint(IPAddress.Any, listenPort);
byte[] bytes = listener.EndReceive(res, ref remoteEP);
var nowtime = DateTime.Now;
// Handle RemoteEP
string remoteStr;
if (remoteEP is not null)
{
var remoteAddress = remoteEP.Address.ToString();
var remotePort = remoteEP.Port;
// Record UDP Receive Data
udpData.Add(remoteAddress, new UDPData()
{
addr = remoteAddress,
port = remotePort,
data = bytes,
datetime = nowtime,
});
remoteStr = $"{remoteAddress}:{remotePort}";
}
else
{
remoteStr = "Unknown";
}
// Handle Package
var sign = bytes[0];
string recvData;
if (sign == (byte)WebProtocol.PackSign.SendAddr)
{
@ -60,8 +99,7 @@ public class UDPServer
recvData = Encoding.ASCII.GetString(bytes, 0, bytes.Length);
}
string remoteStr = (remoteEP is null) ? "Unknown" : $"{remoteEP.Address.ToString()}:{remoteEP.Port.ToString()}";
Console.WriteLine($"Receive Data from {remoteStr} at {DateTime.Now.ToString()}:");
Console.WriteLine($"Receive Data from {remoteStr} at {nowtime.ToString()}:");
Console.WriteLine($"Original Data: {BitConverter.ToString(bytes).Replace("-", " ")}");
if (recvData.Length != 0) Console.WriteLine(recvData);
Console.WriteLine();
@ -69,6 +107,10 @@ public class UDPServer
listener.BeginReceive(new AsyncCallback(ReceiveHandler), null);
}
/// <summary>
/// Start UDP Server
/// </summary>
/// <returns>None</returns>
public void Start()
{
try
@ -85,6 +127,10 @@ public class UDPServer
}
}
/// <summary>
/// Close UDP Server
/// </summary>
/// <returns>None</returns>
public void Stop()
{
listener.Close();

View File

@ -3,26 +3,50 @@ using Newtonsoft.Json;
namespace WebProtocol
{
/// <summary> The Sign of Package </summary>
public enum PackSign
{
/// <summary> Package: Send Read or Write Address to Device </summary>
SendAddr = 0x00,
/// <summary> Package: Send Data Which Update the flash of Device</summary>
SendData = 0xFF,
/// <summary> </summary>
RecvData = 0x0F,
/// <summary> </summary>
RecvResp = 0xF0,
}
/// <summary> Package Burst Type </summary>
public enum BurstType
{
/// <summary> Extended Type </summary>
ExtendBurst = 0b00,
/// <summary> Fixed Type </summary>
FixedBurst = 0b01,
}
/// <summary> Package options which to send address to read or write </summary>
/// <example>
/// {
/// "burType":0,
/// "commandID":1,
/// }
/// </example>
public struct SendAddrPackOptions
{
/// <summary> Package Burst Type </summary>
[JsonProperty("burstType")]
public BurstType burstType;
/// <example>1</example>
public byte commandID;
/// <example> true </example>
public bool isWrite;
/// <example> 255 </example>
public byte burstLength;
/// <example> 0x10_00_00_00 </example>
public UInt32 address;
public override string ToString()