nongye/STM32F103_App1/HardWare/SYSINIT/app_loop.c

417 lines
14 KiB
C
Raw Normal View History

/* app_loop.c - FreeRTOS <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD>װ
*
* <EFBFBD><EFBFBD><EFBFBD>񻮷֣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* net_task(<EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>3, ջ3KB) - <EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD> NET_process<EFBFBD><EFBFBD>4G/WiFi <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>շ<EFBFBD><EFBFBD><EFBFBD>OTA <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* app_task(<EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>2, ջ2KB) - ҵ<EFBFBD>񣺰<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɼ<EFBFBD><EFBFBD>ϱ<EFBFBD><EFBFBD><EFBFBD>OTA ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* sys_task(<EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>1, ջ1KB) - ϵͳ<EFBFBD><EFBFBD>LED<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ
* idle <EFBFBD><EFBFBD><EFBFBD><EFBFBD> - ι IWDG<EFBFBD><EFBFBD>ֻҪ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ź<EFBFBD><EFBFBD>Ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD>ռ CPU ʱ idle <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD>
* g_net_at_mutex - NET_publish_* <EFBFBD> AT <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>ֱ<EFBFBD>Ӷ<EFBFBD><EFBFBD><EFBFBD>
* s_storage_mutex - EEPROM(<EFBFBD><EFBFBD><EFBFBD><EFBFBD>I2C) / W25Q64(<EFBFBD><EFBFBD><EFBFBD><EFBFBD>SPI) <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʻ<EFBFBD><EFBFBD>storage_lock<EFBFBD><EFBFBD>
* log <EFBFBD><EFBFBD><EFBFBD><EFBFBD> - log.c <EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>֯
*/
#include "app_loop.h"
#include "app_common.h"
#include "user_cmd.h"
#include "network.h"
#include "led.h"
#include "sensor.h"
#include "adc.h"
#include "iic.h"
#include "24c02.h"
#include "uart.h"
#include "log_cn.h"
#include "ble_at.h"
#include "oled.h"
#include "../W25Q64/w25q64.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/*==== <20><EFBFBD><E6B4A2><EFBFBD>߻<EFBFBD><DFBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>EEPROM/W25Q64 <20><><EFBFBD><EFBFBD>һ<EFBFBD>ѵݹ<D1B5><DDB9><EFBFBD><EFBFBD><EFBFBD>====*/
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);
}
}
/*==== ҵ<><D2B5>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>£<EFBFBD>====*/
void app_init(void)
{
log_info("");
log_info("* * * * * * * * * * * * * * * * * *");
log_info("* <20>汾: %s (RTOS) *", FIRMWARE_VERSION_STR);
log_info("* * * * * * * By Helei * * * *");
/* EEPROM <20>е<EFBFBD> MQTT/<2F><EFBFBD><E6B1BE><EFBFBD><EFBFBD> */
iicInit();
eepromReadInfo();
log_load_level(); /* <20>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD>ȼ<EFBFBD> */
log_info("> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %s:%d", MqttInfoStr.ServerIP, MqttInfoStr.ServerPort);
log_info("> <20>ͻ<EFBFBD><CDBB><EFBFBD>ID: %s", MqttInfoStr.ClientID);
log_info("> <20>û<EFBFBD><C3BB><EFBFBD>: %s", MqttInfoStr.Username);
log_info("> <20><EFBFBD><E6B1BE><EFBFBD><EFBFBD>: %u", MqttInfoStr.Ver);
/* W25Q64 <20>ⲿ Flash<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD> OTA <20>̼<EFBFBD><CCBC>ݴ<EFBFBD> */
W25Q64_Init();
/* <20>ɼ<EFBFBD><C9BC>նˣ<D5B6><CBA3>޶ϵ<DEB6><CFB5><EFBFBD>¼/<2F>̵<EFBFBD><CCB5><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>س<EFBFBD>ʼ<EFBFBD><CABC>ȫ<EFBFBD><C8AB><EFBFBD>Ƴ<EFBFBD> */
gps_load_mode(); /* GPS <20><>λ<EFBFBD><CEBB><EFBFBD>أ<EFBFBD>EEPROM 173<37><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD> GPS0/1 <20>л<EFBFBD><D0BB><EFBFBD> */
/* <20><><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⣨PA0 ADC<44><43> */
adcInit();
/* RS485 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɼ<EFBFBD> */
sensor_init();
/* LED<45><44>LED2 <20><><EFBFBD><EFBFBD>ͬʱ<CDAC><CAB1><EFBFBD><EFBFBD><EFBFBD>ⲿ<EFBFBD><E2B2BF><EFBFBD>Ź<EFBFBD> TPL5010 ι<><CEB9><EFBFBD><EFBFBD> */
ledInit();
/* OLED <20><>Ļ<EFBFBD><C4BB>128x64 + GB2312 <20>ֿ<EFBFBD> IC<49><43> */
oled_init();
oled_locate(1, 1); oled_print("<EFBFBD><EFBFBD><EFBFBD>ݲɼ<EFBFBD><EFBFBD>ն<EFBFBD>");
oled_locate(2, 2); oled_print("V" FIRMWARE_VERSION_STR " RTOS");
log_info("> OLED: <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
/* <20><><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> EEPROM <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴγɹ<CEB3><C9B9><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ȣ<EFBFBD>4G <20><> WiFi<46><69> */
NET_init();
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD> */
USART2_StartRx(); /* RS485 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
USART3_StartRx(); /* 4G MQTT <20><>Ϣ<EFBFBD><CFA2>DMA+IDLE */
USART1_StartRx(); /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
/* <20>ϵ<EFBFBD><CFB5><EFBFBD> HLK-B40 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ MQTT ClientID<49><44><EFBFBD><EFBFBD>̨<EFBFBD><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
ble_at_init();
ble_setup_name();
}
/*==== net_task<73><6B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD>4G/WiFi <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>շ<EFBFBD><D5B7><EFBFBD>OTA<54><41>====*/
static void net_task(void *arg)
{
(void)arg;
for (;;) {
NET_process();
vTaskDelay(5);
}
}
/*==== app_task<73><6B>ҵ<EFBFBD><D2B5><EFBFBD>߼<EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD>/<2F>ϱ<EFBFBD>/OTA ȷ<>ϣ<EFBFBD>====*/
static void app_task(void *arg)
{
(void)arg;
/* <20><>ѭ<EFBFBD><D1AD>״̬<D7B4><CCAC><EFBFBD><EFBFBD> */
static uint8_t ota_confirmed = 0;
static uint8_t ota_simulate_fail = 0; /* =1<><31><EFBFBD>ԣ<EFBFBD>ģ<EFBFBD><C4A3> OTA ȷ<><C8B7>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD>֤<EFBFBD><D6A4><EFBFBD>ˣ<EFBFBD> */
static uint8_t ota_fail_logged = 0;
static uint32_t ota_confirm_tick = 0;
static uint8_t ota_report_pending = 0;
static uint32_t ota_report_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 (;;) {
/* <20><>¼ MQTT <20>״ξ<D7B4><CEBE><EFBFBD>ʱ<EFBFBD><CAB1> */
if (!mqtt_ready_recorded && g_net_mqtt_ready) {
mqtt_ready_recorded = 1;
mqtt_ready_tick = HAL_GetTick();
}
/* MQTT <20>״ξ<D7B4><CEBE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>һ<EFBFBD>ι̼<CEB9><CCBC><EFBFBD><E6B1BE><EFBFBD><EFBFBD>ƽ̨ˢ<CCA8>°汾<C2B0><E6B1BE><EFBFBD><EFBFBD> */
if (g_net_mqtt_ready && !mqtt_first_status_reported) {
mqtt_first_status_reported = 1;
{ /* ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>һ<EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><E6B1BE>"1.5.0:15"<22><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>汾 + EEPROM <20><EFBFBD><E6B1BE><EFBFBD>ţ<EFBFBD> */
char verbuf[24];
snprintf(verbuf, sizeof(verbuf), "%s:%u",
FIRMWARE_VERSION_STR, (unsigned)MqttInfoStr.Ver);
NET_publish_version(verbuf);
}
log_info("> Main: MQTT Ready <20><><EFBFBD>״<EFBFBD>״̬<D7B4>ϱ<EFBFBD>");
ota_confirm_tick = HAL_GetTick();
}
/* <20>״η<D7B4><CEB7><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD>ӳ<EFBFBD> 9s <20><> OTA ȷ<>ϣ<EFBFBD><CFA3>ܿ<EFBFBD><DCBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><E7B1A9>pow/ICCID/״̬/<2F><><EFBFBD>ܣ<EFBFBD> */
if (!ota_confirmed && g_net_mqtt_ready && g_net_first_publish_ok &&
(HAL_GetTick() - ota_confirm_tick) > 9000) {
if (ota_simulate_fail) {
if (!ota_fail_logged) {
ota_fail_logged = 1;
log_info("> OTA ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD>ڻ<EFBFBD><DABB>˲<EFBFBD><CBB2>ԣ<EFBFBD>");
}
/* <20><><EFBFBD><EFBFBD>λ ota_confirmed<65><64><EFBFBD><EFBFBD> 1 <20><><EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ */
} else {
ota_confirmed = 1;
if (NET_ota_confirm() < 0) { /* <0 <20><><EFBFBD><EFBFBD>δ<EFBFBD>ʹ1=<3D>޹<EFBFBD><DEB9><EFBFBD> OTA <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
ota_report_pending = 1; /* ֪ͨδ<D6AA>ʹ30s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
ota_report_tick = HAL_GetTick();
log_warn("> OTA ȷ<><C8B7>֪ͨδ<D6AA>ʹ<CDB4>Ժ<EFBFBD><D4BA><EFBFBD><EFBFBD><EFBFBD>");
} else {
log_info("> OTA <20><>ȷ<EFBFBD>ϣ<EFBFBD>MQTT Ready + <20>״η<D7B4><CEB7><EFBFBD><EFBFBD>ɹ<EFBFBD> + <20>ӳ<EFBFBD>9s<39><73>");
sensor_notify_ota_confirmed(); /* ê<><C3AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4>ƻ<EFBFBD> */
}
}
}
/* OTA ȷ<><C8B7>֪ͨδ<D6AA>ʹÿ 30s <20><><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD>ϱ<EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><CCA3><EFBFBD><EFBFBD><EFBFBD>ƽ̨֪ͨ<CDA8><D6AA> */
if (ota_report_pending && g_net_mqtt_ready &&
(HAL_GetTick() - ota_report_tick) > 30000) {
ota_report_tick = HAL_GetTick();
if (NET_ota_confirm() >= 0) {
ota_report_pending = 0;
log_info("> OTA ȷ<><C8B7>֪ͨ<CDA8><D6AA><EFBFBD>Գɹ<D4B3>");
}
}
/* MQTT <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD>״<EFBFBD> MPUB<55><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ */
if (!ota_confirmed && mqtt_ready_recorded &&
(HAL_GetTick() - mqtt_ready_tick) > OTA_HEALTH_TIMEOUT_MS) {
log_warn("> OTA <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ: MQTT Ready <20><> 1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MPUB<55><42><EFBFBD><EFBFBD>λ");
W25Q64_OTA_IncTrial(); /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ BL <20><><EFBFBD>ƴΣ<C6B4><CEA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>Դ<EFBFBD> */
HAL_Delay(100);
NVIC_SystemReset();
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD>ϱ<EFBFBD> */
sensor_process();
vTaskDelay(10);
}
}
/*==== OLED <20><><EFBFBD><EFBFBD>ˢ<EFBFBD>£<EFBFBD>1s һ<>Σ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD>/<EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬/<EFBFBD><EFBFBD><EFBFBD><EFBFBD>+<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
* δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> g_net_ui_phase <EFBFBD><EFBFBD>ʾ 4G/WiFi <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD>WiFi <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ 10s <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0/2/4px <EFBFBD>ֻ<EFBFBD> ====*/
static void oled_home_refresh(uint32_t up_ms);
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׶Σ<D7B6>app_init <20><><EFBFBD><EFBFBD> 4G <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* sys_task <EFBFBD><EFBFBD>û<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD> bg_delay ÿ 500ms <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ˢ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ */
void app_oled_presched_tick(void)
{
static uint32_t last = 0;
if (HAL_GetTick() - last < 500) return;
last = HAL_GetTick();
oled_home_refresh(0);
}
/* дһ<D0B4><D2BB><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>ո<EFBFBD><D5B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڳ<EFBFBD><DAB3><EFBFBD><EFBFBD>У<EFBFBD><D0A3>ٴ<EFBFBD>ƫ<EFBFBD>ƴ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD> */
static void oled_row(uint8_t row, uint8_t xoff, const char *s)
{
/* <20><><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD>ǯλ<C7AF><CEBB><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ұ߽<D2B1> */
uint8_t w = oled_text_w(s);
if (xoff > 0 && (uint16_t)xoff + w > 128) xoff = 128 - w;
if (xoff) {
oled_locate(row, 0);
for (uint8_t c = 0; c < xoff; c += 8) oled_print(" "); /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڳ<EFBFBD><DAB3><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
oled_locate(row, 0);
}
oled_locate(row, 0);
oled_xoff(xoff);
oled_print_line(s);
}
static void oled_home_refresh(uint32_t up_ms)
{
char buf[24];
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ 10s <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30>24<32><34>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD>Զ<EFBFBD>ǯλ<C7AF><CEBB> */
uint8_t phase = (uint8_t)((HAL_GetTick() / 10000u) % 8u);
uint8_t xoff = (phase <= 4u) ? phase * 6u : (8u - phase) * 6u;
if (g_net_mqtt_ready) {
/*---- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6A3A8><EFBFBD>в<EFBFBD><D0B2>֣<EFBFBD> ----*/
/* R0: <20><>=<3D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD>=<3D><><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>10s ˢһ<CBA2><D2BB> ADC<44><43> */
{
static uint32_t bat_tick = 0;
static int bat_val = 0;
if (HAL_GetTick() - bat_tick >= 10000u) {
bat_tick = HAL_GetTick();
bat_val = battery_percent();
}
char left[8], right[8];
char r0[40];
const char *nt = (NET_GetActiveBackend() == NET_BACKEND_WIFI) ? "WiFi" : "4G";
snprintf(left, sizeof(left), "%s", nt);
snprintf(right, sizeof(right), "%d%%", bat_val);
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ո<EFBFBD> 8px/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E5A3A9>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 4px<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x=0 <EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ñ<EFBFBD> */
int wl = oled_text_w(left), wr = oled_text_w(right);
int pos;
strcpy(r0, left); pos = wl;
int right_pos = 104 - wr; /* <20>ұ߽<D2B1><DFBD><EFBFBD><EFBFBD>գ<EFBFBD><D5A3><EFBFBD><EFBFBD>ݶ<EFBFBD><DDB6><EFBFBD> 128 ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǯλ<C7AF><CEBB><EFBFBD><EFBFBD> xoff <20><><EFBFBD><EFBFBD> */
while (pos < right_pos) { strcat(r0, " "); pos += 8; }
strcat(r0, right);
oled_row(0, (uint8_t)(xoff + 4), r0);
}
/* R1: <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1> <20><>:ʱ:<3A><> */
{
uint32_t mins = up_ms / 60000u;
snprintf(buf, sizeof(buf), "%02u:%02u:%02u",
(unsigned)(mins / 1440u),
(unsigned)((mins % 1440u) / 60u),
(unsigned)(mins % 60u));
oled_row(1, xoff, buf);
}
/* R2/R3: <20><><EFBFBD>ߴ<EFBFBD><DFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3>ʾ<EFBFBD><CABE>һҳһ·<D2BB><C2B7>5s <20><>ҳ<EFBFBD><D2B3> */
{
char l1[24], l2[24];
if (sensor_oled_summary(l1, l2, sizeof(l1))) {
oled_row(2, xoff, l1);
oled_row(3, xoff, l2);
} else {
oled_row(2, xoff, "<EFBFBD>޴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>");
oled_row(3, xoff, "");
}
}
} else {
/*---- δ<><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ----*/
net_ui_phase_t ph = g_net_ui_phase;
oled_row(0, xoff, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
if (ph == NET_UI_WIFI_FIXED || ph == NET_UI_WIFI_SMART ||
NET_GetActiveBackend() == NET_BACKEND_WIFI) {
if (ph == NET_UI_WIFI_FIXED) {
oled_row(1, xoff, "WiFi<EFBFBD>̶<EFBFBD>ģʽ");
oled_row(2, xoff, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD>");
} else if (ph == NET_UI_WIFI_SMART) {
oled_row(1, xoff, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
oled_row(2, xoff, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>APP<EFBFBD>");
} else {
oled_row(1, xoff, "WiFiģʽ");
oled_row(2, xoff, "<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...");
}
snprintf(buf, sizeof(buf), "ʣ<EFBFBD><EFBFBD> %ds", g_net_ui_countdown);
oled_row(3, xoff, g_net_ui_countdown > 0 ? buf : "");
} else {
/* 4G <20><><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵĽ׶<C4BD> */
const char *step = "<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
switch (ph) {
case NET_UI_4G_RESET: step = "ģ<EFBFBD>鸴λ<EFBFBD>ɹ<EFBFBD>"; break;
case NET_UI_4G_AT: step = "ATָ<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>"; break;
case NET_UI_4G_SIM: step = "SIM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>"; break;
case NET_UI_4G_ATTACH: step = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>"; break;
case NET_UI_4G_MQTT: step = "<EFBFBD><EFBFBD><EFBFBD>ӷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"; break;
case NET_UI_4G_NOSIM: step = "<EFBFBD><EFBFBD>SIM<EFBFBD><EFBFBD>!"; break;
default: break;
}
oled_row(1, xoff, "<EFBFBD><EFBFBD><EFBFBD>ڵȴ<EFBFBD>4G<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
oled_row(2, xoff, step);
oled_row(3, xoff, "");
}
}
}
/*==== sys_task<73><6B>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>LED/<2F><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>====*/
static void sys_task(void *arg)
{
(void)arg;
uint32_t up_last = HAL_GetTick();
uint32_t up_print = HAL_GetTick();
uint32_t disp_tick = HAL_GetTick();
uint64_t up_ms = 0;
for (;;) {
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
process_usart1_command();
/* <20><><EFBFBD><EFBFBD>ָʾ<D6B8><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˸<EFBFBD><CBB8><EFBFBD><EFBFBD><EFBFBD>ϳ<EFBFBD><CFB3><EFBFBD><EFBFBD><EFBFBD>led.c activeEvents <20>ݴ˿<DDB4><CBBF><EFBFBD> PA1<41><31> */
g_net_led_connected = g_net_mqtt_ready ? 1 : 0;
/* LED <20><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD>ָʾ */
activeEvents();
/* OLED <20><><EFBFBD><EFBFBD> 1s ˢ<><CBA2> */
if (HAL_GetTick() - disp_tick >= 1000) {
disp_tick = HAL_GetTick();
oled_home_refresh(up_ms);
}
/* <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ 60s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>Σ<EFBFBD><CEA3><EFBFBD>/ʱ/<2F>֣<EFBFBD><D6A3><EFBFBD>
* δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
* 64 λ<EFBFBD>ۼƣ<EFBFBD>HAL_GetTick Լ 49 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><EFBFBD> */
{
uint32_t now = HAL_GetTick();
up_ms += (uint32_t)(now - up_last); /* 32λ<32><CEBB>ֵ<EFBFBD><D6B5>Ȼ<EFBFBD><C8BB><EFBFBD>̻<EFBFBD><CCBB><EFBFBD> */
up_last = now;
if (now - up_print >= 60000) {
up_print = now;
if (g_net_mqtt_ready) {
uint32_t mins = (uint32_t)(up_ms / 60000);
log_info(FMT_UPTIME,
(unsigned)(mins / 1440),
(unsigned)((mins % 1440) / 60),
(unsigned)(mins % 60));
}
}
}
vTaskDelay(20);
}
}
/*==== FreeRTOS <20><><EFBFBD><EFBFBD> ====*/
/* idle <20><><EFBFBD>ӣ<EFBFBD>ι<EFBFBD><CEB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ź<EFBFBD><C5B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>ռ CPU ʱ idle <20><><EFBFBD><EFBFBD> <20><> IWDG <20><>λ */
void vApplicationIdleHook(void)
{
IWDG_Feed();
}
void vApplicationMallocFailedHook(void)
{
log_error("> RTOS: malloc ʧ<>ܣ<EFBFBD><DCA3>Ѻľ<D1BA><C4BE><EFBFBD>");
taskDISABLE_INTERRUPTS();
for (;;) { }
}
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
{
(void)xTask;
log_error("> RTOS: <20><><EFBFBD><EFBFBD> %s ջ<><D5BB><EFBFBD><EFBFBD>", pcTaskName);
taskDISABLE_INTERRUPTS();
for (;;) { }
}
/*==== <20><><EFBFBD>񴴽<EFBFBD><F1B4B4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>main <20><><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>ٷ<EFBFBD><D9B7>أ<EFBFBD>====*/
void app_rtos_start(void)
{
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>񴴽<EFBFBD> */
log_lock_init();
storage_lock_init();
NET_LockInit();
xTaskCreate(net_task, "net", 768, NULL, 3, NULL); /* ջ 3KB<4B><42>AT/OTA <20>д<EFBFBD><D0B4><EFBFBD> sprintf <20><><EFBFBD><EFBFBD> */
xTaskCreate(app_task, "app", 512, NULL, 2, NULL); /* ջ 2KB */
xTaskCreate(sys_task, "sys", 512, NULL, 1, NULL); /* ջ 2KB<4B><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־һ<D6BE><D2BB> 4 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ܳ<EFBFBD>ջ */
vTaskStartScheduler();
/* <20><><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD><DFB5><EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD><D1B2><EFBFBD><E3B4B4>ʧ<EFBFBD>ܲŻᣩ */
log_error("> RTOS: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>");
for (;;) { }
}