优化了不必要的任务,待测

This commit is contained in:
CSBOOK\44744
2026-06-26 22:20:39 +08:00
parent 7d915e6fb0
commit 0635bd17f7
6 changed files with 126 additions and 356 deletions
@@ -125,3 +125,4 @@ const char *control_plane_key_event_type_name(control_plane_key_event_type_t typ
esp_err_t control_plane_start_key_input_task(void);
void control_plane_stop_key_input_task(void);
esp_err_t control_plane_schedule_websocket_wait_task(void);
void control_plane_set_ptt_active(bool active);
@@ -35,14 +35,6 @@
#define CONFIG_MULTIMODAL_AUDIO_PREWARM_OPUS_BEFORE_WS 1
#endif
#if defined(CONFIG_MULTIMODAL_AUTO_START_ON_WAKEUP)
#define CONTROL_PLANE_MULTIMODAL_AUTO_START_FLAG CONFIG_MULTIMODAL_AUTO_START_ON_WAKEUP
#elif defined(CONFIG_MULTIMODAL_WS_AUTO_START)
#define CONTROL_PLANE_MULTIMODAL_AUTO_START_FLAG CONFIG_MULTIMODAL_WS_AUTO_START
#else
#define CONTROL_PLANE_MULTIMODAL_AUTO_START_FLAG 0
#endif
#define CONTROL_PLANE_DOWNSTREAM_PLAYBACK_GUARD_MS 220
#define CONTROL_PLANE_IDLE_TRANSPORT_SHUTDOWN_MS 30000
#define CONTROL_PLANE_WATCHDOG_TASK_STACK_SIZE 6144
@@ -60,11 +52,8 @@
static const char *TAG = "control_plane_mm_rt";
static TaskHandle_t s_multimodal_watchdog_task;
static TaskHandle_t s_multimodal_autostart_task;
static bool s_multimodal_watchdog_stop_requested;
static bool s_multimodal_autostart_stop_requested;
static bool s_multimodal_watchdog_task_starting;
static bool s_multimodal_autostart_task_starting;
static bool s_model_command_dispatched;
static bool s_server_success_prompt_played;
static control_plane_model_command_callback_t s_model_command_cb;
@@ -370,104 +359,6 @@ esp_err_t control_plane_multimodal_update_info(
return control_plane_multimodal_send_update_info(request);
}
static void multimodal_autostart_task(void *arg)
{
(void)arg;
TaskHandle_t self = xTaskGetCurrentTaskHandle();
TickType_t wait_step = pdMS_TO_TICKS(200);
TickType_t wait_timeout = pdMS_TO_TICKS(CONFIG_MULTIMODAL_RECONNECT_DELAY_MS + 3000);
if (wait_timeout < pdMS_TO_TICKS(3000)) {
wait_timeout = pdMS_TO_TICKS(3000);
}
TickType_t start_tick = xTaskGetTickCount();
while (!get_multimodal_stop_flag(&s_multimodal_autostart_stop_requested) &&
!control_plane_multimodal_is_connected()) {
if ((xTaskGetTickCount() - start_tick) >= wait_timeout) {
ESP_LOGW(TAG, "Auto Start aborted: transport not ready");
clear_multimodal_task_handle_if_match(&s_multimodal_autostart_task, self);
vTaskDelete(NULL);
return;
}
vTaskDelay(wait_step);
}
for (int attempt = 1;
!get_multimodal_stop_flag(&s_multimodal_autostart_stop_requested) && attempt <= 5 &&
control_plane_multimodal_is_connected();
++attempt) {
esp_err_t err = control_plane_multimodal_send_start();
if (err == ESP_OK) {
break;
}
if (attempt < 5 && control_plane_multimodal_is_connected()) {
ESP_LOGW(TAG,
"Auto Start send failed (%d/5): %s",
attempt,
esp_err_to_name(err));
vTaskDelay(pdMS_TO_TICKS(300));
} else {
ESP_LOGW(TAG, "Auto Start send failed: %s", esp_err_to_name(err));
}
}
clear_multimodal_task_handle_if_match(&s_multimodal_autostart_task, self);
vTaskDelete(NULL);
}
static void stop_autostart_task(void)
{
set_multimodal_stop_flag(&s_multimodal_autostart_stop_requested, true);
if (get_multimodal_task_handle(&s_multimodal_autostart_task) != NULL ||
get_multimodal_start_flag(&s_multimodal_autostart_task_starting)) {
if (!wait_task_exit(&s_multimodal_autostart_task,
&s_multimodal_autostart_task_starting,
800)) {
TaskHandle_t task = get_multimodal_task_handle(&s_multimodal_autostart_task);
if (task != NULL) {
vTaskDelete(task);
}
set_multimodal_task_handle(&s_multimodal_autostart_task, NULL);
}
}
set_multimodal_start_flag(&s_multimodal_autostart_task_starting, false);
set_multimodal_stop_flag(&s_multimodal_autostart_stop_requested, false);
}
static void schedule_autostart_if_enabled(void)
{
if (!CONTROL_PLANE_MULTIMODAL_AUTO_START_FLAG) {
return;
}
if (get_multimodal_task_handle(&s_multimodal_autostart_task) != NULL ||
get_multimodal_start_flag(&s_multimodal_autostart_task_starting)) {
return;
}
if (!try_begin_multimodal_task_start(&s_multimodal_autostart_task,
&s_multimodal_autostart_task_starting)) {
return;
}
set_multimodal_stop_flag(&s_multimodal_autostart_stop_requested, false);
if (xTaskCreatePinnedToCore(multimodal_autostart_task,
"mm_autostart",
6144,
NULL,
4,
&s_multimodal_autostart_task,
CONTROL_PLANE_MULTIMODAL_NETWORK_TASK_CORE) != pdPASS) {
set_multimodal_task_handle(&s_multimodal_autostart_task, NULL);
set_multimodal_start_flag(&s_multimodal_autostart_task_starting, false);
ESP_LOGW(TAG, "Auto Start task create failed");
return;
}
set_multimodal_start_flag(&s_multimodal_autostart_task_starting, false);
}
static void stop_watchdog_task(void)
{
set_multimodal_stop_flag(&s_multimodal_watchdog_stop_requested, true);
@@ -520,7 +411,6 @@ static void multimodal_watchdog_task(void *arg)
"Idle multimodal transport timeout, stopping client after %u ms",
(unsigned)CONTROL_PLANE_IDLE_TRANSPORT_SHUTDOWN_MS);
control_plane_multimodal_stop_uplink();
stop_autostart_task();
control_plane_multimodal_stop();
idle_transport_started_ms = 0U;
}
@@ -599,21 +489,16 @@ static void control_plane_multimodal_event_bridge(control_plane_multimodal_event
if (should_play_prompt) {
(void)domain_runtime_behavior_play_prompt_file(CONTROL_PLANE_SERVER_SUCCESS_PROMPT_FILE);
}
if (CONTROL_PLANE_MULTIMODAL_AUTO_START_FLAG) {
schedule_autostart_if_enabled();
}
break;
}
case CONTROL_PLANE_MULTIMODAL_EVENT_TRANSPORT_DISCONNECTED:
control_plane_multimodal_stop_uplink();
stop_autostart_task();
break;
case CONTROL_PLANE_MULTIMODAL_EVENT_TASK_FAILED:
control_plane_request_server_error_expression(DOMAIN_EXPRESSION_TRIGGER_SERVER_TASK_FAILED);
control_plane_multimodal_stop_uplink();
schedule_autostart_if_enabled();
break;
case CONTROL_PLANE_MULTIMODAL_EVENT_TASK_STARTED:
@@ -701,16 +586,11 @@ esp_err_t control_plane_start_multimodal_client(void)
return err;
}
if (CONTROL_PLANE_MULTIMODAL_AUTO_START_FLAG && control_plane_multimodal_is_connected()) {
schedule_autostart_if_enabled();
}
return ESP_OK;
}
void control_plane_stop_multimodal_client(void)
{
stop_autostart_task();
stop_watchdog_task();
control_plane_multimodal_stop();
}
@@ -20,7 +20,6 @@
#include "freertos/task.h"
#include "sdkconfig.h"
#define CONTROL_PLANE_WS_WAIT_TASK_STACK_SIZE (1024 * 10)
#define CONTROL_PLANE_MODEL_CMD_TASK_STACK_SIZE (1024 * 4)
#define CONTROL_PLANE_DIRECTION_TASK_STACK_SIZE (1024 * 4)
#define CONTROL_PLANE_LCD_RENDER_LOOP_TASK_STACK_SIZE (1024 * 12)
@@ -32,6 +31,7 @@
#define CONTROL_PLANE_TASK_START_GATE_WAIT_MS 5000
#define CONTROL_PLANE_INPUT_BUF_SIZE 64
#define CONTROL_PLANE_WIFI_STATE_POLL_INTERVAL_MS 1000
#define CONTROL_PLANE_PTT_ACTIVE_POLL_INTERVAL_MS 80
#define CONTROL_PLANE_WIFI_DISCONNECTED_REFRESH_MS 5000
#define CONTROL_PLANE_WIFI_DISCONNECT_GRACE_MS 3000
#define CONTROL_PLANE_WIFI_RECONNECT_TIMEOUT_MS 10000
@@ -66,6 +66,10 @@
#define CONFIG_TQ_TASK_MONITOR_ENABLE 0
#endif
#ifndef CONFIG_TQ_DIRECTION_CONSOLE_ENABLE
#define CONFIG_TQ_DIRECTION_CONSOLE_ENABLE 0
#endif
#ifndef CONFIG_TQ_TASK_MONITOR_INTERVAL_MS
#define CONFIG_TQ_TASK_MONITOR_INTERVAL_MS 10000
#endif
@@ -134,9 +138,11 @@ typedef struct {
static QueueHandle_t s_model_cmd_queue;
static bool s_model_cmd_queue_with_caps;
static TaskHandle_t s_model_cmd_task;
static TaskHandle_t s_ws_wait_task;
static bool s_ws_wait_task_starting;
static bool s_ws_start_requested;
static bool s_ptt_active;
#if CONFIG_TQ_DIRECTION_CONSOLE_ENABLE
static TaskHandle_t s_direction_console_task;
#endif
static TaskHandle_t s_lcd_render_loop_task;
static TaskHandle_t s_wifi_state_task;
#if CONFIG_TQ_TASK_MONITOR_ENABLE
@@ -166,6 +172,35 @@ static void control_plane_set_runtime_stop_requested(bool stop_requested)
portEXIT_CRITICAL(&s_runtime_lock);
}
void control_plane_set_ptt_active(bool active)
{
portENTER_CRITICAL(&s_runtime_lock);
s_ptt_active = active;
if (active) {
s_ws_start_requested = true;
}
portEXIT_CRITICAL(&s_runtime_lock);
}
static bool control_plane_get_ptt_active(void)
{
bool active = false;
portENTER_CRITICAL(&s_runtime_lock);
active = s_ptt_active;
portEXIT_CRITICAL(&s_runtime_lock);
return active;
}
static bool control_plane_consume_ws_start_requested(void)
{
bool requested = false;
portENTER_CRITICAL(&s_runtime_lock);
requested = s_ws_start_requested;
s_ws_start_requested = false;
portEXIT_CRITICAL(&s_runtime_lock);
return requested;
}
static TaskHandle_t control_plane_get_task_handle(TaskHandle_t *slot)
{
TaskHandle_t task = NULL;
@@ -184,45 +219,6 @@ static void control_plane_set_task_handle(TaskHandle_t *slot, TaskHandle_t task)
static void control_plane_task_start_gate(void *arg);
static void control_plane_clear_websocket_wait_task_if_match(TaskHandle_t task)
{
portENTER_CRITICAL(&s_runtime_lock);
if (s_ws_wait_task == task) {
s_ws_wait_task = NULL;
}
s_ws_wait_task_starting = false;
portEXIT_CRITICAL(&s_runtime_lock);
}
static bool control_plane_websocket_wait_task_idle(void)
{
bool idle = false;
portENTER_CRITICAL(&s_runtime_lock);
idle = (s_ws_wait_task == NULL && !s_ws_wait_task_starting);
portEXIT_CRITICAL(&s_runtime_lock);
return idle;
}
static bool control_plane_wait_websocket_wait_task_idle(int timeout_ms)
{
if (control_plane_websocket_wait_task_idle()) {
return true;
}
TickType_t timeout_ticks = pdMS_TO_TICKS(timeout_ms > 0 ? timeout_ms : 1);
if (timeout_ticks == 0) {
timeout_ticks = 1;
}
TickType_t start_tick = xTaskGetTickCount();
while (!control_plane_websocket_wait_task_idle() &&
(xTaskGetTickCount() - start_tick) < timeout_ticks) {
vTaskDelay(pdMS_TO_TICKS(20));
}
return control_plane_websocket_wait_task_idle();
}
static QueueHandle_t control_plane_get_model_cmd_queue(void)
{
QueueHandle_t queue = NULL;
@@ -492,6 +488,7 @@ static void control_plane_task_start_gate(void *arg)
control_plane_delete_task(NULL, task_with_caps);
}
#if CONFIG_TQ_DIRECTION_CONSOLE_ENABLE
static void control_plane_print_help(void)
{
printf("\n========================================\n");
@@ -573,6 +570,7 @@ static void control_plane_process_direction_command(char *input)
printf("Type 'help' to list available directions\n");
}
}
#endif
static void control_plane_on_model_command(control_plane_model_command_type_t command_type,
const char *value,
@@ -688,71 +686,14 @@ static void control_plane_model_command_task(void *arg)
return;
}
static void control_plane_websocket_wait_task(void *arg)
{
(void)arg;
TaskHandle_t self = xTaskGetCurrentTaskHandle();
if (!control_plane_runtime_stop_requested()) {
(void)control_plane_register_model_command_callback(control_plane_on_model_command, NULL);
while (!control_plane_runtime_stop_requested()) {
while (!control_plane_runtime_stop_requested() && !control_plane_is_sta_connected()) {
vTaskDelay(pdMS_TO_TICKS(500));
}
if (control_plane_runtime_stop_requested()) {
break;
}
esp_err_t err = control_plane_start_multimodal_client();
if (err == ESP_OK) {
ESP_LOGI(TAG, "Multimodal client started");
break;
}
ESP_LOGW(TAG, "Multimodal client start failed: %s", esp_err_to_name(err));
for (int waited_ms = 0;
waited_ms < CONTROL_PLANE_WS_START_RETRY_DELAY_MS &&
!control_plane_runtime_stop_requested() &&
control_plane_is_sta_connected();
waited_ms += 500) {
vTaskDelay(pdMS_TO_TICKS(500));
}
}
}
control_plane_clear_websocket_wait_task_if_match(self);
return;
}
esp_err_t control_plane_schedule_websocket_wait_task(void)
{
bool should_create = false;
portENTER_CRITICAL(&s_runtime_lock);
if (!s_runtime_stop_requested &&
s_ws_wait_task == NULL &&
!s_ws_wait_task_starting) {
s_ws_wait_task_starting = true;
should_create = true;
if (!s_runtime_stop_requested) {
s_ws_start_requested = true;
}
portEXIT_CRITICAL(&s_runtime_lock);
if (!should_create) {
return ESP_OK;
}
esp_err_t err = control_plane_create_task(control_plane_websocket_wait_task,
"cp_ws_wait",
CONTROL_PLANE_WS_WAIT_TASK_STACK_SIZE,
4,
CONTROL_PLANE_NETWORK_TASK_CORE,
&s_ws_wait_task);
portENTER_CRITICAL(&s_runtime_lock);
s_ws_wait_task_starting = false;
portEXIT_CRITICAL(&s_runtime_lock);
return err;
return ESP_OK;
}
#if CONFIG_TQ_TASK_MONITOR_ENABLE
@@ -878,6 +819,7 @@ static void control_plane_task_monitor_task(void *arg)
}
#endif
#if CONFIG_TQ_DIRECTION_CONSOLE_ENABLE
static void control_plane_direction_console_task(void *arg)
{
(void)arg;
@@ -943,6 +885,7 @@ static void control_plane_direction_console_task(void *arg)
control_plane_set_task_handle(&s_direction_console_task, NULL);
return;
}
#endif
#if CONFIG_TQ_SCREEN_ENABLE
static void control_plane_lcd_render_loop_task(void *arg)
@@ -1041,6 +984,53 @@ static esp_err_t control_plane_ensure_user_config_server(void)
#endif
}
static void control_plane_try_start_multimodal_from_state_machine(TickType_t *last_attempt_tick)
{
TickType_t now = xTaskGetTickCount();
TickType_t retry_ticks = pdMS_TO_TICKS(CONTROL_PLANE_WS_START_RETRY_DELAY_MS);
if (retry_ticks == 0) {
retry_ticks = 1;
}
if (last_attempt_tick != NULL &&
*last_attempt_tick != 0 &&
(now - *last_attempt_tick) < retry_ticks) {
return;
}
if (last_attempt_tick != NULL) {
*last_attempt_tick = now;
}
esp_err_t err = control_plane_start_multimodal_client();
if (err == ESP_OK) {
ESP_LOGI(TAG, "Multimodal client started");
return;
}
ESP_LOGW(TAG, "Multimodal client start failed: %s", esp_err_to_name(err));
}
static void control_plane_drive_ptt_state_machine(void)
{
if (!control_plane_get_ptt_active()) {
return;
}
if (!control_plane_is_sta_connected()) {
return;
}
if (!control_plane_multimodal_is_connected()) {
(void)control_plane_schedule_websocket_wait_task();
}
esp_err_t press_err = control_plane_multimodal_handle_ptt_press_step();
if (press_err != ESP_OK &&
press_err != ESP_ERR_INVALID_STATE &&
press_err != ESP_ERR_NOT_SUPPORTED) {
ESP_LOGW(TAG, "PTT press step failed: %s", esp_err_to_name(press_err));
}
}
static void control_plane_stop_user_config_server(void)
{
#if CONFIG_FORTUNE_ENABLE
@@ -1058,6 +1048,7 @@ static void control_plane_wifi_state_task(void *arg)
(void)arg;
ESP_LOGI(TAG, "Wi-Fi state monitor task started");
(void)control_plane_register_model_command_callback(control_plane_on_model_command, NULL);
const TickType_t poll_ticks = pdMS_TO_TICKS(CONTROL_PLANE_WIFI_STATE_POLL_INTERVAL_MS);
const TickType_t refresh_ticks = pdMS_TO_TICKS(CONTROL_PLANE_WIFI_DISCONNECTED_REFRESH_MS);
@@ -1072,6 +1063,7 @@ static void control_plane_wifi_state_task(void *arg)
TickType_t last_disconnected_request_tick = 0;
TickType_t last_reconnect_attempt_tick = 0;
TickType_t last_user_web_attempt_tick = 0;
TickType_t last_ws_start_attempt_tick = 0;
uint32_t reconnect_delay_ms = CONTROL_PLANE_WIFI_RECONNECT_BASE_DELAY_MS;
bool reconnect_attempted = false;
@@ -1083,6 +1075,7 @@ static void control_plane_wifi_state_task(void *arg)
disconnected_expression_active = true;
last_disconnected_request_tick = xTaskGetTickCount();
} else {
(void)control_plane_schedule_websocket_wait_task();
esp_err_t web_err = control_plane_ensure_user_config_server();
if (web_err != ESP_OK) {
ESP_LOGW(TAG, "Initial user configuration server start failed: %s",
@@ -1092,7 +1085,10 @@ static void control_plane_wifi_state_task(void *arg)
}
while (!control_plane_runtime_stop_requested()) {
vTaskDelay(poll_ticks > 0 ? poll_ticks : 1);
TickType_t next_delay_ticks = control_plane_get_ptt_active() ?
pdMS_TO_TICKS(CONTROL_PLANE_PTT_ACTIVE_POLL_INTERVAL_MS) :
poll_ticks;
vTaskDelay(next_delay_ticks > 0 ? next_delay_ticks : 1);
bool connected = control_plane_is_sta_connected();
TickType_t now_tick = xTaskGetTickCount();
@@ -1165,12 +1161,7 @@ static void control_plane_wifi_state_task(void *arg)
control_plane_request_wifi_state_expression(DOMAIN_EXPRESSION_IDLE,
DOMAIN_EXPRESSION_TRIGGER_WIFI_RECONNECTED,
"Wi-Fi reconnected");
esp_err_t ws_task_err = control_plane_schedule_websocket_wait_task();
if (ws_task_err != ESP_OK) {
ESP_LOGW(TAG,
"Schedule multimodal client restart failed: %s",
esp_err_to_name(ws_task_err));
}
(void)control_plane_schedule_websocket_wait_task();
disconnected_expression_active = false;
disconnect_pending = false;
disconnect_started_tick = 0;
@@ -1185,6 +1176,13 @@ static void control_plane_wifi_state_task(void *arg)
}
if (connected) {
bool ws_start_due = control_plane_consume_ws_start_requested();
if (ws_start_due && !control_plane_multimodal_is_connected()) {
control_plane_try_start_multimodal_from_state_machine(&last_ws_start_attempt_tick);
now_tick = xTaskGetTickCount();
}
control_plane_drive_ptt_state_machine();
TickType_t web_retry_ticks = pdMS_TO_TICKS(CONTROL_PLANE_USER_WEB_RETRY_MS);
if (web_retry_ticks == 0) {
web_retry_ticks = 1;
@@ -1519,14 +1517,9 @@ esp_err_t control_plane_start_runtime_workers(void)
}
}
if (control_plane_get_task_handle(&s_ws_wait_task) == NULL) {
esp_err_t task_err = control_plane_schedule_websocket_wait_task();
if (task_err != ESP_OK) {
control_plane_stop_runtime_workers();
return task_err;
}
}
(void)control_plane_schedule_websocket_wait_task();
#if CONFIG_TQ_DIRECTION_CONSOLE_ENABLE
if (control_plane_get_task_handle(&s_direction_console_task) == NULL) {
esp_err_t task_err = control_plane_create_task(control_plane_direction_console_task,
"cp_direction",
@@ -1539,6 +1532,9 @@ esp_err_t control_plane_start_runtime_workers(void)
return task_err;
}
}
#else
ESP_LOGI(TAG, "Direction console disabled by configuration");
#endif
#if CONFIG_TQ_SCREEN_ENABLE
esp_err_t lcd_worker_err = control_plane_start_lcd_render_worker();
@@ -1667,21 +1663,11 @@ void control_plane_stop_runtime_workers(void)
ESP_LOGW(TAG, "LCD render loop stop ended with %s", esp_err_to_name(lcd_stop_err));
}
if (!control_plane_wait_task_exit(&s_ws_wait_task, CONTROL_PLANE_TASK_STOP_WAIT_MS)) {
control_plane_force_delete_task(&s_ws_wait_task, "cp_ws_wait");
}
if (!control_plane_wait_websocket_wait_task_idle(CONTROL_PLANE_TASK_STOP_WAIT_MS)) {
ESP_LOGW(TAG, "cp_ws_wait start did not quiesce before stop timeout");
portENTER_CRITICAL(&s_runtime_lock);
s_ws_wait_task_starting = false;
portEXIT_CRITICAL(&s_runtime_lock);
if (!control_plane_wait_task_exit(&s_ws_wait_task, CONTROL_PLANE_TASK_STOP_WAIT_MS)) {
control_plane_force_delete_task(&s_ws_wait_task, "cp_ws_wait");
}
}
#if CONFIG_TQ_DIRECTION_CONSOLE_ENABLE
if (!control_plane_wait_task_exit(&s_direction_console_task, CONTROL_PLANE_TASK_STOP_WAIT_MS)) {
control_plane_force_delete_task(&s_direction_console_task, "cp_direction");
}
#endif
if (!control_plane_wait_task_exit(&s_lcd_render_loop_task, CONTROL_PLANE_TASK_STOP_WAIT_MS)) {
control_plane_force_delete_task(&s_lcd_render_loop_task, "cp_lcd_render");
}
@@ -31,9 +31,6 @@
#endif
#define CONTROL_PLANE_PTT_HOLD_STEP_MS 80
#define CONTROL_PLANE_PTT_HOLD_START_DELAY_MS 320
#define CONTROL_PLANE_PTT_HOLD_TASK_STACK 4096
#define CONTROL_PLANE_PTT_HOLD_TASK_PRIORITY 4
#ifndef CONFIG_TQ_LOCAL_TASK_CORE
#define CONFIG_TQ_LOCAL_TASK_CORE 1
@@ -49,9 +46,7 @@ static const char *TAG = "cp_system_event";
static QueueHandle_t s_system_event_queue;
static TaskHandle_t s_system_event_task;
static TaskHandle_t s_ptt_hold_task;
static volatile bool s_stop_requested;
static volatile bool s_ptt_hold_active;
static const char *control_plane_event_family_name(control_plane_event_family_t family)
{
@@ -113,88 +108,6 @@ const char *control_plane_key_event_type_name(control_plane_key_event_type_t typ
}
}
static void control_plane_ptt_hold_task(void *arg)
{
(void)arg;
ESP_LOGI(TAG, "PTT hold task started");
bool start_requested = false;
uint32_t waited_ms = 0;
while (s_ptt_hold_active &&
!s_stop_requested &&
waited_ms < CONTROL_PLANE_PTT_HOLD_START_DELAY_MS) {
vTaskDelay(pdMS_TO_TICKS(CONTROL_PLANE_PTT_HOLD_STEP_MS));
waited_ms += CONTROL_PLANE_PTT_HOLD_STEP_MS;
}
while (s_ptt_hold_active && !s_stop_requested) {
if (!control_plane_is_sta_connected()) {
vTaskDelay(pdMS_TO_TICKS(CONTROL_PLANE_PTT_HOLD_STEP_MS));
continue;
}
if (!control_plane_multimodal_is_connected() && !start_requested) {
esp_err_t schedule_err = control_plane_schedule_websocket_wait_task();
if (schedule_err != ESP_OK && schedule_err != ESP_ERR_INVALID_STATE) {
ESP_LOGW(TAG,
"PTT multimodal start schedule failed: %s",
esp_err_to_name(schedule_err));
} else {
start_requested = true;
}
}
esp_err_t press_err = control_plane_multimodal_handle_ptt_press_step();
if (press_err != ESP_OK &&
press_err != ESP_ERR_INVALID_STATE &&
press_err != ESP_ERR_NOT_SUPPORTED) {
ESP_LOGW(TAG, "PTT press step failed: %s", esp_err_to_name(press_err));
}
vTaskDelay(pdMS_TO_TICKS(CONTROL_PLANE_PTT_HOLD_STEP_MS));
}
ESP_LOGI(TAG, "PTT hold task stopped");
s_ptt_hold_task = NULL;
vTaskDelete(NULL);
}
static esp_err_t control_plane_start_ptt_hold_task(void)
{
s_ptt_hold_active = true;
if (s_ptt_hold_task != NULL) {
return ESP_OK;
}
BaseType_t created = xTaskCreatePinnedToCore(control_plane_ptt_hold_task,
"cp_ptt_hold",
CONTROL_PLANE_PTT_HOLD_TASK_STACK,
NULL,
CONTROL_PLANE_PTT_HOLD_TASK_PRIORITY,
&s_ptt_hold_task,
CONTROL_PLANE_SYSTEM_EVENT_TASK_CORE);
if (created != pdPASS) {
s_ptt_hold_task = NULL;
s_ptt_hold_active = false;
return ESP_ERR_NO_MEM;
}
return ESP_OK;
}
static void control_plane_stop_ptt_hold_task(void)
{
s_ptt_hold_active = false;
for (int i = 0; i < 10 && s_ptt_hold_task != NULL; ++i) {
vTaskDelay(pdMS_TO_TICKS(20));
}
if (s_ptt_hold_task != NULL) {
vTaskDelete(s_ptt_hold_task);
s_ptt_hold_task = NULL;
}
}
static void control_plane_dispatch_key_event(const control_plane_key_event_t *event)
{
if (event == NULL) {
@@ -216,15 +129,12 @@ static void control_plane_dispatch_key_event(const control_plane_key_event_t *ev
switch (event->type) {
case CONTROL_PLANE_KEY_EVENT_PRESSED: {
esp_err_t start_err = control_plane_start_ptt_hold_task();
if (start_err != ESP_OK) {
ESP_LOGW(TAG, "PTT hold task start failed: %s", esp_err_to_name(start_err));
}
control_plane_set_ptt_active(true);
break;
}
case CONTROL_PLANE_KEY_EVENT_RELEASED: {
control_plane_stop_ptt_hold_task();
control_plane_set_ptt_active(false);
esp_err_t release_err = control_plane_multimodal_handle_ptt_release();
if (release_err != ESP_OK && release_err != ESP_ERR_INVALID_STATE) {
ESP_LOGW(TAG, "PTT release failed: %s", esp_err_to_name(release_err));
@@ -352,7 +262,7 @@ void control_plane_stop_system_event_task(void)
{
#if CONFIG_TQ_SYSTEM_EVENT_ENABLE
s_stop_requested = true;
control_plane_stop_ptt_hold_task();
control_plane_set_ptt_active(false);
for (int i = 0; i < 20 && s_system_event_task != NULL; ++i) {
vTaskDelay(pdMS_TO_TICKS(50));