docs: update changelog, TODO and discussion records with time-sync and NVS stability plan
This commit is contained in:
12
changelog.md
12
changelog.md
@@ -12,8 +12,18 @@
|
||||
- 时区通过 NVS 持久化存储(`system_config` namespace)
|
||||
- 支持城市名映射(Asia/Shanghai → CST-8 等 18 个预设城市)
|
||||
- `config_show` 中显示当前时区配置
|
||||
- **SNTP 自动时间同步**(新增)
|
||||
- WiFi 连接成功后自动从 `pool.ntp.org` 同步系统时间
|
||||
- 新增 `time_sync` 模块(`main/time_sync/`)
|
||||
- `timezone_show` 命令增加 SNTP 同步状态显示
|
||||
- **NVS 配置安全机制**(新增)
|
||||
- 启动时自动校验关键 NVS 命名空间完整性
|
||||
- 检测并修复损坏的 NVS 条目
|
||||
- 启用 ESP32-S3 Brownout Detection 防止供电不足导致 Flash 写入中断
|
||||
|
||||
### 修复
|
||||
- **LLM Provider 初始化 Bug** — 修复 `llm_provider_init()` 中 provider-specific API key 和 Base URL 无法从 NVS 加载的问题(`llm_provider_get_api_key` 对当前 provider 直接返回内存缓存值,导致 NVS 数据永远不会被读取)
|
||||
- **换 USB 口后配置失效** — 启用 Brownout Detection 防止供电不足时 NVS 写入中断,添加启动时 NVS 完整性校验
|
||||
- ESP-IDF v6.0 编译适配
|
||||
- 修复 flash 大小配置(2MB → 16MB)
|
||||
- 修复 WiFi 断开原因码未定义问题(添加 `#ifdef` 保护)
|
||||
@@ -32,7 +42,7 @@
|
||||
|
||||
### 文档
|
||||
- 新增 `docs/ESP-IDF-V6-MIGRATION.md` — ESP-IDF v6.0 迁移适配记录
|
||||
- 更新 `taolun.md` — 讨论记录整理
|
||||
- 更新 `taolun.md` — 讨论记录整理,新增时间同步和 NVS 配置稳定性问题讨论
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -94,10 +94,9 @@
|
||||
- **MimiClaw**: Not implemented
|
||||
- **Recommendation**: Simple FreeRTOS timer that periodically checks HEARTBEAT.md
|
||||
|
||||
### [ ] Multi-LLM Provider Support
|
||||
### [x] ~~Multi-LLM Provider Support~~
|
||||
- **nanobot**: `providers/litellm_provider.py` — supports OpenRouter, Anthropic, OpenAI, Gemini, DeepSeek, Groq, Zhipu, vLLM via LiteLLM
|
||||
- **MimiClaw**: Hardcoded to Anthropic Messages API
|
||||
- **Recommendation**: Abstract LLM interface, support OpenAI-compatible API (most providers are compatible)
|
||||
- **MimiClaw**: Supports Anthropic, OpenAI, SiliconFlow (硅基流动), Volcengine (火山方舟) — abstracted via `llm_provider.c`
|
||||
|
||||
### [ ] Voice Transcription
|
||||
- **nanobot**: `providers/transcription.py` — Groq Whisper API
|
||||
|
||||
93
taolun.md
93
taolun.md
@@ -2,10 +2,97 @@
|
||||
|
||||
---
|
||||
|
||||
## 讨论:ESP-IDF v6.0 编译适配
|
||||
## 讨论:系统时间同步 + NVS 配置稳定性修复
|
||||
|
||||
**日期**:2026-03-31
|
||||
**目标**:解决 ESP-IDF v6.0 编译失败问题,完成固件烧录
|
||||
**日期**:2026-04-01
|
||||
**目标**:修复两个关键问题 — 时间显示 1970、换 USB 口后配置不生效
|
||||
|
||||
### 问题 1:时间显示 1970-01-01
|
||||
|
||||
**现象**:
|
||||
```
|
||||
Current timezone: Asia/Shanghai [NVS]
|
||||
Local time: 1970-01-01 00:00:23 GMT (Thursday)
|
||||
```
|
||||
|
||||
**根因**:代码中没有初始化 SNTP/NTP 客户端。ESP32 上电后 RTC 时钟从 0 开始计时,`time(NULL)` 返回的就是 1970 年以来的秒数。目前只有 LLM 调用 `get_current_time` 工具时才会通过 HTTP 同步时间。
|
||||
|
||||
**修复方案**:
|
||||
- 新建 `main/time_sync/time_sync.c`,使用 ESP-IDF 内置 SNTP 组件
|
||||
- WiFi 连接成功后自动从 `pool.ntp.org` 同步时间
|
||||
- 同步成功后自动应用已保存的时区配置
|
||||
- `timezone_show` 命令增加 SNTP 同步状态显示
|
||||
|
||||
### 问题 2:换 USB 口/电脑后不工作 + 模型配置不加载
|
||||
|
||||
**现象**:
|
||||
- 插入其他 Type-C 口或电脑,设备不正常工作
|
||||
- 需要在 Web 界面重新填写大模型 ID 和密钥,保存重启后才正常
|
||||
- 命令行中模型状态显示异常
|
||||
|
||||
**根因分析**:
|
||||
|
||||
#### 2.1 LLM Provider 初始化 Bug(核心问题)
|
||||
|
||||
在 `llm_provider.c:260-284` 中,`llm_provider_init()` 通过 `llm_provider_get_api_key()` 加载当前 provider 的 API key:
|
||||
|
||||
```c
|
||||
void llm_provider_init(void) {
|
||||
const char *api_key = llm_provider_get_api_key(s_current_provider->name);
|
||||
if (api_key) {
|
||||
strncpy(s_api_key, api_key, sizeof(s_api_key) - 1);
|
||||
}
|
||||
```
|
||||
|
||||
但 `llm_provider_get_api_key()` 的逻辑是(`llm_provider.c:209-214`):
|
||||
|
||||
```c
|
||||
const char *llm_provider_get_api_key(const char *provider_name) {
|
||||
if (strcmp(provider_name, s_current_provider->name) == 0) {
|
||||
return s_api_key; // 直接返回内存中的值,不从 NVS 读!
|
||||
}
|
||||
// 否则才从 NVS 加载...
|
||||
```
|
||||
|
||||
**形成死循环**:`llm_provider_init()` 想从 NVS 加载 key → 调用 `llm_provider_get_api_key` → 发现是当前 provider → 直接返回内存中的 `s_api_key`(初始为空)→ 把空值复制给自己 → **NVS 中的 provider-specific key(如 `siliconflow_api_key`)永远不会被加载到内存**。
|
||||
|
||||
同理,`s_base_url` 也存在相同问题。
|
||||
|
||||
**为什么 Web 界面保存后能正常工作?**
|
||||
|
||||
Web 界面的 `/save` 处理函数(`wifi_onboard.c:377-408`)会**同时保存两份**:
|
||||
```c
|
||||
nvs_sync_field(root, "api_key", MIMI_NVS_LLM, MIMI_NVS_KEY_API_KEY); // 通用 key
|
||||
nvs_sync_field(root, "api_key", MIMI_NVS_LLM, api_key_nvs); // provider-specific key
|
||||
```
|
||||
|
||||
而 `llm_proxy_init()` 能正确加载 `MIMI_NVS_KEY_API_KEY`(通用 key),所以 Web 保存后能用。但如果只通过 CLI 的 `set_siliconflow_key` 设置(只保存到 `siliconflow_api_key`),上电后就不会被加载。
|
||||
|
||||
#### 2.2 Brownout(欠压)导致 NVS 损坏
|
||||
|
||||
ESP32-S3 开启 WiFi 时峰值电流可达 300-500mA,不同 USB 端口的供电能力差异很大。供电不足时:
|
||||
- 可能导致静默重启或 Flash 写入中断
|
||||
- `nvs_commit` 过程中断电会导致 NVS 数据损坏
|
||||
- WiFi 不稳定但日志看起来"正常"
|
||||
|
||||
**修复方案**:
|
||||
1. 修复 `llm_provider_init()` — 直接从 NVS 读取当前 provider 的 key 和 Base URL,绕过 `llm_provider_get_api_key` 的内存缓存
|
||||
2. 新建 `main/nvs_safety/nvs_safety.c` — 启动时校验关键 NVS 命名空间的完整性,检测并修复损坏条目
|
||||
3. 在 `sdkconfig.defaults` 中启用 ESP32-S3 的 Brownout Detection
|
||||
|
||||
### 改动清单
|
||||
|
||||
| 文件 | 操作 | 说明 |
|
||||
|------|------|------|
|
||||
| `main/llm/llm_provider.c` | **修复** | 修复 `llm_provider_init()` 加载逻辑 |
|
||||
| `main/time_sync/time_sync.h` | 新建 | SNTP 时间同步头文件 |
|
||||
| `main/time_sync/time_sync.c` | 新建 | SNTP 时间同步实现 |
|
||||
| `main/nvs_safety/nvs_safety.h` | 新建 | NVS 完整性校验头文件 |
|
||||
| `main/nvs_safety/nvs_safety.c` | 新建 | NVS 损坏检测与修复 |
|
||||
| `main/mimi.c` | 修改 | WiFi 连接后调用 `time_sync_init()` + 启动时调用 `nvs_safety_check()` |
|
||||
| `main/cli/serial_cli.c` | 修改 | `timezone_show` 增加 SNTP 同步状态 |
|
||||
| `main/CMakeLists.txt` | 修改 | 添加新源文件和 `esp_netif` 依赖 |
|
||||
| `sdkconfig.defaults` | 修改 | 启用 Brownout Detection |
|
||||
|
||||
### 问题清单
|
||||
|
||||
|
||||
Reference in New Issue
Block a user