From 210f6aa61c9f48c8da853a58566f7db9a6df5e7d Mon Sep 17 00:00:00 2001 From: SikongJueluo Date: Tue, 29 Apr 2025 21:13:38 +0800 Subject: [PATCH] add hot reset for remote update but no work --- server/Program.cs | 7 ++ server/server.csproj | 1 + server/src/RemoteUpdate.cs | 140 +++++++++++++++++++++++++----------- server/src/UdpClientPool.cs | 5 +- 4 files changed, 112 insertions(+), 41 deletions(-) diff --git a/server/Program.cs b/server/Program.cs index 02fd163..a3f8d0f 100644 --- a/server/Program.cs +++ b/server/Program.cs @@ -1,3 +1,4 @@ +using Honoo.IO.Hashing; using Microsoft.AspNetCore.Http.Features; using Newtonsoft.Json; using NLog; @@ -104,6 +105,12 @@ try app.MapGet("/", () => Results.Redirect("/swagger")); app.MapControllers(); + // { + // var crc = Crc.Create(CrcName.CRC32_MPEG_2); + // var checkSum = crc.ComputeFinal(new byte[] { 0x1C, 0xDF, 0x44, 0x21 }); + // logger.Info($"CRC: 0x{checkSum.ToString().PadLeft(8, '0')}"); + // } + app.Run("http://localhost:5000"); } catch (Exception exception) diff --git a/server/server.csproj b/server/server.csproj index dca031e..2ef7bc9 100644 --- a/server/server.csproj +++ b/server/server.csproj @@ -13,6 +13,7 @@ + diff --git a/server/src/RemoteUpdate.cs b/server/src/RemoteUpdate.cs index a1061f8..590096c 100644 --- a/server/src/RemoteUpdate.cs +++ b/server/src/RemoteUpdate.cs @@ -61,11 +61,11 @@ static class Global /// public const UInt32 ReadSign = 0x2000_0006; /// - /// 单独擦除开关-读写地址——控制位 - /// [31:24]: {-, -, -, -, -, -, -, - } - /// [23:17]: {-, -, -, -, -, -, -, - } - /// [16: 8]: {-, -, -, -, -, -, -, - } - /// [ 7: 0]: {-, -, -, -, -, -, -, clear_sw_en} + /// 单独擦除开关-读写地址——控制位
+ /// [31:24]: {-, -, -, -, -, -, -, - }
+ /// [23:17]: {-, -, -, -, -, -, -, - }
+ /// [16: 8]: {-, -, -, -, -, -, -, - }
+ /// [ 7: 0]: {-, -, -, -, -, -, -, clear_sw_en}
///
public const UInt32 ClearCtrl = 0x2000_0007; /// @@ -77,29 +77,29 @@ static class Global /// public const UInt32 ClearSign = 0x2000_0008; /// - /// 写开关-读写地址——标志位 - /// [31:24]: {-, -, -, -, -, -, -, - } - /// [23:17]: {-, -, -, -, -, -, -, - } - /// [16: 8]: {-, -, -, -, -, -, { open_sw_num}} - /// [ 7: 0]: {-, -, -, -, -, -, -, write_sw_code_en} + /// 写开关-读写地址——控制位
+ /// [31:24]: {-, -, -, -, -, -, -, - }
+ /// [23:17]: {-, -, -, -, -, -, -, - }
+ /// [16: 8]: {-, -, -, -, -, -, { open_sw_num}}
+ /// [ 7: 0]: {-, -, -, -, -, -, -, write_sw_code_en}
///
- public const UInt32 WriteSwitchSign = 0x2000_0009; + public const UInt32 WriteSwitchCtrl = 0x2000_0009; /// - /// 写开关-只读地址——控制位 - /// [31:24]: {-, -, -, -, -, -, -, - } - /// [23:17]: {-, -, -, -, -, -, -, - } - /// [16: 8]: {-, -, -, -, -, -, -, ipal_busy} - /// [ 7: 0]: {-, -, -, -, -, -, -, open_sw_code_done} + /// 写开关-只读地址——标志位
+ /// [31:24]: {-, -, -, -, -, -, -, - }
+ /// [23:17]: {-, -, -, -, -, -, -, - }
+ /// [16: 8]: {-, -, -, -, -, -, -, ipal_busy}
+ /// [ 7: 0]: {-, -, -, -, -, -, -, open_sw_code_done}
///
- public const UInt32 WriteSwitchCtrl = 0x2000_0010; + public const UInt32 WriteSwitchSign = 0x2000_000A; /// - /// 热启动开关-读写地址——控制位 - /// [31:24]: {-, -, -, -, -, -, -, - } - /// [23:17]: {-, -, -, -, -, -, -, - } - /// [16: 8]: {-, -, -, -, -, -, } - /// [ 7: 0]: {-, -, -, -, -, -, -, hotreset_en} + /// 热启动开关-读写地址——控制位
+ /// [31:24]: {-, -, -, -, -, -, -, - }
+ /// [23:17]: {-, -, -, -, -, -, -, - }
+ /// [16: 8]: {-, -, -, -, -, -, }
+ /// [ 7: 0]: {-, -, -, -, -, -, -, hotreset_en}
///
- public const UInt32 HotResetCtrl = 0x2000_0011; + public const UInt32 HotResetCtrl = 0x2000_000B; } } @@ -130,11 +130,11 @@ public class RemoteUpdater } /// - /// [TODO:description] + /// Writes a bitstream to the FPGA device. /// - /// [TODO:parameter] - /// [TODO:parameter] - /// [TODO:return] + /// The bitstream number (0-3). + /// The bitstream data to write. + /// A result indicating success or failure. public async ValueTask> WriteBitstream(int bitstreamNum, byte[] bitstream) { if (bitstreamNum < 0 || bitstreamNum > 0b11) @@ -165,7 +165,7 @@ public class RemoteUpdater // } { var ret = await UDPClientPool.ReadAddrWithWait( - this.remoteEP, Global.RemoteUpdaterAddr.WriteSign, 0x00_01, 0x00_01, 60 * 1000); + this.remoteEP, Global.RemoteUpdaterAddr.WriteSign, 0x00_00_00_01, 0x00_00_00_01, 60 * 1000); if (!ret.IsSuccessful) return new(ret.Error); if (!ret.Value) return new(new Exception("Clear bitstream failed even over time")); } @@ -178,7 +178,7 @@ public class RemoteUpdater } { var ret = await UDPClientPool.ReadAddrWithWait( - this.remoteEP, Global.RemoteUpdaterAddr.WriteSign, 0x00_10, 0x00_10, timeout); + this.remoteEP, Global.RemoteUpdaterAddr.WriteSign, 0x00_00_01_00, 0x00_00_01_00, timeout); if (!ret.IsSuccessful) return new(ret.Error); if (!ret.Value) return new(new Exception("Write bitstream failed even over time")); } @@ -188,11 +188,11 @@ public class RemoteUpdater } /// - /// [TODO:description] + /// Checks the CRC of a bitstream on the FPGA device. /// - /// [TODO:parameter] - /// [TODO:parameter] - /// [TODO:return] + /// The bitstream number (0-3). + /// The expected CRC checksum value. + /// A result indicating whether the CRC matches. public async ValueTask> CheckBitstreamCRC(int bitstreamNum, UInt32 checkSum) { // Clear Data @@ -210,7 +210,7 @@ public class RemoteUpdater } { var ret = await UDPClientPool.ReadAddrWithWait( - this.remoteEP, Global.RemoteUpdaterAddr.ReadSign, 0x00_11, 0x00_11, 60 * 1000); + this.remoteEP, Global.RemoteUpdaterAddr.ReadSign, 0x00_00_01_00, 0x00_00_01_00, 60 * 1000); if (!ret.IsSuccessful) return new(ret.Error); if (!ret.Value) return new(new Exception("Read bitstream failed even over time")); } @@ -218,7 +218,7 @@ public class RemoteUpdater { var ret = await UDPClientPool.ReadAddr( - this.remoteEP, Global.RemoteUpdaterAddr.ReadSign, timeout); + this.remoteEP, Global.RemoteUpdaterAddr.ReadCRC, timeout); if (!ret.IsSuccessful) return new(ret.Error); if (ret.Value.Options.Data is null) return new(new Exception("Receive null when read sign")); @@ -229,6 +229,8 @@ public class RemoteUpdater var retCRC = crcCode.Value == checkSum; logger.Trace($"Device {this.address} remote update check crc finished"); + logger.Debug($"Expected CRC32/Mpeg Code: 0x{checkSum.ToString("X").PadLeft(8, '0')}"); + logger.Debug($"Actually CRC32/Mpeg Code: 0x{crcCode.Value.ToString("X").PadLeft(8, '0')}"); return retCRC; } } @@ -237,8 +239,60 @@ public class RemoteUpdater /// [TODO:description] /// /// [TODO:parameter] - /// [TODO:parameter] /// [TODO:return] + public async ValueTask> HotReset(int bitstreamNum) + { + // Clear Data + await MsgBus.UDPServer.ClearUDPData(this.address); + + logger.Trace($"Clear up udp server {this.address} receive data"); + + + { + var ret = await UDPClientPool.WriteAddr( + this.remoteEP, Global.RemoteUpdaterAddr.ClearCtrl, + (UInt32)(0b1), timeout); + if (!ret.IsSuccessful) return new(ret.Error); + if (!ret.Value) return new(new Exception("Run clear failed")); + } + { + var ret = await UDPClientPool.ReadAddrWithWait( + this.remoteEP, Global.RemoteUpdaterAddr.ClearSign, 0x00_00_00_01, 0x00_00_00_01, 60 * 1000); + if (!ret.IsSuccessful) return new(ret.Error); + if (!ret.Value) return new(new Exception("Clear failed even over time")); + } + logger.Trace($"Device {this.address} remote update clear finished"); + + { + var ret = await UDPClientPool.WriteAddr( + this.remoteEP, Global.RemoteUpdaterAddr.WriteSwitchCtrl, + (UInt32)((bitstreamNum << 1) | 0b1), timeout); + if (!ret.IsSuccessful) return new(ret.Error); + if (!ret.Value) return new(new Exception("Run write switch code failed")); + } + { + var ret = await UDPClientPool.ReadAddrWithWait( + this.remoteEP, Global.RemoteUpdaterAddr.WriteSwitchSign, + 0x00_00_00_01, 0x00_00_00_01, 60 * 1000); + if (!ret.IsSuccessful) return new(ret.Error); + if (!ret.Value) return new(new Exception("Write switch code failed even over time")); + } + logger.Trace($"Device {this.address} remote update write switch open finished"); + + { + var ret = await UDPClientPool.WriteAddr( + this.remoteEP, Global.RemoteUpdaterAddr.HotResetCtrl, (UInt32)(0b1), timeout); + if (!ret.IsSuccessful) return new(ret.Error); + return ret.Value; + } + } + + /// + /// Updates the bitstream on the FPGA device. + /// + /// The bitstream number (0-3). + /// The bitstream data to update. + /// A result indicating success or failure. public async ValueTask> UpdateBitstream(int bitstreamNum, byte[] bitstream) { { @@ -247,11 +301,17 @@ public class RemoteUpdater if (!ret.Value) return new(new Exception("Write bitstream failed")); } { - var crc = new System.IO.Hashing.Crc32(); - crc.Append(bitstream); - var ret = await CheckBitstreamCRC(bitstreamNum, crc.GetCurrentHashAsUInt32()); - if (!ret.IsSuccessful) return new(ret.Error); + var crc = Honoo.IO.Hashing.Crc.Create(Honoo.IO.Hashing.CrcName.CRC32_MPEG_2); + var checkSum = crc.ComputeFinal(bitstream); + var ret = await CheckBitstreamCRC(bitstreamNum, checkSum.ToUInt32()); + if (!ret.IsSuccessful) return new(ret.Error); + // if (!ret.Value) return new(new Exception("Check bitstream crc32/mpeg-2 failed")); + } + { + var ret = await HotReset(bitstreamNum); + if (!ret.IsSuccessful) return new(ret.Error); + if (!ret.Value) return new(new Exception("Hot reset failed")); return ret.Value; } } diff --git a/server/src/UdpClientPool.cs b/server/src/UdpClientPool.cs index b8891f7..2c59a56 100644 --- a/server/src/UdpClientPool.cs +++ b/server/src/UdpClientPool.cs @@ -354,7 +354,10 @@ public class UDPClientPool return new(new Exception("Message bus not working!")); opts.IsWrite = true; - var writeTimes = dataArray.Length / (256 * (32 / 8)) + 1; + var hasRest = dataArray.Length % (256 * (32 / 8)) != 0; + var writeTimes = hasRest ? + dataArray.Length / (256 * (32 / 8)) + 1 : + dataArray.Length / (256 * (32 / 8)); for (var i = 0; i < writeTimes; i++) { // Sperate Data Array