# BR_YKC 充电桩网关 基于 STM32H743 + AIR724 4G模块 的充电桩网关方案,对接**云快充**平台,支持通过**4G TCP**和**以太网UDP**双通道通信。 --- ## 目录 - [硬件架构](#硬件架构) - [软件架构](#软件架构) - [目录结构](#目录结构) - [通信拓扑](#通信拓扑) - [三层状态机](#三层状态机) - [通信协议](#通信协议) - [南向协议(网关 ↔ 桩)](#南向协议网关--桩) - [上位机协议(网关 ↔ 上位机APP)](#上位机协议网关--上位机app) - [北向协议(网关 ↔ 云快充)](#北向协议网关--云快充) - [4G链路协议(STM32 ↔ AIR724)](#4g链路协议stm32--air724) - [上位机 C# 客户端](#上位机-c-客户端) - [项目结构](#项目结构) - [页面功能](#页面功能) - [通信机制](#通信机制) - [数据存储](#数据存储) - [配置参数](#配置参数) - [配置指南](#配置指南) - [修改桩编码(序列号)](#修改桩编码序列号) - [修改桩数量](#修改桩数量) - [修改每桩枪数](#修改每桩枪数) - [配置云快充服务器地址](#配置云快充服务器地址) - [Flash组件使用说明](#flash组件使用说明) - [框架层 drv_flash](#框架层-drv_flash) - [应用层 flash_config](#应用层-flash_config) - [使用示例](#使用示例) - [任务列表](#任务列表) - [日志格式](#日志格式) --- ## 硬件架构 ``` ┌──────────────────────────────────────────────┐ │ STM32H743 │ │ │ │ UART1 ─── 4G模块(AIR724) ──→ 云快充平台 (TCP)│ │ UART3 ─── RS485 │ │ ETH ──── LAN (UDP, 桩1~6 + 上位机) │ │ UART6 ─── 调试串口(printf) │ └──────────────────────────────────────────────┘ ``` | 外设 | 用途 | |------|------| | UART1 (115200) | 与AIR724 4G模块通信 | | UART3 | RS485接口 | | ETH (LWIP) | 以太网,桩1~6 UDP通信 + 上位机 | | UART6 | printf调试输出 | --- ## 软件架构 ``` Os/ 任务/队列/信号量/定时器管理 ├─ os_task.c 5个任务的创建 ├─ os_queue.c 3个消息队列 ├─ os_timer.c 软件定时器 └─ os_semaphore.c 信号量/互斥量 App/ 应用层任务 ├─ task_air724 4G下行数据解析任务 ├─ task_udp UDP收发 + 解析任务 ├─ task_ykc 云快充核心状态机任务 └─ task_sys 系统任务(心跳指示、喂狗) Driver/ 驱动层 ├─ drv_air724 AIR724命令收发 + 响应解析 ├─ drv_usart 串口收发(含互斥锁) ├─ drv_flash 通用Flash读写框架 └─ flash_config 应用层Flash配置 Network/ 网络层 ├─ udp_manager UDP报文发送 └─ udp_router UDP路由分发 Protocol/ 协议层 ├─ Point/ 南向(充电桩JSON) ├─ Host Computer/ 上位机JSON通信 └─ Ykc/ 北向(云快充字节协议) ├─ charger_to_server 上行帧 ├─ server_to_charger 下行帧 ├─ server_common 公共(组包/解包/CRC) └─ ykc_router 帧类型路由分发 Global/ 全局数据 ├─ g_dcpile 桩/枪 结构体 + 管理器 ├─ g_init 全局初始化 ├─ g_runtime 运行时统计 └─ board_config 板级配置(IP/端口) 4G/ 4G模块Lua固件 ├─ core/main.lua 入口:初始化+串口+网络 ├─ core/cmd.lua 命令解析+分发 └─ core/linksocket.lua 多路TCP socket管理 ``` --- ## 通信拓扑 ``` 云快充服务器(TCP) ↑ │ 4G AIR724模块 ↑ UART1 ┌─────────┴──────────┐ │ STM32H743 网关 │ │ (协议转换器) │ └─────────┬──────────┘ UDP │ 以太网 ┌─────────────┼─────────────┐ │ │ │ 桩1~6 上位机 RS485设备 (10.12.19.101~106) (107) (触摸屏等) ``` **数据路径:** - **云快充 → 桩**:云快充TCP → 4G → UART1 → STM32解析 → 填充数据到桩结构体 - **桩上报 → 云快充**:桩 → UDP → STM32 → 打包Ykc帧 → UART1 → 4G → TCP → 云快充 - **上位机查询**:上位机 → UDP → STM32 → 查询桩数据 → 回复 --- ## 三层状态机 [task_ykc.c](file:///d:/公司项目/BR_YKC/Core/User/App/task_ykc.c) 实现了 **桩层 + 枪层** 两层非阻塞时间片状态机: ### 桩层初始化(桩0~2通用,只做一次) ``` step 0 ── 等待桩UDP上电 → 连接4G通道(i+1) ↓ (socket_connected[i] == true) step 1 ── 发送云快充登录(0x01) ↓ (is_online == true) step 2 ── 发送计费模型验证(0x05) + 请求(0x09) ↓ (get_model == true) step 3 ── 进入枪层运行态 ``` ### 枪层运行(每把枪独立) ``` gun_step 0 ── 每5秒上传实时数据(0x13) + 主动上报到上位机 如有账单(is_get_bill==true),上传交易记录(0x3B) ``` ### 非阻塞机制 所有 `osDelay()` 已被替换为**时间戳轮询**: ```c now = HAL_GetTick(); if (now < pile->step_tick) // 时间没到,立即跳过,不阻塞 continue; // 执行动作 pile->step_tick = now + 5000; // 设定5秒后的下次超时 ``` 6个桩每轮循环只需微秒级完成,互不阻塞。 --- ## 通信协议 ### 南向协议(网关 ↔ 桩) - **传输**:以太网 UDP - **端口**:Server=6001, Stake=6001, App=6002 - **桩IP**:10.12.19.101 ~ 106 - **格式**:JSON **路由表** [udp_router.c](file:///d:/公司项目/BR_YKC/Core/User/Network/udp_router.c): | cmd | 桩ID来源 | 处理函数 | 说明 | |-----|---------|----------|------| | `online` | 桩1~6 | `point_callback_power_on` | 上电,设置 is_udp_online | | `heartbeat` | 桩1~6 | `point_callback_heartbeat` | 心跳 | | `start charging` | 桩1~6 | `point_callback_start_charging` | 开始充电反馈 | | `end charging` | 桩1~6 | `point_callback_end_charging` | 停止充电反馈 | | `realtime data` | 桩1~6 | `point_callback_realtime_data` | 实时数据 | | `settlement bill` | 桩1~6 | `point_callback_settlement_bill` | 结算账单 | | `proactive end charging` | 桩1~6 | `point_callback_proactive_end_charging` | 桩主动停止 | | `charge process real` | 桩1~6 | `point_callback_charge_process` | BMS需求 | | `bms info real` | 桩1~6 | `point_callback_bms_info` | BMS信息 | **桩未上电拦截**:除 `online` 外,所有桩指令都会检查 `is_udp_online`,未上电的桩指令将被静默丢弃。 ### 上位机协议(网关 ↔ 上位机APP) - **传输**:以太网 UDP(同一通道) - **端口**:Server=6001, App=6002 - **上位机ID**:7 - **格式**:JSON,含 `request_id` + `success` **指令表** [host_computer_protocol.h](file:///d:/公司项目/BR_YKC/Core/User/Protocol/Host%20Computer/host_computer_protocol.h): | cmd | 功能 | 处理函数 | 回复字段 | |-----|------|----------|----------| | `server_login` | 登录 | `host_computer_on_login` | success | | `server_get_status` | 获取所有桩状态 | `host_computer_on_get_status` | piles[].serial/is_online/guns[].status | | `server_reboot` | 重启网关 | `host_computer_on_reboot` | 无(立即重启) | | `gateway_get_info` | 查询网关信息 | `host_computer_on_get_gw_info` | device_id, software_ver, hardware_ver, uptime | | `gateway_get_4g_status` | 查询4G状态 | `host_computer_on_get_4g_status` | iccid, net_status, signal, isp | | `gateway_get_cloud_config` | 查询云配置 | `host_computer_on_get_cloud_config` | host, port | | `gateway_set_cloud_config` | 设置云配置 | `host_computer_on_set_cloud_config` | host, port(触发重连) | | `gateway_get_net_config` | 查询网络配置 | `host_computer_on_get_net_config` | ip, mask, gateway, dns | | `gateway_set_net_config` | 设置网络配置 | `host_computer_on_set_net_config` | success(重启生效) | | `server_get_pile_info` | 查询单个桩信息 | `host_computer_on_get_pile_info` | serial, type, gun_num, protocol_ver, software_ver, sim | ### 北向协议(网关 ↔ 云快充) - **传输**:4G TCP - **数据格式**:字节流,含CRC16校验 - **封装**:`55 AA 01 socketId len [ykc_frame] AA 55` #### YKC帧格式 ``` ┌────────┬──────┬────────┬─────────┬────────┬──────────┬──────┐ │ 0x68 │ len │ serial │encrypt │type │ data │ crc │ │ (起始) │(1字节)│ (2字节)│ (1字节) │(1字节) │ (n字节) │2字节│ └────────┴──────┴────────┴─────────┴────────┴──────────┴──────┘ ``` #### 帧类型(上行 → 云快充) | type | 函数 | 说明 | |------|------|------| | 0x01 | `charger_to_server_0X01` | 登录认证 | | 0x03 | `charger_to_server_0X03` | 心跳 | | 0x05 | `charger_to_server_0X05` | 计费模型验证 | | 0x09 | `charger_to_server_0X09` | 计费模型请求 | | 0x13 | `charger_to_server_0X13` | 实时监测数据 | | 0x19 | `charger_to_server_0X19` | 充电结束 | | 0x33 | `charger_to_server_0X33` | 远程启动回复 | | 0x35 | `charger_to_server_0X35` | 远程停机回复 | | 0x3B | `charger_to_server_0X3B` | 交易记录 | | 0x57 | `charger_to_server_0x57` | 计费模型应答 | #### 帧类型(下行 ← 云快充) | type | 处理函数 | 说明 | |------|----------|------| | 0x02 | `on_cmd_frame_type_0X02` | 登录认证应答 | | 0x04 | `on_cmd_frame_type_0X04` | 心跳应答 | | 0x06 | `on_cmd_frame_type_0X06` | 计费模型验证应答 | | 0x0A | `on_cmd_frame_type_0X0A` | 获取计费模型 | | 0x58 | `on_cmd_frame_type_0X58` | 计费模型设置 | | 0x34 | `on_cmd_frame_type_0X34` | 平台启动充电 | | 0x36 | `on_cmd_frame_type_0X36` | 平台控制停止充电 | | 0x40 | `on_cmd_frame_type_0X40` | 交易记录确认 | ### 4G链路协议(STM32 ↔ AIR724) AIR724模块内部运行Lua脚本 [cmd.lua](file:///d:/公司项目/BR_YKC/4G/code/core/cmd.lua) + [linksocket.lua](file:///d:/公司项目/BR_YKC/4G/code/core/linksocket.lua): ``` 55 AA mainCmd subCmd [payload] AA 55 ``` | mainCmd | subCmd | 功能 | |---------|--------|------| | 0x01 | socketId | 数据发送到指定Socket | | 0x02 | - | 系统重启 | | 0x03 | 0x01/0x02 | 连接/断开Socket | | 0x04 | 0x00 | 设置服务器地址 | | 0x05 | 0x01~0x03 | 查询ICCID/IMSI/IMEI | | 0x06 | 0x00 | 查询信号强度 | | 0x07 | 0x00 | 查询链路状态 | **上行响应(4G → STM32)**: | mainCmd | subCmd | 含义 | |---------|--------|------| | 0x83 | 0x01 | TCP已连接 | | 0x83 | 0x02 | TCP已断开 | | 0x83 | 0x03 | TCP连接失败 | | 0x84 | 0x01~0x03 | SIM信息(ICCID/IMSI/IMEI) | | 0x85 | - | 信号强度 | | 0x86 | - | 链路状态 | --- ## 上位机 C# 客户端 C# 上位机客户端项目位于 `C:\Users\Administrator\PycharmProjects\PythonProject\C#\YKC`,基于 **.NET Framework 4.7.2** + **WPF** 框架开发,通过 **UDP** 与网关通信。 ### 项目结构 ``` YKC/ ├── App.xaml(.cs) 程序入口 ├── MainWindow.xaml(.cs) 主窗口(导航框架) ├── LoginWindow.xaml(.cs) 登录窗口 ├── Config.cs 配置参数 + 指令字典 ├── UdpClient.cs UDP通信客户端(同步/异步) ├── PilesDataStore.cs 充电桩历史数据存储(含图表数据) │ ├── Pages/ │ ├── DashboardPage.xaml(.cs) 总览页面 │ ├── RealtimePage.xaml(.cs) 实时监控(含OxyPlot图表) │ ├── ChargerPage.xaml(.cs) 充电桩管理 │ └── GatewayPage.xaml(.cs) 网关管理 │ ├── bin/Debug/ │ ├── OxyPlot.dll 波形图库 │ ├── OxyPlot.Wpf.dll │ ├── OxyPlot.Wpf.Shared.dll │ └── Newtonsoft.Json.dll JSON库 │ └── Properties/ 项目属性 ``` ### 页面功能 #### 1. 登录页面 (LoginWindow) - 用户名/密码认证 - 发送 `server_login` → 网关返回 `success: true/false` - 默认账号:`admin` / `123456` #### 2. 总览页面 (DashboardPage) - **连接状态**:显示网关在线/离线 - **在线/充电统计**:在线桩数、充电中枪数 - **表格列表**:每桩的序列号、在线状态、每枪状态 - 每 **5秒** 自动轮询 `server_get_status` | 枪状态 | 含义 | |--------|------| | 0 | 离线 | | 1 | 故障 | | 2 | 空闲 | | 3 | 充电中 | #### 3. 实时监控页面 (RealtimePage) - 选择桩号(1~N) + 枪号(1~N) - 实时显示:电流(A)、电压(V)、功率(kW)、电量(kWh)、总金额、SOC、累计时间、剩余时间 - **OxyPlot 实时曲线**: - 电流/电压/功率 折线图(含时间轴,最多300个点) - 电费/服务费/总金额 柱状图 - 每 **2秒** 自动轮询 `report_data` 主动上报数据(来自PilesDataStore历史记录) #### 4. 充电桩管理页面 (ChargerPage) **查询桩信息**: - 按桩索引查询 - 回复显示:序列号、类型(直流/交流)、枪数、协议版本、软件版本、SIM **设置桩ID**: - 输入桩索引 + 14位HEX序列号 **重启网关**: - 发送 `server_reboot`(确认弹窗) #### 5. 网关管理页面 (GatewayPage) **网关信息卡片**: - 设备ID、软件版本、硬件版本、运行时长 - 调用 `gateway_get_info` **4G状态卡片**: - ICCID、网络状态、信号强度(dBm)、运营商 - 调用 `gateway_get_4g_status` **云平台配置卡片**: - 查询(`gateway_get_cloud_config`) / 保存(`gateway_set_cloud_config`) - 保存时验证:IP格式或域名格式,端口 1~65535 **网络配置卡片**: - IP/掩码/网关/DNS 查询 + 设置 - 调用 `gateway_get_net_config` / `gateway_set_net_config` - 支持IP地址格式校验 ### 通信机制 UDP通信封装在 [UdpClient.cs](file:///C:/Users/Administrator/PycharmProjects/PythonProject/C%23/YKC/UdpClient.cs): **消息格式**: ```json { "id": 7, // 固定ID=7(上位机) "cmd": "server_login", "request_id": "server_login_1700000000000", ...其他参数... } ``` **回复格式**: ```json { "request_id": "server_login_...", "success": true, ...其他数据... } ``` **两种发送模式**: | 方法 | 说明 | |------|------| | `Send(payload, callback)` | 异步发送,通过回调接收回复 | | `SendSync(payload, timeoutSec?)` | 同步发送,阻塞等待回复或超时(默认4秒) | **超时机制**:异步请求启动定时器,超时后自动回调 `{ success: false, error: "timeout" }` **主动上报接收**:`OnActiveReport` 事件监听 `cmd == "report_data"` / `"pile_metrics"` / `"real_time_data"`,由 `PilesDataStore` 订阅存储。 **监听端口**:`Config.LocalPort = 6002`,目标网关 `Config.TargetIp:Config.TargetPort`(默认 `10.12.19.100:6001`) ### 数据存储 [PilesDataStore.cs](file:///C:/Users/Administrator/PycharmProjects/PythonProject/C%23/YKC/PilesDataStore.cs) 单例模式管理: - **实时数据**:`GetLatest(pile, gun)` → 最新一条 `JObject` - **图表数据**:`GetChartData(pile, gun)` → `GunData` 对象,内含最多300个历史点的电流/电压/功率/电量/金额等序列 - **历史清理**:超过300个点自动移除旧数据 ### 配置参数 [Config.cs](file:///C:/Users/Administrator/PycharmProjects/PythonProject/C%23/YKC/Config.cs): ```csharp TargetIp = "10.12.19.100"; // 网关IP TargetPort = 6001; // 网关UDP端口 LocalPort = 6002; // 本机监听端口 UdpTimeout = 3; // 超时时间(秒) ``` **指令字典**(与网关 `udp_router.c` 路由表对应): | 常量 | cmd | 对应网关处理函数 | |------|-----|------------------| | `LOGIN` | `server_login` | `host_computer_on_login` | | `GET_STATUS` | `server_get_status` | `host_computer_on_get_status` | | `REBOOT` | `server_reboot` | `host_computer_on_reboot` | | `GET_PILE_INFO` | `server_get_pile_info` | `host_computer_on_get_pile_info` | | `GET_GW_INFO` | `gateway_get_info` | `host_computer_on_get_gw_info` | | `GET_4G_STATUS` | `gateway_get_4g_status` | `host_computer_on_get_4g_status` | | `GET_CLOUD_CONFIG` | `gateway_get_cloud_config` | `host_computer_on_get_cloud_config` | | `SET_CLOUD_CONFIG` | `gateway_set_cloud_config` | `host_computer_on_set_cloud_config` | | `GET_NET_CONFIG` | `gateway_get_net_config` | `host_computer_on_get_net_config` | | `SET_NET_CONFIG` | `gateway_set_net_config` | `host_computer_on_set_net_config` | | `SET_PILE_ID` | `server_set_pile_id` | 待开发 | | `REPORT_DATA` | `report_data` | 主动上报(南向) | --- ## 配置指南 ### 修改桩编码(序列号) 修改 [g_dcpile.c](file:///d:/公司项目/BR_YKC/Core/User/Global/g_dcpile.c) 中的 `piles_serial` 数组,每个桩编码为7字节十六进制: ```c /*充电桩序列号*/ const uint8_t piles_serial[6][7] = { {0x32, 0x01, 0x06, 0x01, 0x16, 0x92, 0x45}, // 桩1 {0x32, 0x01, 0x06, 0x01, 0x16, 0x92, 0x44}, // 桩2 {0x32, 0x01, 0x06, 0x01, 0x16, 0x92, 0x43}, // 桩3 {0x32, 0x01, 0x06, 0x01, 0x16, 0x92, 0x42}, // 桩4 {0x32, 0x01, 0x06, 0x01, 0x11, 0x15, 0x58}, // 桩5 {0x32, 0x01, 0x06, 0x01, 0x11, 0x15, 0x54}, // 桩6 }; ``` > `init_chargers()` 中通过 `memcpy(ctx->charger_serial, piles_serial[i], CHARGER_SERIAL_LENGTH)` 加载。 序列号转换为字符串显示时表现为14位HEX码,例如 `32010601169244`。 ### 修改桩数量 **两步:** **①** 修改 [g_dcpile.h](file:///d:/公司项目/BR_YKC/Core/User/Global/g_dcpile.h) 中的宏: ```c #define MAX_CHARGER_COUNT 2 // ← 改为实际桩数量 ``` **②** 确保 [g_dcpile.c](file:///d:/公司项目/BR_YKC/Core/User/Global/g_dcpile.c) 中的 `piles_serial` 数组有对应数量的序列号。 同时需要修改 [udp_router.c](file:///d:/公司项目/BR_YKC/Core/User/Network/udp_router.c) 中 `ROUTE_TABLE` 的路由数量(如果新增桩路由),以及 [task_ykc.c](file:///d:/公司项目/BR_YKC/Core/User/App/task_ykc.c) 中状态机的循环 `for (int i = 0; i < g_charger_manager.charger_count; i++)` 已自动适配。 > 桩1~6的UDP IP地址在 [udp_manager.c](file:///d:/公司项目/BR_YKC/Core/User/Network/udp_manager.c) 中硬编码: > ```c > static ip4_addr_t s_point_ip[6] = { > IPADDR4_INIT_BYTES(10, 12, 19, 101), /* 桩1 */ > IPADDR4_INIT_BYTES(10, 12, 19, 102), /* 桩2 */ > ... > }; > ``` > 如果桩数量变化,需要同步更新此数组。 ### 修改每桩枪数 修改 [g_dcpile.h](file:///d:/公司项目/BR_YKC/Core/User/Global/g_dcpile.h): ```c #define MAX_GUN_PER_CHARGER 2 // ← 改为实际枪数 ``` 状态机中的枪循环已自动适配: ```c for (int g = 0; g < MAX_GUN_PER_CHARGER; g++) ``` ### 配置云快充服务器地址 默认在 [linksocket.lua](file:///d:/公司项目/BR_YKC/4G/code/core/linksocket.lua) 中: ```lua local server_config = { ip = "129.211.170.245", port = 9002 } ``` 可通过上位机指令 `gateway_set_cloud_config` 动态修改 `s_cloud_host` / `s_cloud_port`,修改后调用 `drv_air724_set_server` 触发AIR724重新连接。 --- ## Flash组件使用说明 Flash存储组件分为**两层**: ### 框架层 drv_flash [drv_flash.h](file:///d:/公司项目/BR_YKC/Core/User/Driver/drv_flash.h) / [drv_flash.c](file:///d:/公司项目/BR_YKC/Core/User/Driver/drv_flash.c) 提供通用Flash读写管理,支持按帧类型存取、覆写模式、多帧管理。 #### 帧格式 ``` ┌──────┬──────┬──────┬──────┬──────────┬──────┐ │ HEAD │ size_low │size_high│type│ DATA │ TAIL │ │(0xA5)│ (2字节 小端) │(1字节)│(n字节) │(0x5A)│ └──────┴──────┴──────┴──────┴──────────┴──────┘ ``` #### 核心API | 函数 | 说明 | |------|------| | `flash_manage_init(flash_manage_t *fm)` | 初始化:遍历Flash重建可读帧表 | | `flash_manage_read(fm, *pbuf, frame_type)` | 读取指定类型的帧数据 | | `flash_manage_write(fm, *pbuf, size, frame_type)` | 写入指定类型的帧数据 | #### flash_manage_t 配置 ```c typedef struct { uint8_t align_num; // 地址对齐数(STM32H7一般为32) flash_write_read_mode_t flash_write_mode; // 写模式 flash_write_read_mode_t flash_read_mode; // 读模式 uint32_t flash_start_address; // 管理起始地址(按扇区对齐) uint32_t manage_sector_num; // 管理的扇区数 uint32_t sector_size; // 扇区大小(H743=128KB) void (*read_flash)(...); // 读函数指针 void (*write_flash)(...); // 写函数指针 uint8_t (*erase_sector)(...); // 擦除函数指针 } flash_manage_t; ``` ### 应用层 flash_config [flash_config.h](file:///d:/公司项目/BR_YKC/Core/User/Driver/flash_config.h) / [flash_config.c](file:///d:/公司项目/BR_YKC/Core/User/Driver/flash_config.c) 基于框架层的封装,提供开箱即用的API: ```c // 单例,地址=0x08180000,1个Sector(128KB),32字节对齐 void stm_flash_init(void); // 读取,传入缓冲区 + 帧类型,成功返回1 int8_t stm_flash_read(uint8_t *pbuf, uint8_t frame_type); // 写入,传入数据 + 大小 + 帧类型,成功返回1 int8_t stm_flash_write(uint8_t *pbuf, uint16_t size, uint8_t frame_type); ``` > **注意**:STM32H743 Bank2 的 Sector 擦除规则: > - 起始地址 `0x08100000`,每Sector = 128KB > - 写入必须 **32字节对齐**,不满32字节补 `0xFF` > - `flash_config.c` 使用 `0x08180000`(Bank2的第4个Sector) ### 使用示例 ```c #include "flash_config.h" // 初始化(在main中调用一次) stm_flash_init(); // 写入配置数据 uint8_t config_data[] = {0x01, 0x02, 0x03, 0x04}; stm_flash_write(config_data, sizeof(config_data), 0x01); // 帧类型1 // 读取配置数据 uint8_t read_buf[64] = {0}; if (stm_flash_read(read_buf, 0x01) == 1) { // 读取成功,read_buf中为数据 } else { // 无数据 } ``` **写模式**: | 模式 | 值 | 说明 | |------|----|------| | `FLASH_NO_OVERWRITING_MODE` | 0x00 | 只追加,不覆盖旧帧 | | `FLASH_OVERWRITING_MODE` | 0x01 | 将旧帧头置为无效,写新帧(默认) | **读模式**: | 模式 | 值 | 说明 | |------|----|------| | `FLASH_NO_CLEAR_MODE` | 0x02 | 读取后不清除(默认) | | `FLASH_CLEAR_MODE` | 0x03 | 读取后将帧标记为无效 | --- ## 任务列表 | 任务 | 函数 | 栈大小 | 优先级 | 说明 | |------|------|--------|--------|------| | SysTask | `sys_task_function` | 128 | Low | 指示灯、蜂鸣器、喂狗 | | Air724RecvTask | `air724_recv_task_function` | 1024 | AboveNormal | 解析4G下行数据 | | UDPRecvTask | `udp_recv_task_function` | 1536 | High | UDP接收入队 | | UDPParseTask | `udp_parse_task_function` | 2048 | AboveNormal | UDP数据解析+路由分发 | | YkcTask | `ykc_task_function` | 1024 | AboveNormal | 云快充状态机+数据上报 | ### 消息队列 | 队列 | 长度 | 消息大小 | 用途 | |------|------|----------|------| | Air724_Message_Queue | 20 | 512 | 4G接收数据 | | RS485_Message_Queue | 5 | 256 | RS485接收数据 | | UDP_Message_Queue | 20 | sizeof(UdpMsg_t) | UDP接收数据 | --- ## 日志格式 ``` [YKC Router] frame=0x02 │ stake=1 │ 登录认证应答 ← 4G下行路由 [ UDP 接收路由 ] 指令: realtime data │ 桩ID: 1 │ 实时数据 ← 南向UDP [ UDP 路由拦截 ] 桩ID: 2 未上电,忽略指令: heartbeat ← 上电过滤 [ 北向 ] 对电桩 1 发送登录认证 ← 4G上行 [ 北向 ] 对电桩 1 枪 1 上传交易记录(0x3B),电量:0.00,金额:0.00 ← 4G上行 [ 4G ] 通道 1 连接成功 ← 4G链路通知 [ 上位机 ] get_status 回复已发送 ← 上位机回复 ```