From ad8bafd9703a222f4c20a40a34c122378bb3f03e Mon Sep 17 00:00:00 2001 From: Sylvain Lefebvre <sylvain.lefebvre@inria.fr> Date: Mon, 9 Oct 2023 09:53:28 +0200 Subject: [PATCH 1/3] Exit main loop upon error in fpga_download --- main/fpga_download.c | 6 +++--- main/include/fpga_download.h | 2 +- main/main.c | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/main/fpga_download.c b/main/fpga_download.c index 83a10f8..b9b061e 100644 --- a/main/fpga_download.c +++ b/main/fpga_download.c @@ -277,7 +277,7 @@ bool fpga_host(xQueueHandle buttonQueue, ICE40* ice40, bool enable_uart, const c } } -void fpga_download(xQueueHandle buttonQueue, ICE40* ice40) { +bool fpga_download(xQueueHandle buttonQueue, ICE40* ice40) { fpga_display_message(0x325aa8, 0xFFFFFFFF, "FPGA download mode\nPreparing..."); ILI9341* ili9341 = get_ili9341(); @@ -315,12 +315,12 @@ void fpga_download(xQueueHandle buttonQueue, ICE40* ice40) { ili9341_init(ili9341); } - return; + return true; error: vTaskDelay(1000 / portTICK_PERIOD_MS); fpga_req_cleanup(); fpga_irq_cleanup(ice40); fpga_uninstall_uart(); - return; + return false; } diff --git a/main/include/fpga_download.h b/main/include/fpga_download.h index 0eda90c..8fade81 100644 --- a/main/include/fpga_download.h +++ b/main/include/fpga_download.h @@ -4,5 +4,5 @@ #include "ice40.h" -void fpga_download(xQueueHandle button_queue, ICE40* ice40); +bool fpga_download(xQueueHandle button_queue, ICE40* ice40); bool fpga_host(xQueueHandle button_queue, ICE40* ice40, bool enable_uart, const char* prefix); diff --git a/main/main.c b/main/main.c index 141a54d..51ecb6e 100644 --- a/main/main.c +++ b/main/main.c @@ -434,7 +434,8 @@ void app_main(void) { } else if (webusb_mode == 0x02) { display_boot_screen("FPGA download mode"); while (true) { - fpga_download(rp2040->queue, ice40); + bool ok = fpga_download(rp2040->queue, ice40); + if (!ok) break; } } else if (webusb_mode == 0x03) { webusb_new_main(rp2040->queue); From 3ef8ad3644c12b57f06c5f1cdbc6ca99cd52116a Mon Sep 17 00:00:00 2001 From: Sylvain Lefebvre <sylvain.lefebvre@inria.fr> Date: Mon, 9 Oct 2023 10:08:11 +0200 Subject: [PATCH 2/3] Add memory allocation failure check for data blocks in fpga_download --- main/fpga_download.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/main/fpga_download.c b/main/fpga_download.c index b9b061e..7863a91 100644 --- a/main/fpga_download.c +++ b/main/fpga_download.c @@ -205,7 +205,11 @@ static bool fpga_uart_download(ICE40* ice40) { case 'D': { // Data block - fpga_req_add_file_data(header.fid, buffer, header.len); + int ret = fpga_req_add_file_data(header.fid, buffer, header.len); + if (ret) { + fpga_display_message(0xa85a32, 0xFFFFFFFF, "FPGA download mode\nUpload failed, out of memory"); + return false; + } break; } From 6c1fc8d78c24686e3fcb30dacaadf5af56eb4be4 Mon Sep 17 00:00:00 2001 From: Sylvain Lefebvre <sylvain.lefebvre@inria.fr> Date: Mon, 9 Oct 2023 10:42:32 +0200 Subject: [PATCH 3/3] Allow data buffer to be captured in req list to avoid double allocation --- main/fpga_download.c | 3 ++- main/fpga_util.c | 26 +++++++++++++++++++------- main/include/fpga_util.h | 2 +- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/main/fpga_download.c b/main/fpga_download.c index 7863a91..b34db3f 100644 --- a/main/fpga_download.c +++ b/main/fpga_download.c @@ -205,7 +205,8 @@ static bool fpga_uart_download(ICE40* ice40) { case 'D': { // Data block - int ret = fpga_req_add_file_data(header.fid, buffer, header.len); + int ret = fpga_req_add_file_data(header.fid, buffer, header.len, true); + buffer = NULL; // Buffer has been captured in req list if (ret) { fpga_display_message(0xa85a32, 0xFFFFFFFF, "FPGA download mode\nUpload failed, out of memory"); return false; diff --git a/main/fpga_util.c b/main/fpga_util.c index ef486f8..87c9c1c 100644 --- a/main/fpga_util.c +++ b/main/fpga_util.c @@ -341,6 +341,7 @@ struct req_entry { void *data; size_t len; size_t ofs; + bool external_data; }; struct req_entry *g_req_entries; @@ -361,6 +362,7 @@ static void _fpga_req_delete_entry(uint32_t fid) { // Release if (re->fh) fclose(re->fh); + if (re->external_data) free(re->data); free(re); // Done @@ -468,6 +470,7 @@ void fpga_req_cleanup(void) { while (re_cur) { re_nxt = re_cur->next; if (re_cur->fh) fclose(re_cur->fh); + if (re_cur->external_data) free(re_cur->data); free(re_cur); re_cur = re_nxt; } @@ -488,7 +491,7 @@ int fpga_req_add_file_alias(uint32_t fid, const char *path) { return 0; } -int fpga_req_add_file_data(uint32_t fid, void *data, size_t len) { +int fpga_req_add_file_data(uint32_t fid, void *data, size_t len,bool capture_buffer) { struct req_entry *re; void *buf; @@ -496,7 +499,11 @@ int fpga_req_add_file_data(uint32_t fid, void *data, size_t len) { _fpga_req_delete_entry(fid); // Alloc new entry - buf = malloc(sizeof(struct req_entry) + len); + if (capture_buffer) { + buf = malloc(sizeof(struct req_entry)); + } else { + buf = malloc(sizeof(struct req_entry) + len); + } if (!buf) return -ENOMEM; re = buf; @@ -508,12 +515,17 @@ int fpga_req_add_file_data(uint32_t fid, void *data, size_t len) { // Init fields re->fid = fid; - re->data = buf + sizeof(struct req_entry); re->len = len; - - // Copy actual data - memcpy(re->data, data, len); - + re->external_data = capture_buffer; + if (capture_buffer) { + // Set data pointer to external buffer + re->data = data; + } else { + // Set data pointer to after record + re->data = buf + sizeof(struct req_entry); + // Copy actual data + memcpy(re->data, data, len); + } // Done return 0; } diff --git a/main/include/fpga_util.h b/main/include/fpga_util.h index 302fa64..da2a81b 100644 --- a/main/include/fpga_util.h +++ b/main/include/fpga_util.h @@ -61,7 +61,7 @@ bool fpga_btn_forward_events(ICE40 *ice40, xQueueHandle buttonQueue, esp_err_t * void fpga_req_setup(void); void fpga_req_cleanup(void); int fpga_req_add_file_alias(uint32_t fid, const char *path); -int fpga_req_add_file_data(uint32_t fid, void *data, size_t len); +int fpga_req_add_file_data(uint32_t fid, void *data, size_t len, bool capture_buffer); void fpga_req_del_file(uint32_t fid); bool fpga_req_process(const char *prefix, ICE40 *ice40, TickType_t wait, esp_err_t *err);