private static async Task PerformFirmwareUpdate() { // Notify clients that we are now installing a firmware update using (await Model.Provider.AccessReadWriteAsync()) { Model.Provider.Get.State.Status = MachineStatus.Updating; } // Get the CRC16 checksum of the firmware binary byte[] firmwareBlob = new byte[_firmwareStream.Length]; await _firmwareStream.ReadAsync(firmwareBlob, 0, (int)_firmwareStream.Length); ushort crc16 = CRC16.Calculate(firmwareBlob); // Send the IAP binary to the firmware Console.Write("[info] Flashing IAP binary"); bool dataSent; do { dataSent = DataTransfer.WriteIapSegment(_iapStream); DataTransfer.PerformFullTransfer(); Console.Write('.'); }while (dataSent); Console.WriteLine(); _iapStream.Close(); _iapStream = null; // Start the IAP binary DataTransfer.StartIap(); // Send the firmware binary to the IAP program int numRetries = 0; do { if (numRetries != 0) { Console.WriteLine("Error"); } Console.Write("[info] Flashing RepRapFirmware"); _firmwareStream.Seek(0, SeekOrigin.Begin); while (DataTransfer.FlashFirmwareSegment(_firmwareStream)) { Console.Write('.'); } Console.WriteLine(); Console.Write("[info] Verifying checksum... "); }while (++numRetries < 3 && !DataTransfer.VerifyFirmwareChecksum(_firmwareStream.Length, crc16)); if (numRetries == 3) { Console.WriteLine("Error"); // Failed to flash the firmware await Utility.Logger.LogOutput(MessageType.Error, "Could not flash the firmware binary after 3 attempts. Please install it manually via bossac."); Program.CancelSource.Cancel(); } else { Console.WriteLine("OK"); // Wait for the IAP binary to restart the controller DataTransfer.WaitForIapReset(); Console.WriteLine("[info] Firmware update successful!"); } _firmwareStream.Close(); _firmwareStream = null; using (_firmwareUpdateLock.Lock()) { _firmwareUpdateRequest.SetResult(null); _firmwareUpdateRequest = null; } }
/// <summary> /// Perform the firmware update internally /// </summary> /// <returns>Asynchronous task</returns> private static async Task PerformFirmwareUpdate() { using (await Model.Provider.AccessReadWriteAsync()) { Model.Provider.Get.State.Status = MachineStatus.Updating; } DataTransfer.Updating = true; try { // Get the CRC16 checksum of the firmware binary byte[] firmwareBlob = new byte[_firmwareStream.Length]; await _firmwareStream.ReadAsync(firmwareBlob, 0, (int)_firmwareStream.Length); ushort crc16 = CRC16.Calculate(firmwareBlob); // Send the IAP binary to the firmware _logger.Info("Flashing IAP binary"); bool dataSent; do { dataSent = DataTransfer.WriteIapSegment(_iapStream); DataTransfer.PerformFullTransfer(); if (_logger.IsDebugEnabled) { Console.Write('.'); } }while (dataSent); if (_logger.IsDebugEnabled) { Console.WriteLine(); } // Start the IAP binary DataTransfer.StartIap(); // Send the firmware binary to the IAP program int numRetries = 0; do { if (numRetries != 0) { _logger.Error("Firmware checksum verification failed"); } _logger.Info("Flashing RepRapFirmware"); _firmwareStream.Seek(0, SeekOrigin.Begin); while (DataTransfer.FlashFirmwareSegment(_firmwareStream)) { if (_logger.IsDebugEnabled) { Console.Write('.'); } } if (_logger.IsDebugEnabled) { Console.WriteLine(); } _logger.Info("Verifying checksum"); }while (++numRetries < 3 && !DataTransfer.VerifyFirmwareChecksum(_firmwareStream.Length, crc16)); if (numRetries == 3) { // Failed to flash the firmware await Logger.LogOutput(MessageType.Error, "Could not flash the firmware binary after 3 attempts. Please install it manually via bossac."); Program.CancelSource.Cancel(); } else { // Wait for the IAP binary to restart the controller await DataTransfer.WaitForIapReset(); _logger.Info("Firmware update successful"); } } finally { DataTransfer.Updating = false; // Machine state is reset when the next status response is processed } }