| name | ESP8266_RTOS_SDK-skill |
| description | AI Skill for ESP8266_RTOS_SDK (esp-idf style) firmware development on the ESP8266EX chip. Used when users need to create, modify, or debug ESP8266 FreeRTOS projects, including WiFi STA/AP/ESPNOW, peripheral drivers (GPIO/UART/I2C/SPI/PWM/ADC/hw_timer), sockets/HTTP/MQTT/SNTP networking, NVS/SPIFFS storage, partition tables, OTA firmware upgrade, and sleep/power management. Trigger words: "ESP8266", "ESP8266_RTOS_SDK", "ESP8266EX", "乐鑫", "安信可", "FreeRTOS", "esp-idf style", "xtensa-lx106", "IDF_PATH", "menuconfig", "SoftAP", "ESPNOW", "smartconfig", "OTA" |
| tags | ["embedded","esp8266","espressif","freertos","wifi","esp-idf","rtos","firmware","xtensa","lwip","microcontroller"] |
| license | Apache-2.0 |
| compatibility | Target chip ESP8266EX (Tensilica L106 32-bit); toolchain xtensa-lx106-elf gcc v8.4.0; build via ESP8266_RTOS_SDK (esp-idf style) `make`/CMake with IDF_PATH set |
| metadata | {"author":"Community","version":"1.1.0"} |
ESP8266_RTOS_SDK-skill
面向 ESP8266_RTOS_SDK(esp-idf style 框架)的 AI 固件开发技能。ESP8266_RTOS_SDK 是 Espressif 官方的 ESP8266EX 芯片开发框架,自 v3.0 起采用与 esp-idf 相同的框架(component 化、app_main 入口、Kconfig/menuconfig、partition table、event loop)���本技能提供场景化 recipes、真实 API 参考、Kconfig 速查、常见陷阱与示例索引,帮助 AI 正确编写、配置、构建与烧录 ESP8266 固件。
Core Principles
- 框架是 esp-idf style — 入口为
app_main()(非传统 user_init),项目由 main/ + components/ 组成,通过 make menuconfig 配置 sdkconfig,由 IDF_PATH 环境变量链接到 SDK。不要混用旧版(< v3.0)NonOS SDK / RTOS SDK v2 的 API。
- WiFi 初始化顺序固定 —
nvs_flash_init() → tcpip_adapter_init()(或 esp_netif_init())→ esp_event_loop_create_default() → esp_wifi_init(&cfg) → 注册事件处理器 → esp_wifi_set_mode() → esp_wifi_set_config() → esp_wifi_start()。
- WiFi 事件走 esp_event — 连接、断开、拿到 IP 分别是
WIFI_EVENT / IP_EVENT 两个 base,需分别注册 handler;WIFI_EVENT_STA_DISCONNECTED 中要手动重连。
- 拿 IP 靠 IP_EVENT_STA_GOT_IP —
esp_wifi_connect() 只表示关联到 AP,拿到 IP 由 IP_EVENT_STA_GOT_IP 通知,应用应等该事件再发起网络请求。
- 错误检查用 ESP_ERROR_CHECK — 对返回
esp_err_t 的初始化类 API,用 ESP_ERROR_CHECK(esp_xxx()) 断言,错误会打印 backtrace;不要忽略初始化返回值。
- app_main 不能死循环阻塞 —
app_main 在主任务中运行,返回后该任务被删除。长时间逻辑应放到 xTaskCreate 创建的独立任务里,app_main 仅做初始化与创建任务。
- GPIO 编号 0-16 — ESP8266 只有 GPIO0
GPIO16 共 17 个引脚;GPIO6GPIO11 连接 flash 不可用;GPIO16 是 RTC GPIO,无内部上拉、只能作为输入/输出且特殊。gpio_config() 用 pin_bit_mask 位掩码。
- partition table 决定 flash 布局 — 表烧到 0x8000,factory app 默认在 0x10000;app 分区必须落在单个 1MB 集成分区内,否则启动崩溃。OTA 需至少 ota_0/ota_1 两个 app 槽 + otadata 分区。
- 日志用 ESP_LOGx —
ESP_LOGI/E/W/D/V,需 #include "esp_log.h" 并定义 static const char *TAG = "xxx";,等级由 menuconfig 的 CONFIG_LOG_DEFAULT_LEVEL 控制;不要直接用 printf 做正式日志。
- ADC 与 WiFi 互斥 —
adc_read_fast() 测量期间需关闭 WiFi 与中断;ADC 仅 TOUT(A0) 单通道,模式由 menuconfig 的 CONFIG_ESP8266_PHY vdd33_const 决定(255=测系统电压,否则测外部电压)。
- 构建用 make/CMake 双轨 — 仓库同时支持
make(GNU Make + project.mk)与 cmake(CMakeLists.txt)。示例目录里同时有 Makefile 与 CMakeLists.txt;idf.py 在该分支上优先使用 make 风格命令(make menuconfig/make flash/make monitor)。
- 不臆造 API — 所有函数签名、结构体、宏、Kconfig 选项必须来自
components/esp8266/include/、components/*/include/ 或 docs;查不到即视为不存在,禁止编造。
- 睡眠前先停 WiFi —
esp_deep_sleep / esp_light_sleep_start 不会优雅关闭 WiFi 与协议栈连接(见 esp_sleep.h attention 3)。进 deep/light sleep 前必须 esp_wifi_stop(),否则 esp_light_sleep_start 返回 ESP_ERR_INVALID_STATE。deep sleep 定时唤醒还需要硬件上 XPD_DCDC 经 0Ω 接到 EXT_RSTB。
When to Use
Applicable:
- 创建新的 ESP8266_RTOS_SDK(esp-idf style)项目
- WiFi Station / SoftAP / APSTA / 扫描 / smartconfig / ESPNOW 应用
- 外设驱动:GPIO、UART、I2C、SPI、PWM、ADC、hw_timer、i2s、ir
- 网络应用:BSD sockets(TCP/UDP/组播)、HTTP 请求、HTTP server、MQTT、SNTP、mDNS、CoAP
- 存储:NVS、SPIFFS、partition table、自定义分区
- 固件升级:native OTA(socket)、esp_https_ota、esp_https_ota 简易接口
- 系统与功耗:日志、复位原因、deep sleep / light sleep、power save
Not applicable:
- 旧版 ESP8266 NonOS SDK 或 RTOS_SDK v2(API 与本项目完全不同)
- ESP32 / ESP32-S/C 系列芯片(寄存器、GPIO 数量、双核、蓝牙均不同)—— 用对应芯片的 esp-idf
- Arduino-ESP8266 框架(
setup()/loop() 与本框架不同)
- PCB / 原理图设计、硬件选型咨询
Scenario Quick Reference (Recipes)
当用户意图匹配下方场景时,先读对应 recipe,其中包含完整调用链、分步说明、常见错误与真实代码。
入门 / 项目
| recipe | 场景 |
|---|
recipes/hello_world_project.md | 从零创建第一个 ESP8266_RTOS_SDK 项目(hello_world),配置 / 构建 / 烧录 / 监视 |
recipes/build_and_flash.md | make 与 cmake 双轨构建、menuconfig、make flash / make monitor / make erase_flash |
WiFi 联网
| recipe | 场景 |
|---|
recipes/wifi_station.md | WiFi Station 连接 AP(事件 + 重连 + 拿 IP) |
recipes/wifi_softap.md | WiFi SoftAP 热点(SSID/密码/认证/sta 上下线) |
recipes/smartconfig.md | 一键配网(Esptouch / AirKiss / Esptouch v2) |
recipes/espnow.md | ESPNOW 设备间免连接通信(广播/单播/加密) |
外设驱动
| recipe | 场景 |
|---|
recipes/gpio.md | GPIO 输入输出与中断(per-pin ISR service + 队列) |
recipes/uart.md | UART 驱动安装、事件队列收发、uart_write_bytes / uart_read_bytes |
recipes/pwm.md | 软件 PWM(多通道、占空比、相位) |
recipes/i2c.md | I2C 主机读写(命令链 + MPU6050 实例) |
网络 / 协议
| recipe | 场景 |
|---|
recipes/http_request.md | POSIX socket 发起 HTTP GET 请求 |
recipes/http_server.md | esp_http_server URI handler(GET/POST/PUT、读头/查询、分块响应、动态注册) |
recipes/sockets.md | BSD socket:TCP 服务端(bind/listen/accept)、TCP 客户端、UDP 组播(IP_ADD_MEMBERSHIP) |
recipes/mqtt.md | esp-mqtt 客户端(TCP/SSL/双向认证/PSK/WS/WSS,事件回调订阅发布) |
recipes/sntp_time.md | LwIP SNTP 对时(sntp_setservername + time() + TZ 时区) |
recipes/http_ota.md | native OTA(socket 拉取 + esp_ota_* 写分区)与 esp_https_ota 简易升级 |
存储
| recipe | 场景 |
|---|
recipes/spiffs.md | SPIFFS 文件系统挂载与 POSIX 文件读写 |
功耗 / 睡眠
| recipe | 场景 |
|---|
recipes/deep_sleep_power_save.md | WiFi modem sleep(esp_wifi_set_ps NONE/MIN/MAX)、deep sleep(esp_deep_sleep 定时唤醒)、light sleep(GPIO 唤醒) |
GPIO 速查(ESP8266)
ESP8266EX 可用 GPIO 仅 GPIO0~GPIO16(17 个)。注意大量引脚有引导/flash 复用:
| GPIO | 说明 / 复用注意 |
|---|
| GPIO0 | Boot 模式:上电为低进入下载模式;正常运行建议避免外部强下拉 |
| GPIO1 | UART0 TX(默认),用作普通 IO 需 uart_disable_swap() 并注意日志 |
| GPIO2 | 上电需为高(Boot 模式);常用作 I2C SCL 等 |
| GPIO3 | UART0 RX(默认) |
| GPIO4 / GPIO5 | 普通 IO,最常用,无 boot 约束 |
| GPIO6~GPIO11 | 连接 SPI flash,禁止用作普通 IO |
| GPIO12 | MTDI;上电为高可能影响 flash voltage;PWM/HSPI MISO |
| GPIO13 | MTCK;HSPI MOSI |
| GPIO14 | MTMS;HSPI CLK |
| GPIO15 | MTDO;上电需为低(Boot 模式);HSPI CS / PWM |
| GPIO16 | RTC GPIO,无内部上拉,连接 RTC、可作 deep sleep 唤醒相关,gpio_set_pull_mode 的下拉对其它 IO 无效仅对 GPIO16 生效 |
引脚模式由 gpio_config(gpio_config_t) 统一配置:pin_bit_mask(位掩码,如 (1ULL<<4))、mode、pull_up_en、pull_down_en、intr_type。
WiFi 工作模式与认证
| 枚举 | 含义 |
|---|
WIFI_MODE_NULL | 无 |
WIFI_MODE_STA | Station 模式 |
WIFI_MODE_AP | SoftAP 模式 |
WIFI_MODE_APSTA | Station + SoftAP 同时 |
WIFI_AUTH_OPEN ~ WIFI_AUTH_WPA2_WPA3_PSK | 认证等级;SoftAP 示例常用 WIFI_AUTH_WPA_WPA2_PSK,无密码时设 WIFI_AUTH_OPEN |
Partition Table(内置布局)
| 配置 | 分区(Name, Type, SubType, Offset, Size) |
|---|
| Single factory app, no OTA | nvs data nvs 0x9000 0x6000 · phy_init data phy 0xf000 0x1000 · factory app factory 0x10000 0xF0000 |
| Two OTA app | nvs data nvs 0x9000 0x4000 · otadata data ota 0xd000 0x2000 · phy_init data phy 0xf000 0x1000 · ota_0 app ota_0 0x10000 0xF0000 · ota_1 app ota_1 0x110000 0xF0000 |
自定义分区表:menuconfig 选 "Custom partition table CSV",写 CSV 后 make partition_table 生成二进制表(烧到 0x8000)。
Critical Pitfalls (Must Read)
以下是最常见的错误,任何一条都会导致固件不工作。
1. app_main 中死循环阻塞初始化
void app_main() {
wifi_init_sta();
while (1) {
do_something_blocking();
}
}
void app_main() {
ESP_ERROR_CHECK(nvs_flash_init());
wifi_init_sta();
xTaskCreate(my_loop_task, "my_loop", 4096, NULL, 5, NULL);
}
2. 漏掉 nvs_flash_init()
void app_main() {
wifi_init_sta();
}
void app_main() {
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
wifi_init_sta();
}
3. 等 esp_wifi_connect 返回就以为已联网
esp_wifi_connect();
int s = socket(...);
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
4. STA 断开不重连
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
}
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
esp_wifi_connect();
s_retry_num++;
} else {
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
}
5. 使用了 GPIO6~GPIO11 或 GPIO16 上拉
gpio_set_pull_mode(GPIO_NUM_6, GPIO_PULLUP_ONLY);
gpio_set_pull_mode(GPIO_NUM_4, GPIO_PULLUP_ONLY);
6. 混用 esp-idf 的 esp_netif 与本仓库 tcpip_adapter
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
7. UART 驱动未 install 就 read/write
uart_write_bytes(UART_NUM_0, "hi", 2);
uart_param_config(UART_NUM_0, &uart_config);
uart_driver_install(UART_NUM_0, BUF_SIZE * 2, BUF_SIZE * 2, 100, &uart0_queue, 0);
uart_write_bytes(UART_NUM_0, "hi", 2);
8. PWM 改完配置不调 pwm_start
pwm_set_duty(0, 200);
pwm_set_duty(0, 200);
pwm_start();
9. OTA 不设 boot 分区 / 不重启
esp_ota_end(update_handle);
if (esp_ota_end(update_handle) == ESP_OK) {
ESP_ERROR_CHECK(esp_ota_set_boot_partition(update_partition));
esp_restart();
}
10. 把 factory app 偏移改成跨 1M 边界
# ❌ WRONG — CSV 里 ota_0/ota_1 跨越 1MB 集成分区
ota_0, app, ota_0, 0x10000, 0xF0000
ota_1, app, ota_1, 0x100000, 0xF0000 # 如果改大可能跨边界,启动崩溃
# ✅ CORRECT — app 分区必须完整落在一个 1MB 集成分区内
# 修改起始偏移时,ota_1 = ota_0 + 0x100000,并保持各自不跨边界
11. SPIFFS 挂载前分区表里没有 storage 分区
esp_vfs_spiffs_register(&conf);
12. ADC 测量时未关 WiFi
adc_read_fast(buf, 16);
adc_read_fast(buf, 16);
13. 事件 handler 注册用错 base / event_id
esp_event_handler_register(WIFI_EVENT, IP_EVENT_STA_GOT_IP, &h, NULL);
esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &h, NULL);
esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &h, NULL);
14. IDF_PATH 未设置 / 工具链不在 PATH
make menuconfig
export IDF_PATH=~/esp/ESP8266_RTOS_SDK
export PATH=$PATH:~/esp/xtensa-lx106-elf/bin
make menuconfig
Execution Workflow
| Step | Name | Description |
|---|
| 1 | 明确需求 | 确认芯片就是 ESP8266EX(不是 ESP32),确认用 esp-idf style(v3.0+)而非 NonOS |
| 2 | 选 recipe | 按意图在 recipes/ 找最接近场景,读其调用链与代码 |
| 3 | 查 API | 未覆盖的函数查 resources/api_reference.md,配置项查 resources/config_reference.md |
| 4 | 校验 | 确认头文件 include、函数签名、枚举、Kconfig 符号都来自仓库 |
| 5 | 确认方案 | 向用户说明:需要哪些 component、引脚分配、partition 表、初始化顺序、任务划分 |
| 6 | 执行 | 新项目:复制最接近的示例(见 resources/example_list.md)再改;已有项目:原地编辑 |
| 7 | 自检 | 检查 app_main 不阻塞、NVS 已初始化、GPIO 未用 6-11、错误用 ESP_ERROR_CHECK、事件 base 正确 |
| 8 | 构建 | make menuconfig → make -jN(或 cmake/idf.py) |
| 9 | 烧录监视 | make flash / make flash monitor;串口波特率常用 74880(boot ROM 日志)或 115200 |
Step 6 Detail — 项目创建策略
目标目录尚无项目(首次创建):
- 根据
resources/example_list.md 选最接近的示例目录:
- 入门 →
examples/get-started/hello_world
- WiFi STA →
examples/wifi/getting_started/station
- WiFi AP →
examples/wifi/getting_started/softAP
- 配网 →
examples/wifi/smart_config
- ESPNOW →
examples/wifi/espnow
- GPIO / UART / PWM / I2C →
examples/peripherals/<name>
- HTTP →
examples/protocols/http_request;socket → examples/protocols/sockets/{tcp_client,tcp_server,udp_client,udp_server,udp_multicast}
- MQTT →
examples/protocols/mqtt/{tcp,ssl,ssl_mutual_auth,ssl_psk,ws,wss}
- SNTP →
examples/protocols/sntp;mDNS → examples/protocols/mdns
- HTTP server →
examples/protocols/http_server/{simple,persistent_sockets}
- OTA →
examples/system/ota/native_ota、examples/system/ota/simple_ota_example
- SPIFFS →
examples/storage/spiffs
- 复制整个示例目录到用户工作目录,保留
main/、CMakeLists.txt、Makefile、sdkconfig.defaults、partitions_*.csv 结构。
- 在副本上修改:改
main/*.c、调 menuconfig、改分区表。
- 向用户说明复制了什么、为什么。
目标目录已有项目: 就地编辑,不覆盖。
Failure Strategies
| 情境 | 处理 |
|---|
| 用户其实是 ESP32 / ESP32-S3 | 停止,告知用对应芯片的 esp-idf,本技能不适用 |
| API 在 resources/ 查不到 | 停止,告知用户该 API 在本仓库不存在,禁止臆造 |
| WiFi 一直连不上 | 检查 SSID/密码、threshold.authmode 是否过高、是否在 DISCONNECTED 里重连、信号强度 |
| esp_wifi_init abort | 多半漏了 nvs_flash_init() 或 NVS 分区缺失 |
| GPIO 中断不触发 | 是否 gpio_install_isr_service(0) + gpio_isr_handler_add();引脚是否设为 INPUT |
| OTA 写完不启动新镜像 | 漏 esp_ota_set_boot_partition 或分区表无 ota_0/ota_1/otadata |
| 拿不到 IP | 是否 tcpip_adapter_init()/esp_netif_init() + esp_event_loop_create_default();DHCP 是否开启 |
| 编译报 xtensa-lx106-elf-gcc not found | 工具链未装/未加 PATH;装 v8.4.0 工具链 |
make menuconfig 报 IDF_PATH | 未 export IDF_PATH 或路径含空格 |
References
- 场景 recipes →
recipes/ 目录
- API 速查(WiFi / 外设 / 系统 / 网络 / 存储) →
resources/api_reference.md
- Kconfig / menuconfig 常用配置 →
resources/config_reference.md
- 常见陷阱汇总 →
resources/pitfalls.md
- 示例项目索引(真实路径) →
resources/example_list.md