Skip to content

Commit

Permalink
lib: store firmware path when starting multiboot
Browse files Browse the repository at this point in the history
doom: read firmware path from OTA
  • Loading branch information
and3rson committed Mar 20, 2024
1 parent 4daae5a commit 5389b64
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 7 deletions.
17 changes: 15 additions & 2 deletions firmware/doom/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,22 @@ void setup() {
char arg[] = "doomgeneric";
char arg2[] = "-iwad";
char arg3[64];

// Get firmware arg
String firmwareFile = lilka::multiboot.getFirmwarePath();
lilka::serial_log("Firmware file: %s\n", firmwareFile.c_str());
String firmwarePath;
if (firmwareFile.length()) {
// Get directory from firmware file
int lastSlash = firmwareFile.lastIndexOf('/');
firmwarePath = firmwareFile.substring(0, lastSlash + 1);
} else {
firmwarePath = "/";
}

bool found = false;
// Find the wad file
File root = SD.open("/");
// Find the WAD file
File root = SD.open(firmwarePath.c_str());
File file;
while ((file = root.openNextFile())) {
if (file.isDirectory()) {
Expand Down
43 changes: 38 additions & 5 deletions sdk/lib/lilka/src/lilka/multiboot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ int MultiBoot::start(String path) {
ota_partition = esp_ota_get_next_update_partition(current_partition); // get ota1 (we're in ota0 now)
if (ota_partition == NULL) {
serial_err("Failed to get next OTA partition");
return -3;
return -4;
}
serial_log(
"OTA partition: %s, type: %d, subtype: %d, size: %d",
Expand All @@ -137,7 +137,21 @@ int MultiBoot::start(String path) {
esp_err_t err = esp_ota_begin(ota_partition, bytesTotal, &ota_handle);
if (err != ESP_OK) {
serial_err("Failed to begin OTA: %d", err);
return -4;
return -5;
}

// Write path to last 256 bytes of the OTA partition
size_t partition_size = ota_partition->size;
size_t offset = partition_size - 256;
String arg = path;
// Remove "/sd" prefix
// TODO: Maybe we should use absolute path (including "/sd")?
if (arg.startsWith("/sd/")) {
arg = arg.substring(3);
}
if (esp_partition_write(ota_partition, offset, arg.c_str(), arg.length() + 1) != ESP_OK) {
serial_err("Failed to write arg to OTA partition");
return -6;
}

return 0;
Expand All @@ -159,7 +173,7 @@ int MultiBoot::process() {
esp_err_t err = esp_ota_write(ota_handle, buf, len);
if (err != ESP_OK) {
serial_err("Failed to write OTA: %d", err);
return -5;
return -7;
}

bytesWritten += len;
Expand Down Expand Up @@ -193,14 +207,14 @@ int MultiBoot::finishAndReboot() {
esp_err_t err = esp_ota_end(ota_handle);
if (err != ESP_OK) {
serial_err("Failed to end OTA: %d", err);
return -6;
return -8;
}

// Перевстановлення активного розділу на OTA-розділ (його буде запущено лише один раз, після чого активним залишиться основний розділ).
err = esp_ota_set_boot_partition(ota_partition);
if (err != ESP_OK) {
serial_err("Failed to set boot partition: %d", err);
return -7;
return -9;
}

// Запуск нової прошивки.
Expand All @@ -209,6 +223,25 @@ int MultiBoot::finishAndReboot() {
return 0; // unreachable
}

String MultiBoot::getFirmwarePath() {
size_t partition_size = current_partition->size;
size_t offset = partition_size - 256;
char buf[256];
if (esp_partition_read(current_partition, offset, buf, sizeof(buf)) != ESP_OK) {
serial_err("Failed to read firmware path from current partition");
return "";
}
if (static_cast<uint8_t>(buf[0]) == 0xFF) {
serial_err("Firmware path is not set");
return "";
}
// Clear firmware path from OTA partition
if (esp_partition_erase_range(ota_partition, partition_size - 256, 256) != ESP_OK) {
serial_err("Failed to erase firmware path from OTA partition");
}
return String(buf);
}

MultiBoot multiboot;

} // namespace lilka
2 changes: 2 additions & 0 deletions sdk/lib/lilka/src/lilka/multiboot.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class MultiBoot {
/// \return <0 - у разі помилки. В разі успіху цей метод не повертається, оскільки пристрій перезавантажується.
int finishAndReboot();

String getFirmwarePath();

private:
String path;
FILE* file;
Expand Down

0 comments on commit 5389b64

Please sign in to comment.