diff --git a/V1.4/STM32F103_App1/HardWare/SYSINIT/app_loop.c.bak b/V1.4/STM32F103_App1/HardWare/SYSINIT/app_loop.c.bak deleted file mode 100644 index 15fa4a3..0000000 --- a/V1.4/STM32F103_App1/HardWare/SYSINIT/app_loop.c.bak +++ /dev/null @@ -1,253 +0,0 @@ -/* 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 (;;) { } -}