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; using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer(); 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", Title = "FPGA Web Lab API",
Description = "Use FPGA in the cloud", Description = "Use FPGA in the cloud",
Version = "v1" 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(); var app = builder.Build();

View File

@ -4,13 +4,14 @@
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DotNext" Version="5.19.1" /> <PackageReference Include="DotNext" Version="5.19.1" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.23" /> <PackageReference Include="Microsoft.OpenApi" Version="1.6.23" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <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> </ItemGroup>
</Project> </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 System.Net;
using Common; using Common;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Router namespace Router
{ {
/// <summary>
/// Web API
/// </summary>
class API 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); 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, string address,
int port, int port,
WebProtocol.BurstType burstType, // WebProtocol.BurstType burstType,
byte commandID, // byte commandID,
bool isWrite, // bool isWrite,
byte burstLength, // byte burstLength,
UInt32 devAddress) // UInt32 devAddress)
WebProtocol.SendAddrPackOptions opts)
{ {
WebProtocol.SendAddrPackOptions opts; // WebProtocol.SendAddrPackOptions opts;
opts.burstType = burstType; // opts.burstType = burstType;
opts.commandID = commandID; // opts.commandID = commandID;
opts.isWrite = isWrite; // opts.isWrite = isWrite;
opts.burstLength = burstLength; // opts.burstLength = burstLength;
opts.address = devAddress; // opts.address = devAddress;
var endPoint = new IPEndPoint(IPAddress.Parse(address), port); 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); var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
UDPClientPool.SendDataPack(endPoint, var ret = await UDPClientPool.SendDataPackAsync(endPoint,
new WebProtocol.SendDataPackage(NumberProcessor.StringToBytes(data).Value)); 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"); 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); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
byte[] sendbuf = Encoding.ASCII.GetBytes(stringArray[0]); 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 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 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 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); 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); 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) 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.Net.Sockets;
using System.Text; 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 public class UDPServer
{ {
private int listenPort; private int listenPort;
private UdpClient listener; private UdpClient listener;
private IPEndPoint groupEP; 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) public UDPServer(int port)
{ {
// Construction // Construction
@ -31,9 +48,31 @@ public class UDPServer
{ {
var remoteEP = new IPEndPoint(IPAddress.Any, listenPort); var remoteEP = new IPEndPoint(IPAddress.Any, listenPort);
byte[] bytes = listener.EndReceive(res, ref remoteEP); 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]; var sign = bytes[0];
string recvData; string recvData;
if (sign == (byte)WebProtocol.PackSign.SendAddr) if (sign == (byte)WebProtocol.PackSign.SendAddr)
{ {
@ -60,8 +99,7 @@ public class UDPServer
recvData = Encoding.ASCII.GetString(bytes, 0, bytes.Length); 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 {nowtime.ToString()}:");
Console.WriteLine($"Receive Data from {remoteStr} at {DateTime.Now.ToString()}:");
Console.WriteLine($"Original Data: {BitConverter.ToString(bytes).Replace("-", " ")}"); Console.WriteLine($"Original Data: {BitConverter.ToString(bytes).Replace("-", " ")}");
if (recvData.Length != 0) Console.WriteLine(recvData); if (recvData.Length != 0) Console.WriteLine(recvData);
Console.WriteLine(); Console.WriteLine();
@ -69,6 +107,10 @@ public class UDPServer
listener.BeginReceive(new AsyncCallback(ReceiveHandler), null); listener.BeginReceive(new AsyncCallback(ReceiveHandler), null);
} }
/// <summary>
/// Start UDP Server
/// </summary>
/// <returns>None</returns>
public void Start() public void Start()
{ {
try try
@ -85,6 +127,10 @@ public class UDPServer
} }
} }
/// <summary>
/// Close UDP Server
/// </summary>
/// <returns>None</returns>
public void Stop() public void Stop()
{ {
listener.Close(); listener.Close();

View File

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