修复 RECOVERY 命令:透传态下先 +++ 退透传再 AT+RESTORE(V1.2~V1.4)
This commit is contained in:
parent
42b53f7c30
commit
6df97c1e37
|
|
@ -277,12 +277,32 @@ int esp_smartconfig(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*==== 退出透传模式 ====
|
||||||
|
* "+++" 前后各需 1s 静默 guard time,且不能带 \r\n;
|
||||||
|
* 回命令态后顺手关掉当前 TCP 连接(失败忽略,后续 esp_reset 会兜底) */
|
||||||
|
int esp_exit_transparent(void)
|
||||||
|
{
|
||||||
|
bg_delay(1100);
|
||||||
|
esp_send((uint8_t *)"+++", 3);
|
||||||
|
bg_delay(1100);
|
||||||
|
if (esp_send_cmd("AT", "OK", 2000) != 0) {
|
||||||
|
log_warn("> WiFi: exit transparent no AT reply");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
esp_send_cmd("AT+CIPCLOSE", "OK", 2000);
|
||||||
|
log_info("> WiFi: exit transparent OK");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*==== 恢复出厂设置:AT+RESTORE,模块忘掉已保存的热点(用于测试 SmartConfig)====
|
/*==== 恢复出厂设置:AT+RESTORE,模块忘掉已保存的热点(用于测试 SmartConfig)====
|
||||||
* 注意:RESTORE 后模块自动重启且波特率回到出厂 115200,
|
* 注意 1:RESTORE 后模块自动重启且波特率回到出厂 115200,
|
||||||
* 这里发送后主动把 UART4 切回 115200 探测确认 */
|
* 这里发送后主动把 UART4 切回 115200 探测确认。
|
||||||
|
* 注意 2:WiFi 已连上时模块处于 TCP 透传态,直接发 AT 会被当作 TCP 数据
|
||||||
|
* 发往服务器(模块永远收不到),必须先 "+++" 退透传回命令态! */
|
||||||
int esp_factory_restore(void)
|
int esp_factory_restore(void)
|
||||||
{
|
{
|
||||||
log_info("> WiFi: AT+RESTORE (forget saved AP)");
|
log_info("> WiFi: AT+RESTORE (forget saved AP)");
|
||||||
|
esp_exit_transparent(); /* 透传中先退回命令态;非透传时调用无害 */
|
||||||
esp_rx_clear();
|
esp_rx_clear();
|
||||||
ESP_printf("AT+RESTORE");
|
ESP_printf("AT+RESTORE");
|
||||||
bg_delay(2500); /* 等模块执行 RESTORE 并完成重启 */
|
bg_delay(2500); /* 等模块执行 RESTORE 并完成重启 */
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ int esp_join_fixed_ap(void); /* 连固定SSID(60s
|
||||||
int esp_wait_got_ip(int timeout_s); /* 等已存AP自动连接拿IP, 0=成功 */
|
int esp_wait_got_ip(int timeout_s); /* 等已存AP自动连接拿IP, 0=成功 */
|
||||||
int esp_smartconfig(void); /* ESP-Touch智能配网(60s), 0=成功 */
|
int esp_smartconfig(void); /* ESP-Touch智能配网(60s), 0=成功 */
|
||||||
int esp_enter_transparent(const char *ip, uint16_t port); /* 连TCP并进透传, 0=成功 */
|
int esp_enter_transparent(const char *ip, uint16_t port); /* 连TCP并进透传, 0=成功 */
|
||||||
|
int esp_exit_transparent(void); /* "+++" 退透传+CIPCLOSE, 0=成功 */
|
||||||
int esp_factory_restore(void); /* AT+RESTORE 恢复出厂(忘掉已存AP), 0=成功 */
|
int esp_factory_restore(void); /* AT+RESTORE 恢复出厂(忘掉已存AP), 0=成功 */
|
||||||
void esp_send(const uint8_t *data, uint16_t len); /* 透传模式原始数据发送 */
|
void esp_send(const uint8_t *data, uint16_t len); /* 透传模式原始数据发送 */
|
||||||
void esp_rx_clear(void); /* 清空共享接收缓冲 */
|
void esp_rx_clear(void); /* 清空共享接收缓冲 */
|
||||||
|
|
|
||||||
|
|
@ -303,11 +303,14 @@ int esp_exit_transparent(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*==== 恢复出厂设置:AT+RESTORE,模块忘掉已保存的热点(用于测试 SmartConfig)====
|
/*==== 恢复出厂设置:AT+RESTORE,模块忘掉已保存的热点(用于测试 SmartConfig)====
|
||||||
* 注意:RESTORE 后模块自动重启且波特率回到出厂 115200,
|
* 注意 1:RESTORE 后模块自动重启且波特率回到出厂 115200,
|
||||||
* 这里发送后主动把 UART4 切回 115200 探测确认 */
|
* 这里发送后主动把 UART4 切回 115200 探测确认。
|
||||||
|
* 注意 2:WiFi 已连上时模块处于 TCP 透传态,直接发 AT 会被当作 TCP 数据
|
||||||
|
* 发往服务器(模块永远收不到),必须先 "+++" 退透传回命令态! */
|
||||||
int esp_factory_restore(void)
|
int esp_factory_restore(void)
|
||||||
{
|
{
|
||||||
log_info("> WiFi: AT+RESTORE (forget saved AP)");
|
log_info("> WiFi: AT+RESTORE (forget saved AP)");
|
||||||
|
esp_exit_transparent(); /* 透传中先退回命令态;非透传时调用无害 */
|
||||||
esp_rx_clear();
|
esp_rx_clear();
|
||||||
ESP_printf("AT+RESTORE");
|
ESP_printf("AT+RESTORE");
|
||||||
bg_delay(2500); /* 等模块执行 RESTORE 并完成重启 */
|
bg_delay(2500); /* 等模块执行 RESTORE 并完成重启 */
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,11 @@
|
||||||
volatile uint8_t g_wifi_mqtt_ready = 0;
|
volatile uint8_t g_wifi_mqtt_ready = 0;
|
||||||
volatile uint8_t g_wifi_first_publish_ok = 0;
|
volatile uint8_t g_wifi_first_publish_ok = 0;
|
||||||
|
|
||||||
|
/* WiFi 模块恢复出厂请求标志:由蓝牙 RECOVERY 命令(sys任务)置位,
|
||||||
|
* net 任务在 net_wifi_process 里执行——所有 UART4 操作都收口在 net 任务,
|
||||||
|
* 避免与 4G 切换/建链并发冲突 */
|
||||||
|
volatile uint8_t g_wifi_restore_req = 0;
|
||||||
|
|
||||||
static uint32_t s_ping_tick = 0;
|
static uint32_t s_ping_tick = 0;
|
||||||
|
|
||||||
/* 上行发布主题暂存 */
|
/* 上行发布主题暂存 */
|
||||||
|
|
@ -102,6 +107,20 @@ int net_wifi_init(void)
|
||||||
/*==== 非阻塞轮询:下行报文解析 + 心跳保活 ====*/
|
/*==== 非阻塞轮询:下行报文解析 + 心跳保活 ====*/
|
||||||
void net_wifi_process(void)
|
void net_wifi_process(void)
|
||||||
{
|
{
|
||||||
|
/* 恢复出厂请求(蓝牙 RECOVERY):在 net 任务上下文执行,
|
||||||
|
* 不与本任务的建链/收发并发 */
|
||||||
|
if (g_wifi_restore_req) {
|
||||||
|
g_wifi_restore_req = 0;
|
||||||
|
log_warn("> WiFi: restore request, AT+RESTORE & reboot");
|
||||||
|
g_net_tx_busy = 1;
|
||||||
|
g_wifi_mqtt_ready = 0;
|
||||||
|
if (esp_factory_restore() != 0) {
|
||||||
|
log_warn("> WiFi: RESTORE failed, reboot anyway");
|
||||||
|
}
|
||||||
|
HAL_Delay(100);
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
if (!g_wifi_mqtt_ready) return;
|
if (!g_wifi_mqtt_ready) return;
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
extern volatile uint8_t g_wifi_mqtt_ready;
|
extern volatile uint8_t g_wifi_mqtt_ready;
|
||||||
extern volatile uint8_t g_wifi_first_publish_ok;
|
extern volatile uint8_t g_wifi_first_publish_ok;
|
||||||
|
extern volatile uint8_t g_wifi_restore_req; /* 置1请求 WiFi 模块恢复出厂(net任务执行) */
|
||||||
|
|
||||||
int net_wifi_init(void); /* 阻塞建链:复位→连AP(已存→固定→SmartConfig)→透传→MQTT, 0=就绪 */
|
int net_wifi_init(void); /* 阻塞建链:复位→连AP(已存→固定→SmartConfig)→透传→MQTT, 0=就绪 */
|
||||||
void net_wifi_process(void); /* 非阻塞轮询:解析下行报文 + 心跳保活 */
|
void net_wifi_process(void); /* 非阻塞轮询:解析下行报文 + 心跳保活 */
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ static void sys_task(void *arg)
|
||||||
if (now - up_print >= 30000) {
|
if (now - up_print >= 30000) {
|
||||||
up_print = now;
|
up_print = now;
|
||||||
uint32_t mins = (uint32_t)(up_ms / 60000);
|
uint32_t mins = (uint32_t)(up_ms / 60000);
|
||||||
log_info("> Uptime: %ud %02u:%02u",
|
log_info("> Uptime: %uday--%02uh--%02um\r\n",
|
||||||
(unsigned)(mins / 1440),
|
(unsigned)(mins / 1440),
|
||||||
(unsigned)((mins % 1440) / 60),
|
(unsigned)((mins % 1440) / 60),
|
||||||
(unsigned)(mins % 60));
|
(unsigned)(mins % 60));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,253 @@
|
||||||
|
/* app_loop.c - FreeRTOS 任务调度封装
|
||||||
|
*
|
||||||
|
* 任务划分(裸机主循环轮询项拆分而来):
|
||||||
|
* net_task(优先级3, 栈3KB) - 网络状态机 NET_process:4G/WiFi 建链、收发、OTA 下载
|
||||||
|
* app_task(优先级2, 栈2KB) - 业务:继电器命令/反馈状态机、投喂秤、状态上报、OTA 确认
|
||||||
|
* sys_task(优先级1, 栈1KB) - 系统:LED、电量、蓝牙调试命令、运行时长打印
|
||||||
|
* idle 钩子 - 喂 IWDG(只要调度器正常,看门狗就不会断粮;
|
||||||
|
* 有任务死循环占 CPU 时 idle 饿死 → 复位,正是想要的行为)
|
||||||
|
*
|
||||||
|
* 共享资源互斥:
|
||||||
|
* g_net_at_mutex - NET_publish_* 与长 AT 会话(建链/重连)互斥,拿锁失败直接丢弃
|
||||||
|
* s_storage_mutex - EEPROM(软件I2C) / W25Q64(软件SPI) 跨任务访问互斥(storage_lock)
|
||||||
|
* log 输出 - log.c 内部互斥,多任务日志不交织
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "app_loop.h"
|
||||||
|
#include "app_common.h"
|
||||||
|
#include "user_cmd.h"
|
||||||
|
#include "relay.h"
|
||||||
|
#include "network.h"
|
||||||
|
#include "led.h"
|
||||||
|
#include "adc.h"
|
||||||
|
#include "feed_scale.h"
|
||||||
|
#include "iic.h"
|
||||||
|
#include "24c02.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "../W25Q64/w25q64.h"
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/*==== 存储总线互斥锁(EEPROM/W25Q64 共用一把递归锁)====*/
|
||||||
|
static SemaphoreHandle_t s_storage_mutex = NULL;
|
||||||
|
|
||||||
|
void storage_lock_init(void)
|
||||||
|
{
|
||||||
|
s_storage_mutex = xSemaphoreCreateRecursiveMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
void storage_lock(void)
|
||||||
|
{
|
||||||
|
if (s_storage_mutex && xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
|
||||||
|
xSemaphoreTakeRecursive(s_storage_mutex, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void storage_unlock(void)
|
||||||
|
{
|
||||||
|
if (s_storage_mutex && xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
|
||||||
|
xSemaphoreGiveRecursive(s_storage_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==== 业务模块初始化(调度器启动前调用,与裸机版一致)====*/
|
||||||
|
void app_init(void)
|
||||||
|
{
|
||||||
|
log_info("");
|
||||||
|
log_info("* * * * * * * * * * * * * * * * * *");
|
||||||
|
log_info("* Version: 1.4.0 (RTOS) *");
|
||||||
|
log_info("* * * * * * * By Helei * * * *");
|
||||||
|
|
||||||
|
/* EEPROM 中的 MQTT/版本配置 */
|
||||||
|
iicInit();
|
||||||
|
eepromReadInfo();
|
||||||
|
log_info("> Server: %s:%d", MqttInfoStr.ServerIP, MqttInfoStr.ServerPort);
|
||||||
|
log_info("> Client: %s", MqttInfoStr.ClientID);
|
||||||
|
log_info("> User : %s", MqttInfoStr.Username);
|
||||||
|
log_info("> Firmware Ver: %u", MqttInfoStr.Ver);
|
||||||
|
|
||||||
|
/* W25Q64 外部 Flash,用于 OTA 固件暂存 */
|
||||||
|
W25Q64_Init();
|
||||||
|
|
||||||
|
/* 继电器 GPIO(控制输出 + 反馈输入) */
|
||||||
|
relayInit();
|
||||||
|
|
||||||
|
/* RS485 喂料秤控制模块 */
|
||||||
|
feedScaleInit();
|
||||||
|
|
||||||
|
/* LED(LED2 心跳同时兼任外部看门狗 TPL5010 喂狗) */
|
||||||
|
ledInit();
|
||||||
|
|
||||||
|
/* ADC 电量检测 */
|
||||||
|
adcInit();
|
||||||
|
update_batter();
|
||||||
|
|
||||||
|
/* 网络模块初始化:按 EEPROM 记忆的上次成功方式优先(4G 或 WiFi) */
|
||||||
|
NET_init();
|
||||||
|
|
||||||
|
/* 启动各路串口接收 */
|
||||||
|
USART2_StartRx(); /* RS485 喂料秤 */
|
||||||
|
USART3_StartRx(); /* 4G MQTT 消息,DMA+IDLE */
|
||||||
|
USART1_StartRx(); /* 蓝牙调试命令 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==== net_task:网络状态机(4G/WiFi 建链、收发、OTA)====*/
|
||||||
|
static void net_task(void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
for (;;) {
|
||||||
|
NET_process();
|
||||||
|
vTaskDelay(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==== app_task:业务逻辑(继电器/秤/上报/OTA 确认)====*/
|
||||||
|
static void app_task(void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
/* 主循环状态变量 */
|
||||||
|
static uint8_t ota_confirmed = 0;
|
||||||
|
static uint32_t ota_confirm_tick = 0;
|
||||||
|
static uint32_t mqtt_ready_tick = 0;
|
||||||
|
static uint8_t mqtt_ready_recorded = 0;
|
||||||
|
static uint8_t mqtt_first_status_reported = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
/* 记录 MQTT 首次就绪时刻 */
|
||||||
|
if (!mqtt_ready_recorded && g_net_mqtt_ready) {
|
||||||
|
mqtt_ready_recorded = 1;
|
||||||
|
mqtt_ready_tick = HAL_GetTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MQTT 首次就绪后:先按 EEPROM 恢复继电器上次状态(断电记忆),
|
||||||
|
* 再上报一次完整状态,让平台刷新为真实状态 */
|
||||||
|
if (g_net_mqtt_ready && !mqtt_first_status_reported) {
|
||||||
|
mqtt_first_status_reported = 1;
|
||||||
|
relayRestoreState();
|
||||||
|
relayStatueUpdata();
|
||||||
|
log_info("> Main: first status report after MQTT ready");
|
||||||
|
ota_confirm_tick = HAL_GetTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 首次发布成功后延迟 3s 再 OTA 确认 */
|
||||||
|
if (!ota_confirmed && g_net_mqtt_ready && g_net_first_publish_ok &&
|
||||||
|
(HAL_GetTick() - ota_confirm_tick) > 3000) {
|
||||||
|
ota_confirmed = 1;
|
||||||
|
NET_ota_confirm();
|
||||||
|
log_info("> OTA confirmed (MQTT ready + first publish ok + 3s delay)");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MQTT 就绪后 1 分钟仍未首次 MPUB,主动复位 */
|
||||||
|
if (!ota_confirmed && mqtt_ready_recorded &&
|
||||||
|
(HAL_GetTick() - mqtt_ready_tick) > OTA_HEALTH_TIMEOUT_MS) {
|
||||||
|
log_warn("> OTA health timeout: MQTT ready but no MPUB in 1min, reset");
|
||||||
|
W25Q64_OTA_IncTrial(); /* 软件复位 BL 不计次,这里自行消耗一次试错 */
|
||||||
|
HAL_Delay(100);
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 继电器命令响应状态机 */
|
||||||
|
relayCmdProcess();
|
||||||
|
|
||||||
|
/* 延迟状态上报 */
|
||||||
|
if (relay_report_pending && (HAL_GetTick() - relay_report_tick) > 100) {
|
||||||
|
relay_report_pending = 0;
|
||||||
|
relayStatueUpdata();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 喂料秤轮询与投喂保护 */
|
||||||
|
feedScaleProcess();
|
||||||
|
|
||||||
|
vTaskDelay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==== sys_task:系统辅助(LED/电量/蓝牙命令/运行时长)====*/
|
||||||
|
static void sys_task(void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
uint32_t batt_tick = HAL_GetTick();
|
||||||
|
uint32_t up_last = HAL_GetTick();
|
||||||
|
uint32_t up_print = HAL_GetTick();
|
||||||
|
uint64_t up_ms = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
/* 蓝牙调试命令 */
|
||||||
|
process_usart1_command();
|
||||||
|
|
||||||
|
/* 联网指示:连接中闪烁,连上常亮(led.c activeEvents 据此控制 PA1) */
|
||||||
|
g_net_led_connected = g_net_mqtt_ready ? 1 : 0;
|
||||||
|
|
||||||
|
/* LED 心跳/联网指示 */
|
||||||
|
activeEvents();
|
||||||
|
|
||||||
|
/* 电量 1s 节流更新 */
|
||||||
|
if (HAL_GetTick() - batt_tick >= 1000) {
|
||||||
|
batt_tick = HAL_GetTick();
|
||||||
|
update_batter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 运行时长心跳:每 30s 串口输出一次(天/时/分),
|
||||||
|
* 64 位累计,HAL_GetTick 约 49 天回绕也不受影响 */
|
||||||
|
{
|
||||||
|
uint32_t now = HAL_GetTick();
|
||||||
|
up_ms += (uint32_t)(now - up_last); /* 32位差值天然容忍回绕 */
|
||||||
|
up_last = now;
|
||||||
|
if (now - up_print >= 30000) {
|
||||||
|
up_print = now;
|
||||||
|
uint32_t mins = (uint32_t)(up_ms / 60000);
|
||||||
|
log_info("> Uptime: %uday %02uh:%02um\r\n",
|
||||||
|
(unsigned)(mins / 1440),
|
||||||
|
(unsigned)((mins % 1440) / 60),
|
||||||
|
(unsigned)(mins % 60));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==== FreeRTOS 钩子 ====*/
|
||||||
|
|
||||||
|
/* idle 钩子:喂独立看门狗。有任务死循环占 CPU 时 idle 饿死 → IWDG 复位 */
|
||||||
|
void vApplicationIdleHook(void)
|
||||||
|
{
|
||||||
|
IWDG_Feed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void vApplicationMallocFailedHook(void)
|
||||||
|
{
|
||||||
|
log_error("> RTOS: malloc failed (heap exhausted)");
|
||||||
|
taskDISABLE_INTERRUPTS();
|
||||||
|
for (;;) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
|
||||||
|
{
|
||||||
|
(void)xTask;
|
||||||
|
log_error("> RTOS: stack overflow in task %s", pcTaskName);
|
||||||
|
taskDISABLE_INTERRUPTS();
|
||||||
|
for (;;) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==== 任务创建与调度器启动(main 调用,不再返回)====*/
|
||||||
|
void app_rtos_start(void)
|
||||||
|
{
|
||||||
|
/* 互斥锁先于任务创建 */
|
||||||
|
log_lock_init();
|
||||||
|
storage_lock_init();
|
||||||
|
NET_LockInit();
|
||||||
|
|
||||||
|
xTaskCreate(net_task, "net", 768, NULL, 3, NULL); /* 栈 3KB:AT/OTA 有大的 sprintf 缓冲 */
|
||||||
|
xTaskCreate(app_task, "app", 512, NULL, 2, NULL); /* 栈 2KB */
|
||||||
|
xTaskCreate(sys_task, "sys", 256, NULL, 1, NULL); /* 栈 1KB */
|
||||||
|
|
||||||
|
vTaskStartScheduler();
|
||||||
|
|
||||||
|
/* 不会走到这里(堆不足创建失败才会) */
|
||||||
|
log_error("> RTOS: scheduler failed to start");
|
||||||
|
for (;;) { }
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
#include "net_wifi.h"
|
||||||
#include "esp8266.h"
|
#include "esp8266.h"
|
||||||
|
|
||||||
/* 本地命令字符串不区分大小写比较 */
|
/* 本地命令字符串不区分大小写比较 */
|
||||||
|
|
@ -56,8 +57,6 @@ void process_usart1_command(void)
|
||||||
|
|
||||||
if (cmd_is(cmd, "RESET")) {
|
if (cmd_is(cmd, "RESET")) {
|
||||||
log_warn("> USART1 RESET command received, rebooting...");
|
log_warn("> USART1 RESET command received, rebooting...");
|
||||||
HAL_Delay(100);
|
|
||||||
NVIC_SystemReset();
|
|
||||||
}
|
}
|
||||||
else if (cmd_is(cmd, "INFO")) {
|
else if (cmd_is(cmd, "INFO")) {
|
||||||
log_info("> BT INFO: ver=%u, server=%s:%d, client=%s",
|
log_info("> BT INFO: ver=%u, server=%s:%d, client=%s",
|
||||||
|
|
@ -87,23 +86,18 @@ void process_usart1_command(void)
|
||||||
}
|
}
|
||||||
else if (cmd_is(cmd, "OTA")) {
|
else if (cmd_is(cmd, "OTA")) {
|
||||||
log_info("> BT OTA: reboot to bootloader for OTA check");
|
log_info("> BT OTA: reboot to bootloader for OTA check");
|
||||||
HAL_Delay(100);
|
|
||||||
NVIC_SystemReset();
|
|
||||||
}
|
}
|
||||||
else if (cmd_is(cmd, "RECOVERY")) {
|
else if (cmd_is(cmd, "RECOVERY")) {
|
||||||
/* WiFi 模块 AT+RESTORE 恢复出厂(忘掉已保存的热点),用于测试 SmartConfig;
|
/* WiFi 模块 AT+RESTORE 恢复出厂(忘掉已保存的热点),用于测试 SmartConfig;
|
||||||
* 仅 WiFi 通道激活时才操作模块(UART4 与 4G 共享接收缓冲,
|
* 仅 WiFi 通道激活时才操作模块(UART4 与 4G 共享接收缓冲,
|
||||||
* 4G 模式下动 UART4 会干扰 4G 数据),随后整机复位走完整重连流程 */
|
* 4G 模式下动 UART4 会干扰 4G 数据),随后整机复位走完整重连流程 */
|
||||||
if (NET_GetActiveBackend() == NET_BACKEND_WIFI) {
|
if (NET_GetActiveBackend() == NET_BACKEND_WIFI) {
|
||||||
log_warn("> BT RECOVERY: restore WiFi module & reboot");
|
log_warn("> BT RECOVERY: WiFi restore scheduled"); g_wifi_restore_req = 1;
|
||||||
if (esp_factory_restore() != 0) {
|
|
||||||
log_warn("> BT RECOVERY: RESTORE failed, reboot anyway");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log_warn("> BT RECOVERY: 4G mode, WiFi module untouched, reboot only");
|
log_warn("> BT RECOVERY: 4G mode, WiFi module untouched, reboot only");
|
||||||
|
HAL_Delay(100);
|
||||||
|
NVIC_SystemReset();
|
||||||
}
|
}
|
||||||
HAL_Delay(100);
|
|
||||||
NVIC_SystemReset();
|
|
||||||
}
|
}
|
||||||
else if (cmd_is(cmd, "HELP")) {
|
else if (cmd_is(cmd, "HELP")) {
|
||||||
log_info("CMD: RESET, INFO, STATUS, R1ON/R1OFF~R4ON/R4OFF, ALLON, ALLOFF, OTA, RECOVERY, HELP");
|
log_info("CMD: RESET, INFO, STATUS, R1ON/R1OFF~R4ON/R4OFF, ALLON, ALLOFF, OTA, RECOVERY, HELP");
|
||||||
|
|
|
||||||
|
|
@ -303,11 +303,14 @@ int esp_exit_transparent(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*==== 恢复出厂设置:AT+RESTORE,模块忘掉已保存的热点(用于测试 SmartConfig)====
|
/*==== 恢复出厂设置:AT+RESTORE,模块忘掉已保存的热点(用于测试 SmartConfig)====
|
||||||
* 注意:RESTORE 后模块自动重启且波特率回到出厂 115200,
|
* 注意 1:RESTORE 后模块自动重启且波特率回到出厂 115200,
|
||||||
* 这里发送后主动把 UART4 切回 115200 探测确认 */
|
* 这里发送后主动把 UART4 切回 115200 探测确认。
|
||||||
|
* 注意 2:WiFi 已连上时模块处于 TCP 透传态,直接发 AT 会被当作 TCP 数据
|
||||||
|
* 发往服务器(模块永远收不到),必须先 "+++" 退透传回命令态! */
|
||||||
int esp_factory_restore(void)
|
int esp_factory_restore(void)
|
||||||
{
|
{
|
||||||
log_info("> WiFi: AT+RESTORE (forget saved AP)");
|
log_info("> WiFi: AT+RESTORE (forget saved AP)");
|
||||||
|
esp_exit_transparent(); /* 透传中先退回命令态;非透传时调用无害 */
|
||||||
esp_rx_clear();
|
esp_rx_clear();
|
||||||
ESP_printf("AT+RESTORE");
|
ESP_printf("AT+RESTORE");
|
||||||
bg_delay(2500); /* 等模块执行 RESTORE 并完成重启 */
|
bg_delay(2500); /* 等模块执行 RESTORE 并完成重启 */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue