From 80bf64b7d5e899d9d2dee0bba3655d1c9060eb1c Mon Sep 17 00:00:00 2001 From: nikzori Date: Fri, 28 Feb 2025 18:00:17 +0300 Subject: [PATCH] firmware test --- Datasheet.Designer.cs | 69 +++++++++++++++++++++++- Datasheet.cs | 108 ++++++++++++++++++++++++++++++++++--- Main.cs | 3 +- Modbus.cs | 2 +- Properties/AssemblyInfo.cs | 4 +- Update.cs | 83 ++++++++++++++++++++++++++++ 6 files changed, 257 insertions(+), 12 deletions(-) create mode 100644 Update.cs diff --git a/Datasheet.Designer.cs b/Datasheet.Designer.cs index 1a204c8..a4a2cca 100644 --- a/Datasheet.Designer.cs +++ b/Datasheet.Designer.cs @@ -55,9 +55,15 @@ this.label4 = new System.Windows.Forms.Label(); this.sensorPanel = new System.Windows.Forms.FlowLayoutPanel(); this.label9 = new System.Windows.Forms.Label(); + this.BrowseFirmware = new System.Windows.Forms.Button(); + this.label11 = new System.Windows.Forms.Label(); + this.firmwarePathLabel = new System.Windows.Forms.Label(); + this.WriteFirmware = new System.Windows.Forms.Button(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); this.groupBox1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.nudModbusID)).BeginInit(); this.groupBox2.SuspendLayout(); + this.groupBox3.SuspendLayout(); this.SuspendLayout(); // // groupBox1 @@ -312,7 +318,7 @@ this.sensorPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; this.sensorPanel.Location = new System.Drawing.Point(13, 168); this.sensorPanel.Name = "sensorPanel"; - this.sensorPanel.Size = new System.Drawing.Size(512, 248); + this.sensorPanel.Size = new System.Drawing.Size(512, 262); this.sensorPanel.TabIndex = 4; this.sensorPanel.WrapContents = false; // @@ -325,11 +331,63 @@ this.label9.TabIndex = 5; this.label9.Text = "Датчики"; // + // BrowseFirmware + // + this.BrowseFirmware.Location = new System.Drawing.Point(6, 38); + this.BrowseFirmware.Name = "BrowseFirmware"; + this.BrowseFirmware.Size = new System.Drawing.Size(75, 23); + this.BrowseFirmware.TabIndex = 14; + this.BrowseFirmware.Text = "Обзор"; + this.BrowseFirmware.UseVisualStyleBackColor = true; + this.BrowseFirmware.Click += new System.EventHandler(this.BrowseFirmware_Click); + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(4, 22); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(34, 13); + this.label11.TabIndex = 16; + this.label11.Text = "Путь:"; + // + // firmwarePathLabel + // + this.firmwarePathLabel.AutoSize = true; + this.firmwarePathLabel.Location = new System.Drawing.Point(44, 22); + this.firmwarePathLabel.Name = "firmwarePathLabel"; + this.firmwarePathLabel.Size = new System.Drawing.Size(126, 13); + this.firmwarePathLabel.TabIndex = 17; + this.firmwarePathLabel.Text = "C:\\Path\\To\\Firmware.bin"; + // + // WriteFirmware + // + this.WriteFirmware.Location = new System.Drawing.Point(87, 38); + this.WriteFirmware.Name = "WriteFirmware"; + this.WriteFirmware.Size = new System.Drawing.Size(75, 23); + this.WriteFirmware.TabIndex = 18; + this.WriteFirmware.Text = "Прошить"; + this.WriteFirmware.UseVisualStyleBackColor = true; + this.WriteFirmware.Click += new System.EventHandler(this.WriteFirmware_Click); + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.BrowseFirmware); + this.groupBox3.Controls.Add(this.WriteFirmware); + this.groupBox3.Controls.Add(this.label11); + this.groupBox3.Controls.Add(this.firmwarePathLabel); + this.groupBox3.Location = new System.Drawing.Point(13, 436); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(512, 72); + this.groupBox3.TabIndex = 19; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "Прошивка"; + // // Datasheet // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(537, 428); + this.ClientSize = new System.Drawing.Size(537, 511); + this.Controls.Add(this.groupBox3); this.Controls.Add(this.label9); this.Controls.Add(this.sensorPanel); this.Controls.Add(this.groupBox2); @@ -344,6 +402,8 @@ ((System.ComponentModel.ISupportInitialize)(this.nudModbusID)).EndInit(); this.groupBox2.ResumeLayout(false); this.groupBox2.PerformLayout(); + this.groupBox3.ResumeLayout(false); + this.groupBox3.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -377,5 +437,10 @@ private System.Windows.Forms.Button buttonSetSpeed; private System.Windows.Forms.Label label8; private System.Windows.Forms.ComboBox cBoxSpeed; + private System.Windows.Forms.Button BrowseFirmware; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.Label firmwarePathLabel; + private System.Windows.Forms.Button WriteFirmware; + private System.Windows.Forms.GroupBox groupBox3; } } \ No newline at end of file diff --git a/Datasheet.cs b/Datasheet.cs index 6ba17ef..77861ca 100644 --- a/Datasheet.cs +++ b/Datasheet.cs @@ -2,8 +2,10 @@ using System.Collections; using System.Collections.Generic; using System.Drawing; +using System.IO; using System.IO.Ports; using System.Linq; +using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -27,10 +29,24 @@ namespace Gidrolock_Modbus_Scanner List wiredSensors = new List(); List wirelessSensors; - + public static string firmwarePath; - public Datasheet(byte modbusID, Device device) : base() + + Thread fileThread = new Thread((ThreadStart)delegate + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.InitialDirectory = Application.StartupPath; + ofd.RestoreDirectory = true; + + if (ofd.ShowDialog() == DialogResult.OK) + { + firmwarePath = ofd.FileName; + //firmwarePathLabel.Text = ofd.FileName; + } + }); + + public Datasheet(byte modbusID, Device device) : base() { InitializeComponent(); @@ -70,7 +86,7 @@ namespace Gidrolock_Modbus_Scanner WiredSensor ws = new WiredSensor(i) { Width = 495, Height = 24 }; sensorPanel.Controls.Add(ws); ws.Visible = true; - + } if (device.hasScenarioSensor) { @@ -94,7 +110,7 @@ namespace Gidrolock_Modbus_Scanner sensorPanel.Controls[i].BackColor = i % 2 == 0 ? Color.White : Color.LightGray; - sensorPanel.Update(); + sensorPanel.Update(); } private async void buttonPoll_Click(object sender, EventArgs e) @@ -118,7 +134,7 @@ namespace Gidrolock_Modbus_Scanner } } - res = await PollEntry(device.valveStatus); + res = await PollEntry(device.valveStatus); Console.WriteLine("Polling for valve status, poll success: " + res); if (res) { @@ -267,7 +283,7 @@ namespace Gidrolock_Modbus_Scanner private async void buttonValve_Click(object sender, EventArgs e) { - ushort value = isValveClosed ? (ushort)0: (ushort)0xFF00; + ushort value = isValveClosed ? (ushort)0 : (ushort)0xFF00; Modbus.WriteSingleAsync(FunctionCode.WriteCoil, modbusID, device.valveStatus.address, value); Task.Delay(2000).ContinueWith(_ => @@ -368,6 +384,86 @@ namespace Gidrolock_Modbus_Scanner } catch (Exception ex) { MessageBox.Show(ex.Message); } } + + private void BrowseFirmware_Click(object sender, EventArgs e) + { + try + { + fileThread.TrySetApartmentState(ApartmentState.STA); + fileThread.Start(); + while (!fileThread.IsAlive) { Thread.Sleep(1); } + Thread.Sleep(1); + fileThread.Join(); + } + catch (Exception err) { MessageBox.Show(err.Message); } + } + + private void WriteFirmware_Click(object sender, EventArgs e) + { + FileStream fileStream = File.OpenRead(firmwarePath); + long bytesLeft = fileStream.Length; + int offset = 0; + int count; + byte[] buffer; + byte[] bdma; + List message; + int dma = 0; + Task.Run(() => + { + while (bytesLeft > 0) + { + count = bytesLeft > 64 ? 64 : (int)bytesLeft; + buffer = new byte[count]; + fileStream.Read(buffer, offset, count); + + + bdma = new byte[2]; + bdma[0] = (byte)((dma & 0xFF_00) >> 16); + bdma[1] = (byte)(dma & 0x00_FF); + + message = new List(); + message.Add(modbusID); // device ID + message.Add(0x10); // function code + message.Add(0xFF); // register address + message.Add(0xFF); // register address + message.Add(0x00); // regCnt (?) + message.Add(0x21); // regCnt (?) + message.Add(0x42); // data bytecount + message.Add(bdma[0]); + message.Add(bdma[1]); + + + for (int i = 0; i < buffer.Length; i++) + { + message.Add(buffer[i]); + } + byte[] CRC = new byte[2]; + Modbus.GetCRC(message.ToArray(), ref CRC); + message.Add(CRC[0]); + message.Add(CRC[1]); + + Console.WriteLine("Outgoing firmware message: " + Modbus.ByteArrayToString(message.ToArray())); + + isAwaitingResponse = true; + port.Write(message.ToArray(), 0, message.Count); + + Task.Delay(2000).ContinueWith(_ => + { + if (isAwaitingResponse) + { + MessageBox.Show("Превышено время ожидания ответа от устройства."); + isAwaitingResponse = false; + return; + } + }); + while (isAwaitingResponse) { continue; } + + bytesLeft -= count; + offset += count; + dma += 32; + } + }); + } } public class Sensor : FlowLayoutPanel { diff --git a/Main.cs b/Main.cs index 985bdc5..6acbed8 100644 --- a/Main.cs +++ b/Main.cs @@ -134,7 +134,8 @@ namespace Gidrolock_Modbus_Scanner }); while (isAwaitingResponse) { continue; } - + if (latestMessage is null) + return; if (latestMessage.Status == ModbusStatus.Error) return; diff --git a/Modbus.cs b/Modbus.cs index 5546c92..f986b35 100644 --- a/Modbus.cs +++ b/Modbus.cs @@ -210,7 +210,7 @@ namespace Gidrolock_Modbus_Scanner #region CRC Computation - static void GetCRC(byte[] message, ref byte[] CRC) + public static void GetCRC(byte[] message, ref byte[] CRC) { //Function expects a modbus message of any length as well as a 2 byte CRC array in which to //return the CRC values: diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 01a90ea..e38357d 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -30,6 +30,6 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.9.2.0")] -[assembly: AssemblyFileVersion("0.9.1.0")] +[assembly: AssemblyVersion("0.9.3.0")] +[assembly: AssemblyFileVersion("0.9.3.0")] [assembly: NeutralResourcesLanguage("en")] diff --git a/Update.cs b/Update.cs new file mode 100644 index 0000000..3ce738f --- /dev/null +++ b/Update.cs @@ -0,0 +1,83 @@ +using Gidrolock_Modbus_Scanner; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Ports; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Gidrolock_Modbus_Configurator +{ + public class Update + { + bool isAwaitingResponse = false; + ModbusResponseEventArgs latestMessage; + SerialPort port = Modbus.port; + + public void UpdateFirmware(Stream fileStream) + { + Modbus.ResponseReceived += (sndr, msg) => { isAwaitingResponse = false; latestMessage = msg; }; + int offset = 0; + byte[] buffer; + byte[] preCRC; + byte[] message; + byte[] CRC = new byte[2]; + + long bytesLeft = fileStream.Length; + + while (bytesLeft > 0) + { + int count = bytesLeft > 64 ? 64 : (int)bytesLeft; + buffer = new byte[count]; + + fileStream.Read(buffer, offset, count); + + preCRC = new byte[7 + buffer.Length]; + + preCRC[0] = 0x1E; // Modbus ID + preCRC[1] = 0x10; // Function code + preCRC[2] = 0xFF; // Address 01 + preCRC[3] = 0xFF; // Address 02 + preCRC[4] = 0x00; // Cnt01 + preCRC[5] = 0x21; // Cnt02 + preCRC[6] = 0x42; // byte count + + for (int i = 0; i < count; i++) + { + preCRC[i+7] = buffer[i]; + } + Modbus.GetCRC(preCRC, ref CRC); + message = new byte[preCRC.Length + 2]; + + for (int i = 0; i < preCRC.Length; i++) + { + message[i] = preCRC[i]; + } + message[message.Length - 2] = CRC[0]; + message[message.Length - 1] = CRC[1]; + + isAwaitingResponse = true; + port.Write(message, 0, message.Length); + + var delay = Task.Delay(2000).ContinueWith(_ => + { + if (isAwaitingResponse) + { + MessageBox.Show("Превышено время ожидания ответа от устройства."); + isAwaitingResponse = false; + } + }); + while (isAwaitingResponse) { continue; } + + if (latestMessage != null && latestMessage.Status != ModbusStatus.Error) + { + bytesLeft -= count; + offset += count; + } + } + } + } +}