feat(control_plane): add light standby coordinator

This commit is contained in:
chenjintao
2026-08-21 11:35:52 +08:00
parent 988dc924b9
commit 6a11aca835
9 changed files with 559 additions and 0 deletions
+1
View File
@@ -13,6 +13,7 @@ idf_component_register(
"src/runtime/control_plane_connectivity_runtime.c" "src/runtime/control_plane_connectivity_runtime.c"
"src/runtime/control_plane_fortune_service.c" "src/runtime/control_plane_fortune_service.c"
"src/runtime/control_plane_system_events.c" "src/runtime/control_plane_system_events.c"
"src/runtime/control_plane_light_standby.c"
"src/runtime/control_plane_key_input.c" "src/runtime/control_plane_key_input.c"
"src/runtime/control_plane_reset_service.c" "src/runtime/control_plane_reset_service.c"
"src/runtime/control_plane_remote_log_service.c" "src/runtime/control_plane_remote_log_service.c"
@@ -8,6 +8,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
#include "esp_err.h" #include "esp_err.h"
#ifdef __cplusplus #ifdef __cplusplus
@@ -89,6 +90,35 @@ typedef struct {
esp_err_t last_error; esp_err_t last_error;
} control_plane_ota_snapshot_t; } control_plane_ota_snapshot_t;
typedef enum {
CONTROL_PLANE_LIGHT_STANDBY_STATE_DISABLED = 0,
CONTROL_PLANE_LIGHT_STANDBY_STATE_ACTIVE,
CONTROL_PLANE_LIGHT_STANDBY_STATE_ENTERING,
CONTROL_PLANE_LIGHT_STANDBY_STATE_STANDBY,
CONTROL_PLANE_LIGHT_STANDBY_STATE_WAKING,
CONTROL_PLANE_LIGHT_STANDBY_STATE_STOPPED,
} control_plane_light_standby_state_t;
typedef enum {
CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_UNSPECIFIED = 0,
CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_KEY,
CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_LOCAL_WAKE,
CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_VOICE_INPUT,
CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_VOICE_OUTPUT,
CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_MODEL_COMMAND,
CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_EXTERNAL,
} control_plane_light_standby_activity_t;
typedef struct {
control_plane_light_standby_state_t state;
control_plane_light_standby_activity_t last_activity;
bool running;
uint32_t idle_timeout_ms;
uint64_t last_activity_ms;
uint64_t standby_since_ms;
uint32_t transition_count;
} control_plane_light_standby_snapshot_t;
esp_err_t control_plane_init(void); esp_err_t control_plane_init(void);
/** /**
@@ -109,6 +139,38 @@ esp_err_t control_plane_battery_service_start(void);
*/ */
esp_err_t control_plane_prepare_runtime_storage(void); esp_err_t control_plane_prepare_runtime_storage(void);
/**
* @brief Start the control-plane owned light-standby coordinator.
*
* The coordinator tracks one inactivity deadline for the full runtime. Phase
* one records state transitions only; hardware power policies are attached in
* later phases. Repeated starts are idempotent.
*/
esp_err_t control_plane_light_standby_start(void);
/**
* @brief Stop the light-standby coordinator with bounded teardown.
*
* Zero requests asynchronous stop. Positive values wait up to the supplied
* timeout and apply deterministic task teardown if necessary.
*/
esp_err_t control_plane_light_standby_stop(int timeout_ms);
/**
* @brief Record user activity and return the coordinator to ACTIVE state.
*
* This call is non-blocking and safe from control-plane worker tasks. It must
* not be called directly from an ISR.
*/
esp_err_t control_plane_light_standby_record_activity(
control_plane_light_standby_activity_t activity);
/**
* @brief Copy the current light-standby state snapshot.
*/
esp_err_t control_plane_light_standby_get_snapshot(
control_plane_light_standby_snapshot_t *out_snapshot);
/** /**
* @brief Parse one direction command without side effects. * @brief Parse one direction command without side effects.
* *
@@ -322,6 +322,8 @@ static void local_wake_handle_detection(
(unsigned)event->confidence_x10000, (unsigned)event->confidence_x10000,
(unsigned)event->detection_generation); (unsigned)event->detection_generation);
(void)control_plane_light_standby_record_activity(
CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_LOCAL_WAKE);
control_plane_set_ptt_active_from_local_wake(); control_plane_set_ptt_active_from_local_wake();
} }
@@ -870,6 +870,21 @@ static void control_plane_multimodal_event_bridge(control_plane_multimodal_event
{ {
(void)user_data; (void)user_data;
switch (event) {
case CONTROL_PLANE_MULTIMODAL_EVENT_SPEECH_STARTED:
case CONTROL_PLANE_MULTIMODAL_EVENT_SPEECH_ENDED:
(void)control_plane_light_standby_record_activity(
CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_VOICE_INPUT);
break;
case CONTROL_PLANE_MULTIMODAL_EVENT_RESPONDING_STARTED:
case CONTROL_PLANE_MULTIMODAL_EVENT_RESPONDING_ENDED:
(void)control_plane_light_standby_record_activity(
CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_VOICE_OUTPUT);
break;
default:
break;
}
switch (event) { switch (event) {
case CONTROL_PLANE_MULTIMODAL_EVENT_TRANSPORT_CONNECTED: { case CONTROL_PLANE_MULTIMODAL_EVENT_TRANSPORT_CONNECTED: {
control_plane_schedule_server_success_prompt(); control_plane_schedule_server_success_prompt();
@@ -0,0 +1,429 @@
/*
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "control_plane_internal.h"
#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include "esp_log.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "sdkconfig.h"
#ifndef CONFIG_TQ_LIGHT_STANDBY_ENABLE
#define CONFIG_TQ_LIGHT_STANDBY_ENABLE 0
#endif
#ifndef CONFIG_TQ_LIGHT_STANDBY_IDLE_TIMEOUT_MS
#define CONFIG_TQ_LIGHT_STANDBY_IDLE_TIMEOUT_MS 300000
#endif
#ifndef CONFIG_TQ_LIGHT_STANDBY_TASK_STACK_BYTES
#define CONFIG_TQ_LIGHT_STANDBY_TASK_STACK_BYTES 3072
#endif
#ifndef CONFIG_TQ_LIGHT_STANDBY_TASK_PRIORITY
#define CONFIG_TQ_LIGHT_STANDBY_TASK_PRIORITY 3
#endif
#ifndef CONFIG_TQ_LOCAL_TASK_CORE
#define CONFIG_TQ_LOCAL_TASK_CORE 1
#endif
#define CONTROL_PLANE_LIGHT_STANDBY_ELIGIBILITY_RECHECK_MS 1000U
#define CONTROL_PLANE_LIGHT_STANDBY_STOP_POLL_MS 20U
#if CONFIG_TQ_LOCAL_TASK_CORE < 0
#define CONTROL_PLANE_LIGHT_STANDBY_TASK_CORE tskNO_AFFINITY
#else
#define CONTROL_PLANE_LIGHT_STANDBY_TASK_CORE ((BaseType_t)CONFIG_TQ_LOCAL_TASK_CORE)
#endif
typedef struct {
TaskHandle_t task;
control_plane_light_standby_state_t state;
control_plane_light_standby_activity_t last_activity;
bool running;
bool stop_requested;
uint64_t last_activity_ms;
uint64_t standby_since_ms;
uint32_t transition_count;
} control_plane_light_standby_runtime_t;
static const char *TAG = "cp_light_standby";
static control_plane_light_standby_runtime_t s_standby;
static portMUX_TYPE s_standby_lock = portMUX_INITIALIZER_UNLOCKED;
static uint64_t control_plane_light_standby_now_ms(void)
{
return (uint64_t)(esp_timer_get_time() / 1000);
}
static const char *control_plane_light_standby_state_name(
control_plane_light_standby_state_t state)
{
switch (state) {
case CONTROL_PLANE_LIGHT_STANDBY_STATE_DISABLED:
return "DISABLED";
case CONTROL_PLANE_LIGHT_STANDBY_STATE_ACTIVE:
return "ACTIVE";
case CONTROL_PLANE_LIGHT_STANDBY_STATE_ENTERING:
return "ENTERING";
case CONTROL_PLANE_LIGHT_STANDBY_STATE_STANDBY:
return "STANDBY";
case CONTROL_PLANE_LIGHT_STANDBY_STATE_WAKING:
return "WAKING";
case CONTROL_PLANE_LIGHT_STANDBY_STATE_STOPPED:
return "STOPPED";
default:
return "UNKNOWN";
}
}
static const char *control_plane_light_standby_activity_name(
control_plane_light_standby_activity_t activity)
{
switch (activity) {
case CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_KEY:
return "key";
case CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_LOCAL_WAKE:
return "local_wake";
case CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_VOICE_INPUT:
return "voice_input";
case CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_VOICE_OUTPUT:
return "voice_output";
case CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_MODEL_COMMAND:
return "model_command";
case CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_EXTERNAL:
return "external";
case CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_UNSPECIFIED:
default:
return "unspecified";
}
}
static void control_plane_light_standby_log_transition(
control_plane_light_standby_state_t from,
control_plane_light_standby_state_t to,
const char *reason)
{
ESP_LOGI(TAG,
"State %s -> %s reason=%s",
control_plane_light_standby_state_name(from),
control_plane_light_standby_state_name(to),
reason != NULL ? reason : "-");
}
static bool control_plane_light_standby_runtime_is_eligible(void)
{
if (!control_plane_voice_turn_is_idle() ||
!control_plane_ota_voice_services_allowed() ||
control_plane_is_mini_program_provisioning_running()) {
return false;
}
control_plane_multimodal_runtime_state_t state = {0};
if (control_plane_multimodal_get_runtime_state(&state) != ESP_OK) {
return true;
}
return !state.remote_responding &&
!state.client_speech_active &&
!state.request_to_speak_pending &&
!state.response_pending &&
!state.local_responding_started;
}
static void control_plane_light_standby_enter(uint64_t now_ms)
{
control_plane_light_standby_state_t from = CONTROL_PLANE_LIGHT_STANDBY_STATE_ACTIVE;
bool entering = false;
portENTER_CRITICAL(&s_standby_lock);
if (s_standby.running && !s_standby.stop_requested &&
s_standby.state == CONTROL_PLANE_LIGHT_STANDBY_STATE_ACTIVE &&
(now_ms - s_standby.last_activity_ms) >=
(uint64_t)CONFIG_TQ_LIGHT_STANDBY_IDLE_TIMEOUT_MS) {
from = s_standby.state;
s_standby.state = CONTROL_PLANE_LIGHT_STANDBY_STATE_ENTERING;
s_standby.transition_count++;
entering = true;
}
portEXIT_CRITICAL(&s_standby_lock);
if (!entering) {
return;
}
control_plane_light_standby_log_transition(from,
CONTROL_PLANE_LIGHT_STANDBY_STATE_ENTERING,
"idle_timeout");
bool entered = false;
portENTER_CRITICAL(&s_standby_lock);
if (s_standby.state == CONTROL_PLANE_LIGHT_STANDBY_STATE_ENTERING &&
!s_standby.stop_requested) {
s_standby.state = CONTROL_PLANE_LIGHT_STANDBY_STATE_STANDBY;
s_standby.standby_since_ms = now_ms;
s_standby.transition_count++;
entered = true;
}
portEXIT_CRITICAL(&s_standby_lock);
if (entered) {
control_plane_light_standby_log_transition(
CONTROL_PLANE_LIGHT_STANDBY_STATE_ENTERING,
CONTROL_PLANE_LIGHT_STANDBY_STATE_STANDBY,
"phase1_state_only");
}
}
static void control_plane_light_standby_task(void *arg)
{
(void)arg;
ESP_LOGI(TAG,
"Coordinator started idle_timeout_ms=%u",
(unsigned)CONFIG_TQ_LIGHT_STANDBY_IDLE_TIMEOUT_MS);
while (true) {
uint64_t last_activity_ms = 0U;
bool stop_requested = false;
control_plane_light_standby_state_t state =
CONTROL_PLANE_LIGHT_STANDBY_STATE_STOPPED;
portENTER_CRITICAL(&s_standby_lock);
last_activity_ms = s_standby.last_activity_ms;
stop_requested = s_standby.stop_requested;
state = s_standby.state;
portEXIT_CRITICAL(&s_standby_lock);
if (stop_requested) {
break;
}
if (state == CONTROL_PLANE_LIGHT_STANDBY_STATE_STANDBY) {
(void)ulTaskNotifyTake(
pdTRUE,
pdMS_TO_TICKS(CONFIG_TQ_LIGHT_STANDBY_IDLE_TIMEOUT_MS));
continue;
}
uint64_t now_ms = control_plane_light_standby_now_ms();
uint64_t idle_ms = now_ms - last_activity_ms;
if (idle_ms >= (uint64_t)CONFIG_TQ_LIGHT_STANDBY_IDLE_TIMEOUT_MS) {
if (control_plane_light_standby_runtime_is_eligible()) {
control_plane_light_standby_enter(now_ms);
}
(void)ulTaskNotifyTake(
pdTRUE,
pdMS_TO_TICKS(CONTROL_PLANE_LIGHT_STANDBY_ELIGIBILITY_RECHECK_MS));
continue;
}
uint64_t remaining_ms =
(uint64_t)CONFIG_TQ_LIGHT_STANDBY_IDLE_TIMEOUT_MS - idle_ms;
TickType_t wait_ticks = pdMS_TO_TICKS((uint32_t)remaining_ms);
if (wait_ticks == 0U) {
wait_ticks = 1U;
}
(void)ulTaskNotifyTake(pdTRUE, wait_ticks);
}
portENTER_CRITICAL(&s_standby_lock);
s_standby.task = NULL;
s_standby.running = false;
s_standby.state = CONTROL_PLANE_LIGHT_STANDBY_STATE_STOPPED;
s_standby.transition_count++;
portEXIT_CRITICAL(&s_standby_lock);
ESP_LOGI(TAG, "Coordinator stopped");
vTaskDelete(NULL);
}
esp_err_t control_plane_light_standby_start(void)
{
#if !CONFIG_TQ_LIGHT_STANDBY_ENABLE
return ESP_ERR_NOT_SUPPORTED;
#else
uint64_t now_ms = control_plane_light_standby_now_ms();
portENTER_CRITICAL(&s_standby_lock);
if (s_standby.running) {
portEXIT_CRITICAL(&s_standby_lock);
return ESP_OK;
}
s_standby.state = CONTROL_PLANE_LIGHT_STANDBY_STATE_ACTIVE;
s_standby.last_activity = CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_UNSPECIFIED;
s_standby.running = true;
s_standby.stop_requested = false;
s_standby.last_activity_ms = now_ms;
s_standby.standby_since_ms = 0U;
s_standby.transition_count = 0U;
portEXIT_CRITICAL(&s_standby_lock);
TaskHandle_t task = NULL;
BaseType_t created = xTaskCreatePinnedToCore(
control_plane_light_standby_task,
"cp_light_standby",
CONFIG_TQ_LIGHT_STANDBY_TASK_STACK_BYTES,
NULL,
CONFIG_TQ_LIGHT_STANDBY_TASK_PRIORITY,
&task,
CONTROL_PLANE_LIGHT_STANDBY_TASK_CORE);
if (created != pdPASS) {
portENTER_CRITICAL(&s_standby_lock);
s_standby.running = false;
s_standby.state = CONTROL_PLANE_LIGHT_STANDBY_STATE_STOPPED;
portEXIT_CRITICAL(&s_standby_lock);
return ESP_ERR_NO_MEM;
}
portENTER_CRITICAL(&s_standby_lock);
s_standby.task = task;
portEXIT_CRITICAL(&s_standby_lock);
return ESP_OK;
#endif
}
esp_err_t control_plane_light_standby_stop(int timeout_ms)
{
if (timeout_ms < 0) {
return ESP_ERR_INVALID_ARG;
}
#if !CONFIG_TQ_LIGHT_STANDBY_ENABLE
return ESP_OK;
#else
TaskHandle_t task = NULL;
portENTER_CRITICAL(&s_standby_lock);
if (!s_standby.running) {
portEXIT_CRITICAL(&s_standby_lock);
return ESP_OK;
}
s_standby.stop_requested = true;
task = s_standby.task;
portEXIT_CRITICAL(&s_standby_lock);
if (task != NULL) {
xTaskNotifyGive(task);
}
if (timeout_ms == 0) {
return ESP_OK;
}
uint64_t deadline_ms = control_plane_light_standby_now_ms() + (uint64_t)timeout_ms;
while (control_plane_light_standby_now_ms() < deadline_ms) {
bool running = false;
portENTER_CRITICAL(&s_standby_lock);
running = s_standby.running;
portEXIT_CRITICAL(&s_standby_lock);
if (!running) {
return ESP_OK;
}
vTaskDelay(pdMS_TO_TICKS(CONTROL_PLANE_LIGHT_STANDBY_STOP_POLL_MS));
}
portENTER_CRITICAL(&s_standby_lock);
task = s_standby.task;
s_standby.task = NULL;
s_standby.running = false;
s_standby.state = CONTROL_PLANE_LIGHT_STANDBY_STATE_STOPPED;
s_standby.transition_count++;
portEXIT_CRITICAL(&s_standby_lock);
if (task != NULL) {
ESP_LOGW(TAG, "Coordinator stop timed out; forcing task teardown");
vTaskDelete(task);
}
return ESP_ERR_TIMEOUT;
#endif
}
esp_err_t control_plane_light_standby_record_activity(
control_plane_light_standby_activity_t activity)
{
if (activity <= CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_UNSPECIFIED ||
activity > CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_EXTERNAL) {
return ESP_ERR_INVALID_ARG;
}
#if !CONFIG_TQ_LIGHT_STANDBY_ENABLE
return ESP_ERR_NOT_SUPPORTED;
#else
control_plane_light_standby_state_t from = CONTROL_PLANE_LIGHT_STANDBY_STATE_ACTIVE;
TaskHandle_t task = NULL;
bool waking = false;
uint64_t now_ms = control_plane_light_standby_now_ms();
portENTER_CRITICAL(&s_standby_lock);
if (!s_standby.running || s_standby.stop_requested) {
portEXIT_CRITICAL(&s_standby_lock);
return ESP_ERR_INVALID_STATE;
}
s_standby.last_activity = activity;
s_standby.last_activity_ms = now_ms;
task = s_standby.task;
if (s_standby.state == CONTROL_PLANE_LIGHT_STANDBY_STATE_STANDBY ||
s_standby.state == CONTROL_PLANE_LIGHT_STANDBY_STATE_ENTERING) {
from = s_standby.state;
s_standby.state = CONTROL_PLANE_LIGHT_STANDBY_STATE_WAKING;
s_standby.transition_count++;
waking = true;
}
portEXIT_CRITICAL(&s_standby_lock);
if (waking) {
const char *reason = control_plane_light_standby_activity_name(activity);
control_plane_light_standby_log_transition(
from,
CONTROL_PLANE_LIGHT_STANDBY_STATE_WAKING,
reason);
bool activated = false;
portENTER_CRITICAL(&s_standby_lock);
if (s_standby.state == CONTROL_PLANE_LIGHT_STANDBY_STATE_WAKING) {
s_standby.state = CONTROL_PLANE_LIGHT_STANDBY_STATE_ACTIVE;
s_standby.standby_since_ms = 0U;
s_standby.transition_count++;
activated = true;
}
portEXIT_CRITICAL(&s_standby_lock);
if (activated) {
control_plane_light_standby_log_transition(
CONTROL_PLANE_LIGHT_STANDBY_STATE_WAKING,
CONTROL_PLANE_LIGHT_STANDBY_STATE_ACTIVE,
reason);
}
}
if (task != NULL) {
xTaskNotifyGive(task);
}
return ESP_OK;
#endif
}
esp_err_t control_plane_light_standby_get_snapshot(
control_plane_light_standby_snapshot_t *out_snapshot)
{
if (out_snapshot == NULL) {
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL(&s_standby_lock);
#if CONFIG_TQ_LIGHT_STANDBY_ENABLE
*out_snapshot = (control_plane_light_standby_snapshot_t) {
.state = s_standby.state,
.last_activity = s_standby.last_activity,
.running = s_standby.running,
.idle_timeout_ms = CONFIG_TQ_LIGHT_STANDBY_IDLE_TIMEOUT_MS,
.last_activity_ms = s_standby.last_activity_ms,
.standby_since_ms = s_standby.standby_since_ms,
.transition_count = s_standby.transition_count,
};
#else
*out_snapshot = (control_plane_light_standby_snapshot_t) {
.state = CONTROL_PLANE_LIGHT_STANDBY_STATE_DISABLED,
};
#endif
portEXIT_CRITICAL(&s_standby_lock);
return ESP_OK;
}
@@ -1212,6 +1212,9 @@ static void control_plane_model_command_task(void *arg)
break; break;
} }
(void)control_plane_light_standby_record_activity(
CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_MODEL_COMMAND);
if (cmd.command_type == CONTROL_PLANE_MODEL_COMMAND_DIRECTION) { if (cmd.command_type == CONTROL_PLANE_MODEL_COMMAND_DIRECTION) {
size_t direction_index = 0; size_t direction_index = 0;
control_plane_direction_command_t parsed = control_plane_parse_direction_command(cmd.value, control_plane_direction_command_t parsed = control_plane_parse_direction_command(cmd.value,
@@ -2536,6 +2539,12 @@ esp_err_t control_plane_start_runtime_workers(void)
return system_event_err; return system_event_err;
} }
esp_err_t standby_err = control_plane_light_standby_start();
if (standby_err != ESP_OK && standby_err != ESP_ERR_NOT_SUPPORTED) {
control_plane_stop_runtime_workers();
return standby_err;
}
esp_err_t key_input_err = control_plane_start_key_input_task(); esp_err_t key_input_err = control_plane_start_key_input_task();
if (key_input_err != ESP_OK) { if (key_input_err != ESP_OK) {
control_plane_stop_runtime_workers(); control_plane_stop_runtime_workers();
@@ -2620,6 +2629,7 @@ void control_plane_stop_event_observer_runtime(void)
void control_plane_stop_runtime_workers(void) void control_plane_stop_runtime_workers(void)
{ {
control_plane_set_runtime_stop_requested(true); control_plane_set_runtime_stop_requested(true);
(void)control_plane_light_standby_stop(CONTROL_PLANE_TASK_STOP_WAIT_MS);
(void)control_plane_battery_service_stop(CONTROL_PLANE_TASK_STOP_WAIT_MS); (void)control_plane_battery_service_stop(CONTROL_PLANE_TASK_STOP_WAIT_MS);
(void)control_plane_stop_ota_service(CONFIG_TQ_LOCAL_WAKE_STOP_WAIT_MS); (void)control_plane_stop_ota_service(CONFIG_TQ_LOCAL_WAKE_STOP_WAIT_MS);
(void)control_plane_stop_mini_program_provisioning( (void)control_plane_stop_mini_program_provisioning(
@@ -130,6 +130,9 @@ static void control_plane_dispatch_key_event(const control_plane_key_event_t *ev
event->press_duration_ms, event->press_duration_ms,
event->click_count); event->click_count);
(void)control_plane_light_standby_record_activity(
CONTROL_PLANE_LIGHT_STANDBY_ACTIVITY_KEY);
if (event->key_id == CONTROL_PLANE_KEY_ID_RESET) { if (event->key_id == CONTROL_PLANE_KEY_ID_RESET) {
if (event->type == CONTROL_PLANE_KEY_EVENT_LONG_PRESS_START) { if (event->type == CONTROL_PLANE_KEY_EVENT_LONG_PRESS_START) {
control_plane_reset_wifi_provisioning_and_restart(); control_plane_reset_wifi_provisioning_and_restart();
+33
View File
@@ -323,6 +323,39 @@ menu "Example Configuration"
help help
Stack size in bytes for the control-plane system event task. Stack size in bytes for the control-plane system event task.
menu "Light Standby"
config TQ_LIGHT_STANDBY_ENABLE
bool "Enable light-standby state coordinator"
default y
help
Track a single device-wide inactivity deadline and expose
ACTIVE, ENTERING, STANDBY, and WAKING states. Hardware power
actions are attached to these transitions separately.
config TQ_LIGHT_STANDBY_IDLE_TIMEOUT_MS
int "Light-standby inactivity timeout (ms)"
default 300000
range 1000 3600000
depends on TQ_LIGHT_STANDBY_ENABLE
help
Time without key, local-wake, or voice interaction before
entering light standby. The production default is 5 minutes.
config TQ_LIGHT_STANDBY_TASK_STACK_BYTES
int "Light-standby task stack size (bytes)"
default 3072
range 2048 8192
depends on TQ_LIGHT_STANDBY_ENABLE
config TQ_LIGHT_STANDBY_TASK_PRIORITY
int "Light-standby task priority"
default 3
range 1 10
depends on TQ_LIGHT_STANDBY_ENABLE
endmenu
menu "Remote Logging" menu "Remote Logging"
config TQ_REMOTE_LOG_ENABLE config TQ_REMOTE_LOG_ENABLE
+4
View File
@@ -50,6 +50,10 @@ CONFIG_TQ_NETWORK_AUTO_REASSOCIATION_ENABLE=y
CONFIG_TQ_SYSTEM_EVENT_ENABLE=y CONFIG_TQ_SYSTEM_EVENT_ENABLE=y
CONFIG_TQ_SYSTEM_EVENT_QUEUE_LEN=32 CONFIG_TQ_SYSTEM_EVENT_QUEUE_LEN=32
CONFIG_TQ_SYSTEM_EVENT_TASK_STACK=4096 CONFIG_TQ_SYSTEM_EVENT_TASK_STACK=4096
CONFIG_TQ_LIGHT_STANDBY_ENABLE=y
CONFIG_TQ_LIGHT_STANDBY_IDLE_TIMEOUT_MS=300000
CONFIG_TQ_LIGHT_STANDBY_TASK_STACK_BYTES=3072
CONFIG_TQ_LIGHT_STANDBY_TASK_PRIORITY=3
CONFIG_TQ_REMOTE_LOG_ENABLE=y CONFIG_TQ_REMOTE_LOG_ENABLE=y
CONFIG_TQ_REMOTE_LOG_ENDPOINT="http://47.98.175.183:8090/log/batch" CONFIG_TQ_REMOTE_LOG_ENDPOINT="http://47.98.175.183:8090/log/batch"
CONFIG_TQ_REMOTE_LOG_AUTH_TOKEN="" CONFIG_TQ_REMOTE_LOG_AUTH_TOKEN=""