shuichan_old/V1.3/STM32F103_App1/HardWare/SYSINIT/app_loop.c

187 lines
5.9 KiB
C
Raw Normal View History

/* app_loop.c - 主循环业务调度封装
*
* main() while(1)
* 使 main.c app_loop_process()
*/
#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"
/* 主循环状态变量 */
static uint8_t ota_confirmed = 0;
static uint8_t ota_simulate_fail = 0; /* =1测试模拟 OTA 确认失败 */
static uint8_t ota_fail_logged = 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;
/**
* @brief /
* @note /GPIO/UART/ Board_Init()
*/
void app_init(void)
{
log_info("");
log_info("* * * * * * * * * * * * * * * * * *");
log_info("* Version: 1.3.0 *");
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();
/* LEDLED2 心跳同时兼任外部看门狗 TPL5010 喂狗) */
ledInit();
/* ADC 电量检测 */
adcInit();
update_batter();
/* 网络模块初始化4G Air780E 优先,无 SIM 卡时自动切换到 WiFi(ESP-01S) */
NET_init();
/* 启动各路串口接收 */
USART2_StartRx(); /* RS485 喂料秤 */
USART3_StartRx(); /* 4G MQTT 消息DMA+IDLE */
USART1_StartRx(); /* 蓝牙调试命令 */
}
void app_loop_init(void)
{
/* 继电器断电记忆恢复挪到 app_loop_process 的"MQTT 首次就绪"分支执行:
* SIM WiFi 2 */
}
void app_loop_process(void)
{
/* 记录 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();
}
/* 更新联网指示灯 */
g_net_led_connected = g_net_mqtt_ready ? 1 : 0;
/* 首次发布成功后延迟 3s 再 OTA 确认 */
if (!ota_confirmed && g_net_mqtt_ready && g_net_first_publish_ok &&
(HAL_GetTick() - ota_confirm_tick) > 3000) {
if (ota_simulate_fail) {
if (!ota_fail_logged) {
ota_fail_logged = 1;
log_info("> OTA confirm skipped (simulate fail for rollback test)");
}
/* 不置位 ota_confirmed让 1 分钟健康超时触发复位 */
} else {
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();
}
/* 蓝牙调试命令 */
process_usart1_command();
/* 继电器命令响应状态机 */
relayCmdProcess();
/* 延迟状态上报 */
if (relay_report_pending && (HAL_GetTick() - relay_report_tick) > 100) {
relay_report_pending = 0;
relayStatueUpdata();
}
/* 各模块轮询 */
NET_process();
update_batter();
feedScaleProcess();
activeEvents();
/* 运行时长心跳:每 30s 串口输出一次(天/时/分),
* 64 HAL_GetTick 49 */
{
static uint32_t up_last = 0;
static uint32_t up_print = 0;
static uint64_t up_ms = 0;
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));
}
}
}
/* 后台任务切片:供长时间阻塞的 AT/OTA 流程在等待间隙调用。
* NET_process */
void app_bg_service(void)
{
static uint32_t bg_batt_tick = 0;
/* 长阻塞流程AT/OTA 等待)在等待间隙喂狗 */
IWDG_Feed();
/* 蓝牙调试命令 */
process_usart1_command();
/* 喂料秤轮询与投喂保护 */
feedScaleProcess();
/* LED 心跳/联网指示 */
activeEvents();
/* 电量 1s 节流更新 */
if (HAL_GetTick() - bg_batt_tick >= 1000) {
bg_batt_tick = HAL_GetTick();
update_batter();
}
}