初始提交卡包 USB 工程

纳入固件源码、屏幕组件、nand_xfer 工具和文档。忽略本机构建产物、sdkconfig,以及含本机路径的依赖锁。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zhengxin
2026-10-13 21:54:50 +08:00
co-authored by Cursor
commit 851e347cf5
260 changed files with 269349 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
#include <stdio.h>
#include <stdlib.h>
#include "event.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
EventGroupHandle_t system_event_group = NULL;
QueueHandle_t system_event_queue = NULL;
bool init_event_system(void)
{
// 检查是否已经初始化
if (system_event_group != NULL)
{
ESP_LOGW("EVENT", "Event system already initialized");
return true;
}
// 创建事件组
system_event_group = xEventGroupCreate();
if (system_event_group == NULL)
{
ESP_LOGE("EVENT", "Failed to create event group");
return false;
}
// 创建事件队列(BLE 回调等通过队列投递,避免在回调中直接操作事件组/任务通知)
system_event_queue = xQueueCreate(8, sizeof(uint32_t));
if (system_event_queue == NULL)
{
ESP_LOGE("EVENT", "Failed to create event queue");
vEventGroupDelete(system_event_group);
system_event_group = NULL;
return false;
}
ESP_LOGI("EVENT", "Event system initialized (group + queue)");
return true;
}
// 清理函数
void deinit_event_system(void)
{
if (system_event_queue != NULL)
{
vQueueDelete(system_event_queue);
system_event_queue = NULL;
}
if (system_event_group != NULL)
{
vEventGroupDelete(system_event_group);
system_event_group = NULL;
}
ESP_LOGI("EVENT", "Event system deinitialized");
}
void set_system_event(uint32_t bits)
{
ESP_LOGI("EVENT", "[DEBUG] set_system_event(0x%lX) group=%p queue=%p main_handle=%p",
(unsigned long)bits, (void *)system_event_group, (void *)system_event_queue, (void *)main_task_handle);
if (system_event_group)
{
xEventGroupSetBits(system_event_group, bits);
}
/* 通过队列投递,main_task 阻塞接收,避免 BLE 回调上下文限制导致事件丢失 */
if (system_event_queue)
{
UBaseType_t q_waiting = uxQueueMessagesWaiting(system_event_queue);
UBaseType_t q_spaces = uxQueueSpacesAvailable(system_event_queue);
ESP_LOGI("EVENT", "[DEBUG] queue before send: pending=%u, spaces=%u",
(unsigned)q_waiting, (unsigned)q_spaces);
BaseType_t ok = xQueueSend(system_event_queue, &bits, 0);
ESP_LOGI("EVENT", "[DEBUG] xQueueSend result=%d (1=ok, 0=full)", (int)ok);
if (!ok)
{
ESP_LOGE("EVENT", "Event queue FULL! bits=0x%lX DROPPED! pending=%u",
(unsigned long)bits, (unsigned)q_waiting);
}
}
else
{
ESP_LOGW("EVENT", "[DEBUG] system_event_queue is NULL!");
}
if (main_task_handle)
{
xTaskNotify(main_task_handle, bits, eSetBits);
}
else
{
ESP_LOGW("EVENT", "[DEBUG] main_task_handle is NULL!");
}
}
void clear_system_event(uint32_t bits)
{
if (system_event_group)
{
xEventGroupClearBits(system_event_group, bits);
}
}
uint32_t wait_system_event(uint32_t bits, TickType_t timeout)
{
if (system_event_group)
{
return xEventGroupWaitBits(system_event_group, bits, pdTRUE, pdFALSE, timeout);
}
return 0;
}
+59
View File
@@ -0,0 +1,59 @@
#ifndef EVENT_H
#define EVENT_H
#include "freertos/FreeRTOS.h" // 必须第一个包含
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "freertos/queue.h"
// 声明全局变量(extern 表示在其他文件中定义)
extern EventGroupHandle_t system_event_group;
extern QueueHandle_t system_event_queue; /* 事件队列:BLE 等回调通过队列投递,main_task 阻塞接收 */
extern TaskHandle_t main_task_handle;
// 事件标志定义
#define BLE_CONNECTED_BIT (1 << 0)
#define WIFI_CONNECTED_BIT (1 << 1)
#define WIFI_DISCONNECTED_BIT (1 << 2)
#define BLE_DISCONNECTED_BIT (1 << 14)
#define WEBSOCKET_CONNECTED_BIT (1 << 3)
#define WEBSOCKET_DISCONNECTED_BIT (1 << 4)
#define WEBSOCKET_DATA_BIT (1 << 5)
#define IMU_DATA_READY_BIT (1 << 6)
#define USER_INPUT_BIT (1 << 7)
#define SYSTEM_ERROR_BIT (1 << 8)
#define OTA_UPDATE_STARTED_BIT (1 << 9)
#define OTA_UPDATE_COMPLETED_BIT (1 << 10)
#define DOWNLOAD_EMOJI_BIT (1 << 11)
#define DOWNLOAD_SUCCESS_BIT (1 << 12)
#define DOWNLOAD_FAILED_BIT (1 << 13)
#define OTA_RECOVER_REQUIRED_BIT (1 << 15)
/** OTA 任务因失败退出:先等 WiFi 重连结果再恢复 UI(由 main 处理) */
#define OTA_FAIL_RECOVER_PENDING_BIT (1 << 16)
/** BLE 触发的 WiFi 配网:重试用尽/最终失败后,释放 WiFi 并恢复 LVGL/UI(仅此场景使用) */
#define WIFI_BLE_PROV_FAIL_RECOVER_UI_BIT (1 << 17)
/** 表情包下载成功后的第一次切换:收尾升级;若切到下载包则强制停在该包 default.json */
#define EMOJI_UPGRADE_FINALIZE_BIT (1 << 18)
/* main_task 监听的系统事件掩码(用于 xEventGroupWaitBits) */
#define MAIN_TASK_EVENT_MASK (BLE_CONNECTED_BIT | WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT | \
WEBSOCKET_CONNECTED_BIT | WEBSOCKET_DISCONNECTED_BIT | WEBSOCKET_DATA_BIT | \
IMU_DATA_READY_BIT | USER_INPUT_BIT | SYSTEM_ERROR_BIT | \
OTA_UPDATE_STARTED_BIT | OTA_UPDATE_COMPLETED_BIT | \
DOWNLOAD_EMOJI_BIT | DOWNLOAD_SUCCESS_BIT | DOWNLOAD_FAILED_BIT | \
BLE_DISCONNECTED_BIT | OTA_RECOVER_REQUIRED_BIT | OTA_FAIL_RECOVER_PENDING_BIT | \
WIFI_BLE_PROV_FAIL_RECOVER_UI_BIT | EMOJI_UPGRADE_FINALIZE_BIT)
// 函数声明
void set_system_event(uint32_t bits);
void clear_system_event(uint32_t bits);
uint32_t wait_system_event(uint32_t bits, TickType_t timeout);
// 新增:初始化和清理函数
bool init_event_system(void);
void deinit_event_system(void);
/* WiFi 配网守卫:收到配网指令后开启故障重启策略 */
void notify_wifi_provision_signal_received(void);
#endif // EVENT_H