This commit is contained in:
2026-02-27 17:07:07 +01:00
parent e848168840
commit dc3467ac0f
6 changed files with 206 additions and 56 deletions

View File

@@ -176,14 +176,37 @@ int flash_get_slot_info(slot_info_t *info) {
}
int flash_init_firmware_upload(void) {
const struct flash_area *fa;
int rc;
rc = flash_img_init_id(&flash_ctx, SLOT1_ID);
rc = flash_area_open(SLOT1_ID, &fa);
if (rc != 0) {
printk("Error initializing flash image: %d\n", rc);
return rc;
}
return 0;
LOG_INF("Erasing secondary slot (size: %zu)...", fa->fa_size);
rc = flash_area_erase(fa, 0, fa->fa_size);
flash_area_close(fa);
if (rc != 0) {
LOG_ERR("Failed to erase flash area: %d", rc);
return rc;
}
rc = flash_img_init_id(&flash_ctx, SLOT1_ID);
if (rc != 0)
{
LOG_ERR("Failed to initialize flash image context: %d", rc);
return rc;
}
else
{
LOG_INF("Flash image context initialized for slot 1 with size %zu", flash_ctx.flash_area->fa_size);
}
return rc;
}
int flash_write_firmware_block(const uint8_t *buffer, size_t length, bool is_last_block) {

View File

@@ -75,8 +75,7 @@ int main(void)
}
else if (reboot_code == REBOOT_STATUS_FIRMWARE_CONFIRMED)
{
LOG_INF("Firmware was just confirmed in the last reboot. Playing confirmation sound.");
audio_play("/lfs/sys/confirm");
LOG_INF("Firmware was just confirmed in the last reboot.");
}
else
{

View File

@@ -2,6 +2,7 @@
#include <zephyr/logging/log.h>
#include <zephyr/logging/log_ctrl.h>
#include <string.h>
#include <errno.h>
#include <fs.h>
#include <app_version.h>
#include <zephyr/sys/crc.h>
@@ -12,7 +13,7 @@
#include <protocol.h>
#include <audio.h>
#define PROTOCOL_VERSION 1
#define PROTOCOL_VERSION 2
LOG_MODULE_REGISTER(protocol, LOG_LEVEL_INF);
@@ -33,7 +34,57 @@ void send_ok()
usb_write_buffer((const uint8_t *)response, strlen(response));
}
void send_error(int32_t error_code)
static protocol_error_t protocol_map_error(int32_t rc)
{
if (rc == 0)
{
return P_ERR_NONE;
}
int32_t err = rc < 0 ? -rc : rc;
switch (err)
{
case ENOENT:
return P_ERR_FILE_NOT_FOUND;
case EEXIST:
return P_ERR_ALREADY_EXISTS;
case ENOTDIR:
return P_ERR_NOT_A_DIRECTORY;
case EISDIR:
return P_ERR_IS_A_DIRECTORY;
case EACCES:
case EPERM:
return P_ERR_ACCESS_DENIED;
case ENOSPC:
return P_ERR_NO_SPACE;
case EFBIG:
return P_ERR_FILE_TOO_LARGE;
case ETIMEDOUT:
return P_ERR_TIMEOUT;
case EMSGSIZE:
return P_ERR_COMMAND_TOO_LONG;
case EINVAL:
return P_ERR_INVALID_PARAMETERS;
case EILSEQ:
return P_ERR_INVALID_COMMAND;
case ECANCELED:
return P_ERR_TRANSFER_ABORTED;
case ENOSYS:
case ENOTSUP:
return P_ERR_NOT_SUPPORTED;
case EBUSY:
return P_ERR_BUSY;
case EBADMSG:
return P_ERR_CRC_MISMATCH;
case EIO:
return P_ERR_IO;
default:
return P_ERR_INTERNAL;
}
}
void send_error(protocol_error_t error_code)
{
char response[32];
snprintf(response, sizeof(response), "ERR %d\n", error_code);
@@ -51,7 +102,7 @@ int cmd_ls(const char *path)
if (fs_pm_opendir(&dirp, ls_path) < 0)
{
LOG_ERR("Failed to open directory '%s'", ls_path);
return ENOENT;
return -ENOENT;
}
char tx_buffer[300];
@@ -73,7 +124,7 @@ int cmd_info()
if (rc)
{
LOG_ERR("Failed to get filesystem stats: %d", rc);
return -rc;
return rc;
}
snprintf(info, sizeof(info), "%u;%s;%lu;%lu;%lu;%s\n", PROTOCOL_VERSION, APP_VERSION_STRING, stat.f_frsize, stat.f_blocks, stat.f_bfree, boot_is_img_confirmed() ? "CONFIRMED" : "UNCONFIRMED");
usb_write_buffer((const uint8_t *)info, strlen(info));
@@ -124,7 +175,7 @@ int cmd_put_binary_file(const char *filename, ssize_t filesize, uint32_t expecte
if (rc < 0)
{
LOG_ERR("Failed to open file '%s' for writing: %d", filename, rc);
return -rc;
return rc;
}
}
usb_write_buffer((const uint8_t *)"READY\n", 6);
@@ -148,7 +199,7 @@ int cmd_put_binary_file(const char *filename, ssize_t filesize, uint32_t expecte
{
fs_pm_close(&file);
}
return -read;
return (int)read;
}
else if (read == 0)
{
@@ -222,7 +273,8 @@ int cmd_put_binary_file(const char *filename, ssize_t filesize, uint32_t expecte
{
int rc;
rc = boot_request_upgrade(BOOT_UPGRADE_TEST);
if (rc < 0) {
if (rc < 0)
{
LOG_ERR("Failed to request firmware upgrade: %d", rc);
return rc;
}
@@ -239,13 +291,14 @@ int cmd_put_binary_file(const char *filename, ssize_t filesize, uint32_t expecte
if (running_crc32 != expected_crc32)
{
LOG_ERR("CRC32 mismatch for file '%s': expected 0x%08x, got 0x%08x", filename, expected_crc32, running_crc32);
return -EIO;
return -EBADMSG;
}
LOG_DBG("File '%s' received successfully with matching CRC32", filename);
return 0;
}
int cmd_mkdir(const char *path) {
int cmd_mkdir(const char *path)
{
int rc = fs_pm_mkdir(path);
if (rc < 0)
{
@@ -255,7 +308,8 @@ int cmd_mkdir(const char *path) {
return rc;
}
int cmd_rm(const char *path) {
int cmd_rm(const char *path)
{
int rc = fs_pm_unlink(path);
if (rc < 0)
{
@@ -265,37 +319,49 @@ int cmd_rm(const char *path) {
return rc;
}
int cmd_confirm_firmware() {
int rc = boot_write_img_confirmed();
if (rc < 0)
int cmd_confirm_firmware()
{
if (!boot_is_img_confirmed())
{
LOG_ERR("Failed to confirm firmware: %d", rc);
return rc;
int rc = boot_write_img_confirmed();
if (rc < 0)
{
LOG_ERR("Failed to confirm firmware: %d", rc);
return rc;
}
LOG_INF("Firmware confirmed successfully");
send_ok();
audio_play("/lfs/sys/confirm");
}
else
{
LOG_INF("Firmware is already confirmed, no action taken");
}
LOG_INF("Firmware confirmed successfully");
send_ok();
reboot_with_status(REBOOT_STATUS_FIRMWARE_CONFIRMED);
return 0;
}
int cmd_reboot_device() {
int cmd_reboot_device()
{
LOG_INF("Rebooting device as requested by host...");
send_ok();
reboot_with_status(REBOOT_STATUS_NORMAL);
return 0; // Dieser Code wird nie erreicht, aber wir geben ihn der Vollständigkeit halber zurück
}
void cmd_play(const char *filename) {
void cmd_play(const char *filename)
{
LOG_DBG("Play command received with filename: '%s'", filename);
audio_play(filename);
}
int cmd_check(const char *param) {
int cmd_check(const char *param)
{
LOG_DBG("Check command received with parameter: '%s'", param);
struct fs_file_t file;
fs_file_t_init(&file);
int rc = fs_pm_open(&file, param, FS_O_READ);
if (rc < 0) {
if (rc < 0)
{
LOG_ERR("Check failed: file '%s' not found", param);
return -ENOENT;
}
@@ -307,7 +373,8 @@ int cmd_check(const char *param) {
crc32 = crc32_ieee_update(crc32, buffer, read);
}
fs_pm_close(&file);
if (read < 0) {
if (read < 0)
{
LOG_ERR("Check failed: error reading file '%s': %d", param, (int)read);
return (int)read;
}
@@ -332,7 +399,7 @@ void execute_current_command(void)
}
else
{
send_error(rc);
send_error(protocol_map_error(rc));
}
break;
case CMD_INFO:
@@ -348,7 +415,7 @@ void execute_current_command(void)
}
else
{
send_error(rc);
send_error(protocol_map_error(rc));
}
break;
case CMD_PUT_BINARY_FILE:
@@ -360,7 +427,7 @@ void execute_current_command(void)
if (rc != 3)
{
LOG_ERR("Invalid parameters for PUT_BINARY_FILE command (got %d): '%s'", rc, buffer);
send_error(EINVAL);
send_error(P_ERR_INVALID_PARAMETERS);
break;
}
LOG_DBG("Executing PUT_BINARY_FILE command filename: '%s', filesize: %zd, crc32: 0x%08x", filename, filesize, crc32);
@@ -373,35 +440,40 @@ void execute_current_command(void)
else
{
usb_flush_rx();
send_error(rc);
send_error(protocol_map_error(rc));
}
break;
case CMD_MKDIR:
LOG_DBG("Executing MKDIR command with parameters: '%s'", buffer);
rc = cmd_mkdir((char *)buffer);
if (rc == 0) {
if (rc == 0)
{
send_ok();
}
else {
send_error(rc);
else
{
send_error(protocol_map_error(rc));
}
break;
case CMD_RM:
LOG_DBG("Executing RM command with parameters: '%s'", buffer);
rc = cmd_rm((char *)buffer);
if (rc == 0) {
if (rc == 0)
{
send_ok();
audio_refresh_file_count(); // Nach erfolgreichem Löschen die Anzahl der verfügbaren Audiodateien aktualisieren
}
else {
send_error(rc);
else
{
send_error(protocol_map_error(rc));
}
break;
case CMD_CONFIRM:
LOG_DBG("Executing CONFIRM command");
rc = cmd_confirm_firmware();
if (rc != 0) {
send_error(rc);
if (rc != 0)
{
send_error(protocol_map_error(rc));
break;
}
send_ok();
@@ -409,11 +481,12 @@ void execute_current_command(void)
case CMD_REBOOT:
LOG_DBG("Executing REBOOT command");
rc = cmd_reboot_device();
if (rc != 0) {
send_error(rc);
if (rc != 0)
{
send_error(protocol_map_error(rc));
}
break;
case CMD_PLAY:
case CMD_PLAY:
LOG_DBG("Executing PLAY command");
cmd_play((char *)buffer);
send_ok();
@@ -421,17 +494,18 @@ void execute_current_command(void)
case CMD_CHECK:
LOG_DBG("Executing CHECK command");
rc = cmd_check((char *)buffer);
if (rc == 0) {
if (rc == 0)
{
send_ok();
}
else
{
send_error(rc);
send_error(protocol_map_error(rc));
}
break;
default:
LOG_ERR("No execution logic for command %d", current_command);
send_error(ENOSYS);
send_error(P_ERR_NOT_SUPPORTED);
break;
}
}
@@ -504,7 +578,7 @@ protocol_state_t reading_command(uint8_t byte)
{
LOG_DBG("Unknown command: %s", buffer);
current_command = CMD_INVALID;
send_error(EILSEQ);
send_error(P_ERR_INVALID_COMMAND);
if (byte != '\n' && byte != '\r')
return PS_WAITING_FOR_END_OF_LINE;
return PS_WAITING_FOR_COMMAND;
@@ -531,7 +605,7 @@ protocol_state_t reading_command(uint8_t byte)
}
else
{
send_error(EMSGSIZE);
send_error(P_ERR_COMMAND_TOO_LONG);
return PS_WAITING_FOR_END_OF_LINE;
}
}
@@ -553,7 +627,7 @@ protocol_state_t reading_parameters(uint8_t byte)
if (rx_index >= BUFFER_SIZE)
{
rx_index = 0;
send_error(EMSGSIZE);
send_error(P_ERR_COMMAND_TOO_LONG);
return PS_WAITING_FOR_COMMAND;
}
return PS_READING_PARAMETERS;

View File

@@ -22,4 +22,27 @@ typedef enum {
/* Weitere Kommandos folgen hier */
} protocol_cmd_t;
typedef enum {
P_ERR_NONE = 0x00,
P_ERR_INVALID_COMMAND = 0x01,
P_ERR_INVALID_PARAMETERS = 0x02,
P_ERR_COMMAND_TOO_LONG = 0x03,
P_ERR_FILE_NOT_FOUND = 0x10,
P_ERR_ALREADY_EXISTS = 0x11,
P_ERR_NOT_A_DIRECTORY = 0x12,
P_ERR_IS_A_DIRECTORY = 0x13,
P_ERR_ACCESS_DENIED = 0x14,
P_ERR_NO_SPACE = 0x15,
P_ERR_FILE_TOO_LARGE = 0x16,
P_ERR_IO = 0x20,
P_ERR_TIMEOUT = 0x21,
P_ERR_CRC_MISMATCH = 0x22,
P_ERR_TRANSFER_ABORTED = 0x23,
P_ERR_NOT_SUPPORTED = 0x30,
P_ERR_BUSY = 0x31,
P_ERR_INTERNAL = 0x32,
} protocol_error_t;
#endif // PROTOCOL_H