This commit is contained in:
2026-02-27 11:50:27 +01:00
parent 5934bba4af
commit 82b535a183
12 changed files with 323 additions and 65 deletions

View File

@@ -1,9 +1,12 @@
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/logging/log_ctrl.h>
#include <string.h>
#include <fs.h>
#include <app_version.h>
#include <zephyr/sys/crc.h>
#include <zephyr/dfu/mcuboot.h>
#include <zephyr/sys/reboot.h>
#include <usb.h>
#include <protocol.h>
@@ -80,22 +83,50 @@ int send_info()
int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_crc32)
{
int rc;
struct fs_file_t file;
ssize_t bytes_written = 0;
uint32_t running_crc32 = 0;
uint32_t retry_count = 0;
size_t accumulated = 0;
struct fs_file_t file;
bool firmware_update = false;
fs_file_t_init(&file);
fs_pm_unlink(filename);
LOG_DBG("Opening file '%s' for writing (expected size: %zd bytes, expected CRC32: 0x%08x)", filename, filesize, expected_crc32);
rc = fs_pm_open(&file, filename, FS_O_CREATE | FS_O_WRITE);
if (rc < 0)
if (strcmp(filename, "update.bin") == 0 ||
strcmp(filename, "firmware.bin") == 0 ||
strcmp(filename, "update") == 0 ||
strcmp(filename, "firmware") == 0)
{
LOG_ERR("Failed to open file '%s' for writing: %d", filename, rc);
return -rc;
firmware_update = true;
LOG_INF("Firmware update requested with file '%s'", filename);
}
if (firmware_update)
{
slot_info_t slot1_info;
rc = flash_get_slot_info(&slot1_info);
if (rc < 0)
{
LOG_ERR("Failed to get slot 1 info: %d", rc);
return rc;
}
if (filesize > slot1_info.size)
{
LOG_ERR("File size %zd exceeds slot 1 size %zu", filesize, slot1_info.size);
return -EFBIG;
}
flash_init_firmware_upload();
}
else
{
fs_file_t_init(&file);
fs_pm_unlink(filename);
LOG_DBG("Opening file '%s' for writing (expected size: %zd bytes, expected CRC32: 0x%08x)", filename, filesize, expected_crc32);
rc = fs_pm_open(&file, filename, FS_O_CREATE | FS_O_WRITE);
if (rc < 0)
{
LOG_ERR("Failed to open file '%s' for writing: %d", filename, rc);
return -rc;
}
}
usb_write_buffer((const uint8_t *)"READY\n", 6);
uint32_t start = k_uptime_get_32();
@@ -110,7 +141,13 @@ int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_cr
if (read < 0)
{
LOG_ERR("Error reading from USB: %d", read);
fs_pm_close(&file);
if (firmware_update)
{
}
else
{
fs_pm_close(&file);
}
return -read;
}
else if (read == 0)
@@ -118,18 +155,24 @@ int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_cr
if (retry_count >= 10)
{
LOG_ERR("No data received from USB after multiple attempts");
fs_pm_close(&file);
if (firmware_update)
{
}
else
{
fs_pm_close(&file);
}
return -ETIMEDOUT;
}
usb_resume_rx();
if ((bytes_written + accumulated) == 0)
{
usb_wait_for_data(K_SECONDS(30));
usb_wait_for_data(K_SECONDS(1));
}
else
{
usb_wait_for_data(K_SECONDS(1));
usb_wait_for_data(K_MSEC(100));
}
retry_count++;
continue;
@@ -144,14 +187,25 @@ int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_cr
ODER wenn wir das Ende der Datei erreicht haben. */
if (accumulated == sizeof(buffer) || (bytes_written + accumulated) == filesize)
{
ssize_t written = fs_write(&file, buffer, accumulated);
if (written < 0)
if (firmware_update)
{
LOG_ERR("Error writing to file '%s': %d", filename, (int)written);
fs_pm_close(&file);
return (int)written;
int rc = flash_write_firmware_block(buffer, accumulated, (bytes_written + accumulated) == filesize);
if (rc < 0)
{
LOG_ERR("Error writing to flash: %d", rc);
return rc;
}
}
else
{
ssize_t written = fs_write(&file, buffer, accumulated);
if (written < 0)
{
LOG_ERR("Error writing to file '%s': %d", filename, (int)written);
fs_pm_close(&file);
return (int)written;
}
}
/* CRC erst nach dem erfolgreichen Block-Schreiben berechnen */
running_crc32 = crc32_ieee_update(running_crc32, buffer, accumulated);
bytes_written += accumulated;
@@ -164,8 +218,26 @@ int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_cr
uint32_t duration = k_uptime_get_32() - start;
uint32_t kb_per_s = (filesize * 1000) / (duration * 1024 + 1);
LOG_DBG("Received file '%s' (%zd bytes) in %u ms (%u kb/s), CRC32: 0x%08x", filename, filesize, duration, kb_per_s, running_crc32);
fs_pm_close(&file);
LOG_DBG("Closed file '%s' after writing", filename);
if (firmware_update)
{
int rc;
rc = boot_request_upgrade(BOOT_UPGRADE_TEST);
if (rc < 0) {
LOG_ERR("Failed to request firmware upgrade: %d", rc);
return rc;
}
send_ok();
LOG_INF("Firmware upgrade requested, rebooting into bootloader...");
k_sleep(K_MSEC(100)); // Kurze Pause, damit die OK-Antwort noch rausgeht
while (log_process());
sys_reboot(SYS_REBOOT_COLD);
}
else
{
fs_pm_close(&file);
LOG_DBG("Closed file '%s' after writing", filename);
}
if (running_crc32 != expected_crc32)
{
LOG_ERR("CRC32 mismatch for file '%s': expected 0x%08x, got 0x%08x", filename, expected_crc32, running_crc32);
@@ -175,6 +247,26 @@ int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_cr
return 0;
}
int mkdir(const char *path) {
int rc = fs_pm_mkdir(path);
if (rc < 0)
{
LOG_ERR("Failed to create directory '%s': %d", path, rc);
}
LOG_DBG("Directory '%s' created successfully", path);
return rc;
}
int rm(const char *path) {
int rc = fs_pm_unlink(path);
if (rc < 0)
{
LOG_ERR("Failed to remove '%s': %d", path, rc);
}
LOG_DBG("'%s' removed successfully", path);
return rc;
}
void execute_current_command(void)
{
int rc;
@@ -233,6 +325,27 @@ void execute_current_command(void)
send_error(rc);
}
break;
case CMD_MKDIR:
LOG_DBG("Executing MKDIR command with parameters: '%s'", buffer);
rc = mkdir((char *)buffer);
if (rc == 0) {
send_ok();
}
else {
send_error(rc);
}
break;
case CMD_RM:
LOG_DBG("Executing RM command with parameters: '%s'", buffer);
rc = rm((char *)buffer);
if (rc == 0) {
send_ok();
audio_refresh_file_count(); // Nach erfolgreichem Löschen die Anzahl der verfügbaren Audiodateien aktualisieren
}
else {
send_error(rc);
}
break;
default:
LOG_ERR("No execution logic for command %d", current_command);
send_error(ENOSYS);
@@ -274,7 +387,16 @@ protocol_state_t reading_command(uint8_t byte)
LOG_DBG("Received PUT_BINARY_FILE command");
current_command = CMD_PUT_BINARY_FILE;
}
else if (strcmp((char *)buffer, "mkdir") == 0)
{
LOG_DBG("Received MKDIR command");
current_command = CMD_MKDIR;
}
else if (strcmp((char *)buffer, "rm") == 0)
{
LOG_DBG("Received RM command");
current_command = CMD_RM;
}
else
{
LOG_DBG("Unknown command: %s", buffer);