sync
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
#include <fs.h>
|
||||
#include <io.h>
|
||||
|
||||
LOG_MODULE_REGISTER(audio, LOG_LEVEL_DBG);
|
||||
LOG_MODULE_REGISTER(audio, LOG_LEVEL_INF);
|
||||
|
||||
/* Dauer eines Blocks in ms (4096 Bytes / (16kHz * 2 Kanäle * 2 Bytes)) = 64 ms */
|
||||
#define BLOCK_DURATION_MS 64
|
||||
@@ -68,8 +68,8 @@ void i2s_resume(void)
|
||||
|
||||
void audio_refresh_file_count(void)
|
||||
{
|
||||
struct fs_dir_t dirp;
|
||||
struct fs_dirent entry;
|
||||
static struct fs_dir_t dirp;
|
||||
static struct fs_dirent entry;
|
||||
uint32_t count = 0;
|
||||
|
||||
fs_dir_t_init(&dirp);
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#include <zephyr/fs/littlefs.h>
|
||||
#include <zephyr/drivers/flash.h>
|
||||
#include <zephyr/dfu/flash_img.h>
|
||||
#include <zephyr/pm/device.h>
|
||||
#include <fs.h>
|
||||
LOG_MODULE_REGISTER(buzz_fs, LOG_LEVEL_DBG);
|
||||
LOG_MODULE_REGISTER(buzz_fs, LOG_LEVEL_INF);
|
||||
|
||||
#define STORAGE_PARTITION_ID FIXED_PARTITION_ID(littlefs_storage)
|
||||
#define SLOT1_ID FIXED_PARTITION_ID(slot1_partition)
|
||||
|
||||
FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(fs_storage_data);
|
||||
|
||||
#define QSPI_FLASH_NODE DT_ALIAS(qspi_flash)
|
||||
@@ -13,8 +16,11 @@ FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(fs_storage_data);
|
||||
#endif
|
||||
|
||||
static const struct device *flash_dev = DEVICE_DT_GET(QSPI_FLASH_NODE);
|
||||
|
||||
static volatile uint32_t open_count = 0;
|
||||
static struct k_mutex flash_pm_lock;
|
||||
static struct slot_info_t slot1_info;
|
||||
static struct flash_img_context flash_ctx;
|
||||
|
||||
static struct fs_mount_t fs_storage_mnt = {
|
||||
.type = FS_LITTLEFS,
|
||||
@@ -30,6 +36,17 @@ int fs_init(void) {
|
||||
return rc;
|
||||
}
|
||||
k_mutex_init(&flash_pm_lock);
|
||||
|
||||
const struct flash_area *fa;
|
||||
rc = flash_area_open(SLOT1_ID, &fa);
|
||||
if (rc < 0) {
|
||||
LOG_ERR("Error opening flash area for slot 1: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
slot1_info.start_addr = fa->fa_off;
|
||||
slot1_info.size = fa->fa_size;
|
||||
flash_area_close(fa);
|
||||
|
||||
LOG_DBG("Filesystem mounted successfully");
|
||||
return 0;
|
||||
}
|
||||
@@ -128,10 +145,7 @@ int fs_pm_unlink(const char *path)
|
||||
LOG_DBG("PM Unlinking file '%s'", path);
|
||||
fs_pm_flash_resume();
|
||||
int rc = fs_unlink(path);
|
||||
if (rc < 0)
|
||||
{
|
||||
fs_pm_flash_suspend();
|
||||
}
|
||||
fs_pm_flash_suspend();
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -142,4 +156,42 @@ int fs_pm_statvfs(const char *path, struct fs_statvfs *stat)
|
||||
int rc = fs_statvfs(path, stat);
|
||||
fs_pm_flash_suspend();
|
||||
return rc;
|
||||
}
|
||||
|
||||
int fs_pm_mkdir(const char *path)
|
||||
{
|
||||
LOG_DBG("PM Creating directory '%s'", path);
|
||||
fs_pm_flash_resume();
|
||||
int rc = fs_mkdir(path);
|
||||
fs_pm_flash_suspend();
|
||||
return rc;
|
||||
}
|
||||
int flash_get_slot_info(slot_info_t *info) {
|
||||
if (slot1_info.size != 0) {
|
||||
*info = slot1_info;
|
||||
return 0;
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int flash_init_firmware_upload(void) {
|
||||
int rc;
|
||||
|
||||
rc = flash_img_init_id(&flash_ctx, SLOT1_ID);
|
||||
if (rc != 0) {
|
||||
printk("Error initializing flash image: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flash_write_firmware_block(const uint8_t *buffer, size_t length, bool is_last_block) {
|
||||
int rc;
|
||||
rc = flash_img_buffered_write(&flash_ctx, buffer, length, is_last_block);
|
||||
|
||||
if (rc != 0) {
|
||||
printk("Error writing flash image: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -3,6 +3,11 @@
|
||||
|
||||
#include <zephyr/fs/fs.h>
|
||||
|
||||
typedef struct slot_info_t {
|
||||
size_t start_addr;
|
||||
size_t size;
|
||||
} slot_info_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes the filesystem by mounting it
|
||||
*/
|
||||
@@ -68,4 +73,35 @@ int fs_pm_unlink(const char *path);
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
int fs_pm_statvfs(const char *path, struct fs_statvfs *stat);
|
||||
|
||||
/**
|
||||
* @brief Wrapper around fs_mkdir that handles power management for the flash
|
||||
* Resumes the flash before creating the directory and suspends it afterwards
|
||||
* @param path Path to the directory to create
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
int fs_pm_mkdir(const char *path);
|
||||
|
||||
/**
|
||||
* @brief Retrieves information about the firmware slot, such as start address and size
|
||||
* @param info Pointer to slot_info_t structure to be filled with slot information
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
int flash_get_slot_info(slot_info_t *info);
|
||||
|
||||
/**
|
||||
* @brief Initializes the flash for firmware upload, preparing it for receiving new firmware data
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
int flash_init_firmware_upload(void);
|
||||
|
||||
/**
|
||||
* @brief Writes a block of firmware data to the flash
|
||||
* @param buffer Pointer to the data buffer
|
||||
* @param length Length of the data buffer
|
||||
* @param is_last_block Indicates if this is the last block of the firmware
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
int flash_write_firmware_block(const uint8_t *buffer, size_t length, bool is_last_block);
|
||||
|
||||
#endif // FS_H
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <audio.h>
|
||||
|
||||
LOG_MODULE_REGISTER(io, LOG_LEVEL_DBG);
|
||||
LOG_MODULE_REGISTER(io, LOG_LEVEL_INF);
|
||||
|
||||
#define STATUS_LED_NODE DT_ALIAS(status_led)
|
||||
#define USB_LED_NODE DT_ALIAS(usb_led)
|
||||
|
||||
@@ -16,36 +16,9 @@
|
||||
|
||||
LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);
|
||||
|
||||
void print_device_id(void) {
|
||||
uint8_t device_id[8]; // 64 Bit = 8 Bytes
|
||||
ssize_t length;
|
||||
|
||||
// Device ID auslesen
|
||||
length = hwinfo_get_device_id(device_id, sizeof(device_id));
|
||||
|
||||
if (length > 0) {
|
||||
char id_str[17]; // 16 Zeichen + Null-Terminator
|
||||
for (int i = 0; i < length; i++) {
|
||||
sprintf(&id_str[i * 2], "%02x", device_id[i]);
|
||||
}
|
||||
LOG_INF("Board Device ID: %s", id_str);
|
||||
} else {
|
||||
LOG_ERR("Konnte Device ID nicht lesen");
|
||||
}
|
||||
}
|
||||
|
||||
static int print_custom_banner(void)
|
||||
{
|
||||
printk("*** Edis Buzzer Version: " APP_VERSION_STRING " ***" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(print_custom_banner, PRE_KERNEL_1, 0);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
LOG_INF("Starting Edis Buzzer Application");
|
||||
print_device_id();
|
||||
LOG_INF("Starting Edi's Buzzer Application");
|
||||
|
||||
int rc;
|
||||
|
||||
@@ -75,4 +48,10 @@ int main(void)
|
||||
|
||||
LOG_INF("All subsystems initialized. Starting application threads.");
|
||||
audio_system_ready();
|
||||
k_sleep(K_SECONDS(5)); // Kurze Pause, damit die READY-Antworten der Subsysteme noch rausgehen
|
||||
volatile uint32_t *invalid_pointer = (volatile uint32_t *)0xFFFFFFFF;
|
||||
*invalid_pointer = 0xDEADBEEF;
|
||||
while (1) {
|
||||
k_sleep(K_FOREVER);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -13,6 +13,8 @@ typedef enum {
|
||||
CMD_INFO,
|
||||
CMD_LS,
|
||||
CMD_PUT_BINARY_FILE,
|
||||
CMD_MKDIR,
|
||||
CMD_RM,
|
||||
/* Weitere Kommandos folgen hier */
|
||||
} protocol_cmd_t;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user