Обновление прошивкиC#

Место общения программистов C#
Ответить
Anonymous
 Обновление прошивки

Сообщение Anonymous »

Я создал приложение в Unity, написанное на C#, которое считывает COM-порт USB с устройства esp32 (Wemos Lolin32).
Я хочу, чтобы приложение обновляло прошивку устройства с помощью пользовательской Код C#.
Функциональность должна быть аналогична esptool.py. Но я предпочитаю не использовать ни его, ни какую-либо внешнюю библиотеку.
Судя по собранной информации, процесс обновления в общих чертах выглядит следующим образом:
  • войти в режим загрузчика
  • отправить команду синхронизации
  • стереть флэш-память
  • записать новую флэш-память
  • перезагрузить устройство
К сожалению, это не работает.
Повсюду есть попытки, и они есть. явных ошибок не обнаружено.
Я подозреваю, что причина кроется в неточных номерах команд и/или неправильном времени.
Далее пишется полный код. Есть какие-нибудь советы?
Спасибо!

// Update call
StartCoroutine(UpdateFirmware());

// ====================================================================
IEnumerator UpdateFirmware()
{
serialPort.BaudRate = 921600;
serialPort.ReadTimeout = 1;

yield return EnterBootloaderMode();
yield return SendSyncCommand();
yield return EraseFlash();
for (int i = 0; i < 4; i++) yield return WriteFlash(i);

serialPort.BaudRate = 115200;
serialPort.ReadTimeout = 90;

yield return ResetDevice();

AddLog("Firmware update completed!");
yield return null;
}

// --------------------------------------------------------------------
IEnumerator EnterBootloaderMode()
{
serialPort.DtrEnable = false;
serialPort.RtsEnable = false;
yield return new WaitForSecondsRealtime(1.5f);

serialPort.DtrEnable = true;
serialPort.RtsEnable = false;
yield return new WaitForSecondsRealtime(1.5f);

serialPort.DtrEnable = true;
serialPort.RtsEnable = true;
yield return new WaitForSecondsRealtime(1.5f);
}

// --------------------------------------------------------------------
IEnumerator SendSyncCommand()
{
byte[] syncCommand = new byte[] { 0x07, 0x07, 0x12, 0x20, 0x55, 0x55, 0x55, 0x55 };

try
{
serialPort.Write(syncCommand, 0, syncCommand.Length);
serialPort.BaseStream.Flush();
}
catch { AddLog("Sync Failed"); yield break; }

yield return new WaitForSecondsRealtime(2.0f);
}

// --------------------------------------------------------------------
IEnumerator EraseFlash()
{
byte[] eraseCommand = new byte[] { 0xC0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 };

try
{
serialPort.Write(eraseCommand, 0, eraseCommand.Length);
serialPort.BaseStream.Flush();
}
catch { AddLog("Erase Failed"); yield break; }

yield return new WaitForSecondsRealtime(6.0f);
}

// --------------------------------------------------------------------
IEnumerator WriteFlash(int id)
{
int offset = 0;
int packetSize = 1024;

byte[] fileBytes = firmwareData[id];
while (offset < fileBytes.Length)
{
int remaining = fileBytes.Length - offset;
int size = remaining < packetSize ? remaining : packetSize;
byte[] packet = new byte[size];
Array.Copy(fileBytes, offset, packet, 0, size);

// Prepare the command
byte[] writeCommand = new byte[8 + 4 + packet.Length];
writeCommand[0] = 0x02; // OpCode for write flash

// Length of the data including the address (4 bytes for address + data length)
int dataLength = 4 + packet.Length;
writeCommand[1] = (byte)(dataLength & 0xFF);
writeCommand[2] = (byte)((dataLength >> 8) & 0xFF);
writeCommand[3] = (byte)((dataLength >> 16) & 0xFF);
writeCommand[4] = (byte)((dataLength >> 24) & 0xFF);

// Checksum (simple sum of all data bytes)
byte checksum = 0;
foreach (byte b in packet) checksum ^= b;
writeCommand[5] = checksum;

// Reserved bytes
writeCommand[6] = 0x00;
writeCommand[7] = 0x00;

// Flash address
int[] flashAddress = new int[] {0xe000, 0x1000, 0x10000, 0x8000};
writeCommand[8] = (byte)(flashAddress[id] & 0xFF);
writeCommand[9] = (byte)((flashAddress[id] >> 8) & 0xFF);
writeCommand[10] = (byte)((flashAddress[id] >> 16) & 0xFF);
writeCommand[11] = (byte)((flashAddress[id] >> 24) & 0xFF);

// Data payload
Array.Copy(packet, 0, writeCommand, 12, packet.Length);

// Send the command
try { serialPort.Write(writeCommand, 0, writeCommand.Length); }
catch { AddLog($"Error writing packet #" + id); yield break; }

// Wait a bit before sending the next packet
offset += size;
yield return new WaitForSecondsRealtime(0.01f);
}
}

// --------------------------------------------------------------------
IEnumerator ResetDevice()
{
serialPort.DtrEnable = false;
serialPort.RtsEnable = true;
yield return new WaitForSecondsRealtime(1.5f);
}
// --------------------------------------------------------------------



Подробнее здесь: https://stackoverflow.com/questions/790 ... are-update
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»