diff --git a/main/control_plane/src/controller_lifecycle.c b/main/control_plane/src/controller_lifecycle.c index d4cf158..1d7c64e 100644 --- a/main/control_plane/src/controller_lifecycle.c +++ b/main/control_plane/src/controller_lifecycle.c @@ -1,6 +1,7 @@ #include "controller_lifecycle.h" #include "esp_log.h" +#include "image_generation.h" #include "printer_protocol.h" #include "rest_server.h" #include "system_runtime.h" @@ -18,6 +19,9 @@ esp_err_t controller_lifecycle_start(void) { ESP_LOGI(TAG, "Starting voice interaction"); ESP_ERROR_CHECK(voice_interaction_init()); + ESP_LOGI(TAG, "Scheduling HTTPS prewarm"); + image_generation_schedule_prewarm(); + ESP_LOGI(TAG, "Starting REST server"); ESP_ERROR_CHECK(rest_server_start()); diff --git a/main/control_plane/src/rest_server.c b/main/control_plane/src/rest_server.c index b76b2e3..501b576 100644 --- a/main/control_plane/src/rest_server.c +++ b/main/control_plane/src/rest_server.c @@ -69,8 +69,9 @@ static const char *s_web_index = " \n" "
\n" " \n" @@ -262,7 +263,7 @@ static const char *s_web_index = "\n" " return {\n" " prompt: mergedPrompt,\n" - " size: imgSizeEl.value || '1120*1440',\n" + " size: imgSizeEl.value || '512*768',\n" " prompt_extend: imgPromptExtendEl.checked,\n" " threshold: toInt(imgThresholdEl.value, 160, 0, 255),\n" " max_height: toInt(imgMaxHeightEl.value, 2200, 64, 3000),\n" @@ -369,6 +370,11 @@ esp_err_t rest_server_start(void) { config.uri_match_fn = httpd_uri_match_wildcard; config.max_uri_handlers = 32; config.stack_size = 10240; +#if CONFIG_FREERTOS_UNICORE + config.core_id = 0; +#else + config.core_id = 1; +#endif esp_err_t err = httpd_start(&s_server, &config); if (err != ESP_OK) { diff --git a/main/control_plane/src/rest_server_print_image.c b/main/control_plane/src/rest_server_print_image.c index e785d9d..e231a76 100644 --- a/main/control_plane/src/rest_server_print_image.c +++ b/main/control_plane/src/rest_server_print_image.c @@ -7,6 +7,7 @@ #include "esp_log.h" #include "image_generation.h" +#include "printer_protocol.h" #include "raster_tools.h" static const char *TAG = "rest_print"; @@ -410,6 +411,7 @@ static esp_err_t rest_server_print_image_generate(httpd_req_t *req) { image_generation_result_t *gen_result = NULL; uint8_t *raster = NULL; char request_id[80] = {0}; + bool status_poll_paused = false; esp_err_t ret = ESP_FAIL; esp_err_t body_err = rest_server_read_body(req, &body); @@ -473,10 +475,14 @@ static esp_err_t rest_server_print_image_generate(httpd_req_t *req) { image_generation_result_reset(gen_result); char model_err[160] = {0}; + printer_protocol_set_status_poll_paused(true); + status_poll_paused = true; esp_err_t gen_rc = image_generation_generate_png(&gen_req, gen_result, model_err, sizeof(model_err)); + printer_protocol_set_status_poll_paused(false); + status_poll_paused = false; if (gen_rc != ESP_OK) { ESP_LOGW(TAG, "image generate failed, rc=0x%x, msg=%s", @@ -545,6 +551,9 @@ static esp_err_t rest_server_print_image_generate(httpd_req_t *req) { request_id); cleanup: + if (status_poll_paused) { + printer_protocol_set_status_poll_paused(false); + } if (body != NULL) { free(body); } @@ -558,6 +567,11 @@ cleanup: image_generation_result_free(gen_result); free(gen_result); } + printer_runtime_status_t runtime = {0}; + printer_protocol_get_runtime_status(&runtime); + if (!runtime.busy) { + image_generation_schedule_prewarm(); + } return ret; } diff --git a/main/domain/include/image_generation.h b/main/domain/include/image_generation.h index 6a58c11..175e223 100644 --- a/main/domain/include/image_generation.h +++ b/main/domain/include/image_generation.h @@ -28,6 +28,7 @@ typedef struct { void image_generation_result_reset(image_generation_result_t *result); void image_generation_result_free(image_generation_result_t *result); +void image_generation_schedule_prewarm(void); esp_err_t image_generation_generate_png(const image_generation_request_t *req, image_generation_result_t *out_result, diff --git a/main/domain/include/printer_protocol.h b/main/domain/include/printer_protocol.h index 6e82d8a..14b1252 100644 --- a/main/domain/include/printer_protocol.h +++ b/main/domain/include/printer_protocol.h @@ -53,6 +53,7 @@ esp_err_t printer_protocol_connect(const char *target_name, uint32_t timeout_ms) void printer_protocol_disconnect(void); void printer_protocol_get_runtime_status(printer_runtime_status_t *out_status); +void printer_protocol_set_status_poll_paused(bool paused); esp_err_t printer_protocol_submit_raster_job(const uint8_t *raster, size_t raster_len, diff --git a/main/domain/src/printer_protocol.c b/main/domain/src/printer_protocol.c index a920de0..5eff99b 100644 --- a/main/domain/src/printer_protocol.c +++ b/main/domain/src/printer_protocol.c @@ -15,6 +15,7 @@ QueueHandle_t s_job_queue; EventGroupHandle_t s_evt; uint32_t s_busy_refcnt; +static bool s_status_poll_paused; parsed_status_t s_status = { .has_paper = true, @@ -32,6 +33,23 @@ job_slot_t s_jobs[JOB_SLOT_MAX]; static const char *TAG = "printer_protocol"; +#if CONFIG_FREERTOS_UNICORE +#define PRINT_WORKER_CORE_ID 0 +#else +#define PRINT_WORKER_CORE_ID 1 +#endif + +void printer_protocol_set_status_poll_paused(bool paused) { + if (s_mutex == NULL) { + return; + } + if (xSemaphoreTake(s_mutex, pdMS_TO_TICKS(200)) != pdTRUE) { + return; + } + s_status_poll_paused = paused; + xSemaphoreGive(s_mutex); +} + bool printer_protocol_acquire_control_lane(uint32_t timeout_ms, char *err, size_t err_len) { if (xSemaphoreTake(s_mutex, pdMS_TO_TICKS(timeout_ms)) != pdTRUE) { if (err != NULL && err_len > 0) { @@ -232,7 +250,7 @@ static void status_poll_task(void *arg) { while (true) { bool can_poll = false; if (xSemaphoreTake(s_mutex, pdMS_TO_TICKS(50)) == pdTRUE) { - can_poll = (s_busy_refcnt == 0); + can_poll = (s_busy_refcnt == 0) && !s_status_poll_paused; xSemaphoreGive(s_mutex); } @@ -314,12 +332,24 @@ esp_err_t printer_protocol_init(void) { return err; } - BaseType_t ok = xTaskCreate(printer_protocol_worker_task, "print_worker", 6144, NULL, 6, NULL); + BaseType_t ok = xTaskCreatePinnedToCore(printer_protocol_worker_task, + "print_worker", + 6144, + NULL, + 6, + NULL, + PRINT_WORKER_CORE_ID); if (ok != pdPASS) { return ESP_ERR_NO_MEM; } - ok = xTaskCreate(status_poll_task, "status_poll", 4096, NULL, 4, NULL); + ok = xTaskCreatePinnedToCore(status_poll_task, + "status_poll", + 4096, + NULL, + 4, + NULL, + PRINT_WORKER_CORE_ID); if (ok != pdPASS) { return ESP_ERR_NO_MEM; } diff --git a/main/platform/src/ble_printer_client.c b/main/platform/src/ble_printer_client.c index d1fe646..fd4787e 100644 --- a/main/platform/src/ble_printer_client.c +++ b/main/platform/src/ble_printer_client.c @@ -519,6 +519,11 @@ static void nimble_host_task(void *param) { esp_err_t ble_printer_client_init(ble_frame_rx_cb_t rx_cb) { s_rx_cb = rx_cb; + // NimBLE emits very chatty INFO logs during each chunk write. + // Lowering these logs reduces serial I/O overhead and improves runtime smoothness. + esp_log_level_set("NimBLE", ESP_LOG_WARN); + esp_log_level_set("BLE_INIT", ESP_LOG_WARN); + s_evt_group = xEventGroupCreate(); if (s_evt_group == NULL) { return ESP_ERR_NO_MEM;