main.c
main() 启动时序(main.c:348-369)4.2 start_task() 的任务创建表(main.c:140-339)4.3 event_init() 事件对象创建(main.c:74-131)4.4 快调度事件标志流水线 g_t_fast_dispatch_flag4.5 定时/调度时序小结4.6 关键全局变量在本文件中的读写5. 对外接口6. 依赖关系7. 备注与风险点源文件路径:
user/main.c所属模块:user(主程序入口 / 系统启动与任务编排) 代码行数:370
1. 文件职责
本文件是整个 EMS 3.6 固件的唯一入口与任务总编排点。main() 只做三件事:把 CPU 全中断打开、把时钟/延时/板级外设初始化好、调用 OSInit() 初始化 uCOS-II,然后创建一个最低优先级的 start_task 并 OSStart(),从此再不回到 main()。真正的"业务启动"全部由 start_task 完成——它在临界区内一次性 OSTaskCreateExt() 出 15 个应用任务(数据管理、辅助功能、电表、逆变器、BMS、逻辑调度、接口解析、以太网监控、逆变器 CAN、云通信、以太网、采样、Modbus RTU、并机 SCI、HMI),再由 event_init() 统一创建 8 个串口/采样/掉电信号量和 1 个快调度事件标志组,最后把自己挂起。它处在数据流的最上游:所有模块的任务都是它"派生"出来的,任务优先级决定了下游各模块被调度的相对实时性;本文件也是全局任务计数结构 g_t_task_run_status 的定义者。本文件不含任何储能业务算法。
2. 关键数据结构与宏
2.1 本文件定义/使用的全局对象
| 名称 | 类型 | 说明 |
|---|---|---|
g_t_task_run_status | 结构体(SYSTEM_TASK_CNT_T) | 定义于本文件 main.c:31,类型定义在 UCOSII/uCOS-CONFIG/includes.h:29-47,extern 声明于 includes.h:49。含 14 个任务计数 + 1 个 u32_irq_dma_cnt,各任务在自己的 DEBUG_xxx == 1 分支里自增,用于看门狗式任务存活诊断(实际诊断代码在 midware/auxiliary/system_aux.c:1746-1801 已被整段注释掉) |
TASK_START_STK[256] | OS_STK 数组 | main.c:33,start_task 任务栈 |
TASK_DATA_STK[512] | OS_STK 数组 | main.c:35 |
TASK_AUXILIARY_STK[512] | OS_STK 数组 | main.c:36 |
TASK_METER_STK[256] | OS_STK 数组 | main.c:37 |
TASK_INVERTER_STK[512] | OS_STK 数组 | main.c:38 |
TASK_BMS_STK[256] | OS_STK 数组 | main.c:39 |
TASK_LOGIC_STK[512] | OS_STK 数组 | main.c:40 |
TASK_INTERFACE_STK[512] | OS_STK 数组 | main.c:41 |
TASK_ETHERNET_MONITOR_STK[256] | OS_STK 数组 | main.c:42 |
TASK_INVERTER_CAN_STK[256] | OS_STK 数组 | main.c:43 |
TASK_NET_STK[512] | OS_STK 数组 | main.c:44 |
TASK_ETHERNET_STK[1024] | OS_STK 数组 | main.c:45,全工程最大任务栈(W5500 + 无线 + DHCP 协议栈) |
TASK_SAMPLING_STK[256] | OS_STK 数组 | main.c:46 |
TASK_MODBUS_RTU_STK[256] | OS_STK 数组 | main.c:47 |
TASK_PARALLEL_SCI_STK[256] | OS_STK 数组 | main.c:48 |
TASK_HMI_STK[512] | OS_STK 数组 | main.c:49 |
TASK_USMART_STK[512] | OS_STK 数组 | main.c:51,被 #if DEBUG_SUMART 包裹 |
g_t_uart0_rcv_sem … g_t_uart5_rcv_sem | OS_EVENT * | main.c:53-58,6 路串口接收完成信号量 |
g_t_ct_sample_sem | OS_EVENT * | main.c:59,CT 采样 DMA+定时器触发信号量 |
g_t_power_down_sem | OS_EVENT * | main.c:60,掉电检测 EXTI 中断投递 |
g_t_fast_dispatch_flag | OS_FLAG_GRP * | main.c:62,逻辑-逆变器"快调度"流水线事件标志组 |
2.2 本文件使用的宏(均在别处定义)
| 名称 | 类型 | 说明 |
|---|---|---|
START_TASK_PRIO | 宏 = 30u | UCOSII/uCOS-CONFIG/app_cfg.h:56,启动任务优先级,见备注 4 |
TASK_SYSTEM_DATA_PRIO | 宏 = 7u | app_cfg.h:58 |
TASK_SYSTEM_AUX_PRIO | 宏 = 8u | app_cfg.h:59 |
TASK_METER_PRIO | 宏 = 9u | app_cfg.h:60 |
TASK_INVERTER_PRIO | 宏 = 10u | app_cfg.h:61;logic.c:2954 用 OSTimeDlyResume(TASK_INVERTER_PRIO) 主动唤醒它 |
TASK_BMS_PRIO | 宏 = 11u | app_cfg.h:62 |
TASK_LOGIC_CONTROL_PRIO | 宏 = 12u | app_cfg.h:63 |
TASK_INTERFACE_PRIO | 宏 = 13u | app_cfg.h:64 |
TASK_ETHERNET_MONITOR_PRIO | 宏 = 14u | app_cfg.h:65 |
TASK_INVERTER_CAN_PRIO | 宏 = 15u | app_cfg.h:66 |
TASK_NET_PRIO | 宏 = 16u | app_cfg.h:67 |
TASK_ETHERNET_PRIO | 宏 = 17u | app_cfg.h:68 |
TASK_SAMPLING_PRIO | 宏 = 18u | app_cfg.h:69 |
TASK_MODBUS_RTU_PRIO | 宏 = 19u | app_cfg.h:70 |
TASK_PARALLEL_SCI_PRIO | 宏 = 20u | app_cfg.h:71 |
TASK_HMI_PRIO | 宏 = 21u | app_cfg.h:72 |
TASK_USMART_PRIO | 宏 = 22u | app_cfg.h:73(当前未编译) |
TASK_*_STK_SIZE | 宏 | app_cfg.h:83-100,各任务栈深度(OS_STK 条目数) |
DEBUG_OS_EVENT | 宏 = 0 | 本工程定义于 user/main.h:51;为 1 时打印每个事件对象指针 |
DEBUG_SUMART | 宏 = 0 | 定义于 midware/debug/shell_usmart.h:13;为 1 时才编译 USMART 调试任务 |
OS_TASK_OPT_STK_CHK / OS_TASK_OPT_STK_CLR / OS_TASK_OPT_SAVE_FP | 宏 | uCOS-II 任务创建选项:栈检查、栈清零、保存浮点寄存器 |
OS_TASK_STAT_EN / OS_CPU_CFG_INT_DIS_MEAS_EN | 宏 | 控制 OSStatInit() 与中断关断时间测量是否编译 |
OS_LOWEST_PRIO | 宏 = 63u | os_cfg.h:39;OS_TASK_STAT_PRIO = 62、OS_TASK_TMR_PRIO = 53 |
OS_MAX_TASKS | 宏 = 20u | os_cfg.h:46,任务上限(见备注 4) |
OS_MAX_EVENTS | 宏 = 30u | os_cfg.h:42 |
OS_MAX_FLAGS | 宏 = 5u | os_cfg.h:43 |
OS_TICKS_PER_SEC | 宏 = 1000u | os_cfg.h:51,即 1 tick = 1 ms |
OS_CRITICAL_METHOD | 宏 = 3u | UCOSII/uCOS-II/Ports/ARM-Cortex-M4/Generic/RealView/os_cpu.h:138,临界区采用"保存-恢复 CPU_SR"方式,可安全嵌套(见备注 5) |
3. 函数清单
| 函数名 | 作用域 | 说明 |
|---|---|---|
event_init | static(main.c:74) | 创建 8 个信号量 + 1 个事件标志组,并给每个对象设置名字 |
start_task | static(main.c:140) | 启动任务:统计初始化 → 临界区内批量创建 15 个应用任务 → event_init() → 退出临界区 → 挂起自身 |
main | 全局(main.c:348) | 中断/时钟/板级初始化 → OSInit() → 创建 start_task → OSStart(),不再返回 |
本文件无函数指针、无回调注册;全工程唯一被 main() 直接调用的入口就是 start_task。
4. 核心逻辑解析
4.1 main() 启动时序(main.c:348-369)
| 步骤 | 行号 | 动作 | 说明 | ||
|---|---|---|---|---|---|
| 1 | 350 | INTX_ENABLE() | 汇编 cpsie i 打开全局中断(system/sys/chip.c:68) | ||
| 2 | 351 | systick_config() | 配置 SysTick 为 1000 Hz(SysTick_Config(SystemCoreClock/1000)),并设 NVIC 优先级 0(system/sys/chip.c:24-33)。uCOS-II 的 tick 由该中断提供,因此 OS_TICKS_PER_SEC 必须与之一致 | ||
| 3 | 352 | delay_init(SystemCoreClock / 1000000U) | 以 us 为单位的忙等延时基数 | ||
| 4 | 353 | Board_init() | 板级初始化:NVIC → IWDG → GPIO → usart0(115200 调试)、usart1(9600 电表 485)、usart2(9600 逆变器 MDSP)、uart4(9600 BMS 485)、usart5(115200 WiFi)、flash、SDRAM、PCF8563、WS2812、CAN0/CAN1(250 Kbps)、uart3(外部 485,按 g_t_modbus_config.u8_modbus_baud_rate);每步之间 IWDG_Feed(),最后 sys_info_restore 与上电原因记录(system/board_init/board_init.c:217-275) | ||
| 5 | 355 | OSInit() | 初始化 uCOS-II:创建空闲任务(prio 63)、统计任务(prio 62,因 OS_TASK_STAT_EN=1);OS_TMR_EN=0 故不创建定时器任务 | ||
| 6 | 358-366 | OSTaskCreateExt(start_task, …) | 优先级 30,栈 256,任务 ID 与优先级相同,选项 `STK_CHK\ | STK_CLR\ | SAVE_FP`。注意此时还没有开调度器,所以创建动作是顺序执行的 |
| 7 | 368 | OSStart() | 启动调度器,从此进入多任务世界,main() 的栈帧永久保留 |
为何 INTX_ENABLE() 在最前:systick_config() 里 SysTick_Config 会立刻使能 SysTick 中断与异常,若全局中断未开则计数不会走;同时 Board_init() 中的中断驱动外设(串口接收、EXTI 掉电中断)也要求中断已开。
4.2 start_task() 的任务创建表(main.c:140-339)
进入后先做统计初始化,再进临界区批量建任务:
main.c:146-148:#if (OS_TASK_STAT_EN > 0)→OSStatInit()。这一步必须在临界区之外(main.c:154才OS_ENTER_CRITICAL()),因为OSStatInit()内部会OSTimeDly()让出 CPU 两个 tick 来测量空闲计数,需要调度器已运行。main.c:150-152:#ifdef CPU_CFG_INT_DIS_MEAS_EN→CPU_IntDisMeasMaxCurReset(),复位"最长关中断时间"统计。main.c:154:OS_ENTER_CRITICAL(),其后的全部OSTaskCreateExt都在关中断状态下执行。main.c:156-319:按优先级从高到低依次创建 15 个任务。main.c:321-332:#if DEBUG_SUMART下创建task_usmart(当前为 0,不编译)。main.c:334:event_init()。main.c:336:OS_EXIT_CRITICAL()。main.c:338:OSTaskSuspend(OS_PRIO_SELF)——挂起自己,且永不OSTaskDel,因此它永久占用一个 TCB 槽位(见备注 4)。
任务创建明细(优先级/栈大小均引用自 app_cfg.h):
| 行号 | 任务函数 | 优先级 | 栈(字) | 任务名 | 定义位置 | 周期/触发 |
|---|---|---|---|---|---|---|
| 156 | task_system_data | 7 | 512 | task_system_data | data/data.c:251 | OSSemPend(g_t_power_down_sem, 500),500 ms 超时轮询 |
| 167 | task_system_aux | 8 | 512 | task_system_aux | midware/auxiliary/system_aux.c:2056 | OSTimeDlyHMSM(0,0,0,400) + IWDG_Feed() |
| 178 | task_meter | 9 | 256 | task_meter | midware/meter/meter.c:5710 | 300 ms 级轮询 |
| 189 | task_inverter | 10 | 512 | task_inverter | midware/inverter/inverter.c:1045 | OSFlagPend(PEND_LOGIC_CALCULATE_DONE, 20ms) 阻塞等待逻辑算完 |
| 200 | task_bms | 11 | 256 | task_bms | midware/bms/bms.c:2731 | 100 ms 级 CAN 轮询 |
| 211 | task_system_logic_control | 12 | 512 | task_system_logic_control | logic/logic.c:2902 | OSFlagPend(POST_PEND_FAST_ENABLE, 20ms) + OSTimeDlyHMSM(0,0,0,280) |
| 222 | task_interface_parse | 13 | 512 | task_interface_parse | midware/interface/interface.c:211 | 500 ms(DRM / 干接点 / EPO) |
| 233 | task_ethernet_monitor | 14 | 256 | task_ethernet_monitor | midware/ethernt/ethernet.c:1538 | 500 ms |
| 244 | task_inverter_can | 15 | 256 | task_inverter_can | midware/inverter/inverter.c:1199 | OSFlagPend(PEND_INV_CALCULATE_DONE, 20ms, CONSUME) |
| 255 | task_net_app | 16 | 512 | task_net_app | net/ems.c:7250 | OSTimeDlyHMSM(0,0,0,25) |
| 266 | task_ethernet | 17 | 1024 | task_ethernet | midware/ethernt/ethernet.c:986 | OSQPend(g_pEthernetQ, 10) |
| 277 | task_sampling | 18 | 256 | task_sampling | midware/meter/ct.c:844 | OSSemPend(g_t_ct_sample_sem, 100) |
| 288 | task_modbus_rtu | 19 | 256 | task_modbus_rtu | midware/interface/interface.c:298 | 100 ms 级 / 场景切换 |
| 299 | task_parallel_sci | 20 | 256 | task_modbus_rtu(名字写错,见备注 1) | midware/inverter/inverter.c:1296 | OSTimeDlyHMSM(0,0,0,100) |
| 310 | task_hmi_parse | 21 | 512 | task_hmi_parse | hmi/key.c:8888 | 10 ms 级(按键/ LED / LCD) |
| 322 | task_usmart | 22 | 512 | task_usmart_parse | midware/debug/shell_usmart.c:54 | #if DEBUG_SUMART,当前不编译 |
任务总数核对:应用任务 15 个 + start_task 自身 1 个 + uCOS-II 统计任务(prio 62)1 个 + 空闲任务(prio 63)1 个 = 18 个 TCB,上限 OS_MAX_TASKS = 20;若打开 DEBUG_SUMART 则为 19 个。
优先级设计要点:数字越小优先级越高。task_system_data(7) 优先级最高——它承担掉电保存,必须在断电电容能量耗尽前抢到 CPU;task_ethernet(17) 虽然只排第 11 位,但因为 OSQPend 超时只有 10 tick,实际跑得最勤;task_hmi_parse(21) 排在应用任务末位,人机界面响应可以被任何测量/控制任务抢占。START_TASK_PRIO = 30 高于所有应用任务,保证启动阶段不被抢占。
4.3 event_init() 事件对象创建(main.c:74-131)
全部创建在 start_task 的临界区内按固定顺序执行:
| 行号 | 对象 | 初值 | 名字 | 生产者(OSSemPost/OSFlagPost) | 消费者(OSSemPend/OSFlagPend) |
|---|---|---|---|---|---|
| 78 | g_t_uart0_rcv_sem | 0 | uart0_rcv_sem | hardware/usart0/usart0.c:92(接收中断) | hardware/usart0/usart0.c:212(调试口收帧,500 tick 超时) |
| 84 | g_t_uart1_rcv_sem | 0 | uart1_rcv_sem | hardware/usart1/usart1.c:303(帧结束 + 总线静默 3.5T) | hardware/usart1/usart1.c:256(电表 RS485) |
| 90 | g_t_uart2_rcv_sem | 0 | uart2_rcv_sem | hardware/usart2/usart2.c:94 | hardware/usart2/usart2.c:213(逆变器 MDSP) |
| 96 | g_t_uart3_rcv_sem | 0 | uart3_rcv_sem | hardware/usart3/usart3.c:123 | hardware/usart3/usart3.c:277、midware/interface/interface.c 的 task_modbus_rtu(外部 485 / Modbus RTU) |
| 102 | g_t_uart4_rcv_sem | 0 | uart4_rcv_sem | hardware/usart4/usart4.c:120 | hardware/usart4/usart4.c:325(BMS RS485) |
| 108 | g_t_uart5_rcv_sem | 0 | uart5_rcv_sem | hardware/usart5/usart5.c:99 | midware/ethernt/wireless/elink_parse.c:108(WiFi 模组 AT 通路) |
| 114 | g_t_ct_sample_sem | 0 | ct_sample_sem | midware/meter/ct.c:834(定时器/DMA 中断) | midware/meter/ct.c:883 的 task_sampling(100 tick 超时) |
| 120 | g_t_power_down_sem | 0 | g_t_power_down_sem | hardware/exti/exti.c:95(掉电检测 EXTI) | data/data.c:263 的 task_system_data(500 tick 超时) |
| 126 | g_t_fast_dispatch_flag | 0(FAST_DISPATCH_IDLE) | fast_dispatch_flag | 见 4.4 | 见 4.4 |
所有信号量初值均为 0,即"上电即阻塞",必须由中断或其它任务显式投递。
4.4 快调度事件标志流水线 g_t_fast_dispatch_flag
这是一条典型的三任务流水线握手,标志位定义在 logic/logic.h:121-130:
| 枚举 | 值(二进制) | 置位方 | 说明 | |
|---|---|---|---|---|
FAST_DISPATCH_IDLE | 0 | — | 初值,全清 | |
POST_PEND_FAST_ENABLE | 0b0001 | net/server.c:838 | 云端下发快速调度请求 → bit0 置位,作为整条流水线的"门控"位 | |
POST_LOGIC_CALCULATE_DONE | 0b0010 | logic/logic.c:2953 | 逻辑算完 → bit1 置位 | |
PEND_LOGIC_CALCULATE_DONE | 0b0011 | — | 逆变器等待掩码:需要 bit0+bit1 同时置位 | |
POST_INV_CALCULATE_DONE | 0b0100 | midware/inverter/inverter.c:1185 | 逆变器算完 → bit2 置位 | |
PEND_INV_CALCULATE_DONE | 0b0111 | — | CAN 任务等待掩码:bit0+bit1+bit2,且 `OS_FLAG_WAIT_SET_ALL \ | OS_FLAG_CONSUME` |
数据流:server.c 置 bit0 → task_system_logic_control(logic.c:2912,OS_FLAG_WAIT_SET_ALL 掩码 1、不消费、20 tick 超时)醒来,把 5 个软定时 tick 清零(logic.c:2916-2920,即强制跳过所有节流间隔立刻算一次)→ 算完后置 bit1 并 OSTimeDlyResume(TASK_INVERTER_PRIO)(logic.c:2951-2955)→ task_inverter 的 OSFlagPend(掩码 3) 满足,清零自己的查询 tick 后写逆变器控制功率 → 置 bit2 → task_inverter_can 以掩码 7 + CONSUME 收尾,一次性把 bit0/bit1/bit2 全部清掉,标志组回到 FAST_DISPATCH_IDLE。因此整条链是"一次外部触发 = 一次完整下发",如果某个环节超时(20 tick = 20 ms),对应任务仍会按普通周期节流继续运行,只是失去了"立即响应"的加速效果。
4.5 定时/调度时序小结
- 时间基准:SysTick 1000 Hz,
OS_TICKS_PER_SEC = 1000,即 1 tick = 1 ms。所有OSFlagPend/OSSemPend的超时值(20、100、500)都是毫秒。 OSTimeDlyHMSM(0,0,0,N)的 N 即 N ms。- 中断→任务的同步全部走本节 4.3 表中的信号量,无一例外;没有使用消息邮箱(
OSMbox),唯一的队列是task_ethernet自己运行时创建的OSQCreate(g_pEthernetMsg, ETHERNET_Q_LEN)(midware/ethernt/ethernet.c:993,不在本文件内)。 - 看门狗:
task_system_aux每次循环IWDG_Feed()(system_aux.c:2086),本文件的所有任务均无喂狗动作。
4.6 关键全局变量在本文件中的读写
本文件只定义、几乎不修改任何跨模块变量:
g_t_task_run_status(main.c:31):本文件仅定义,无任何写操作;写操作分散在data.c:314、ems.c:7283、logic.c:2948、meter.c:5884、ct.c:798(中断上下文)、ct.c:1182、key.c:8982、inverter.c:1180/1282、bms.c:2931、interface.c:228/376,且几乎全部被DEBUG_xxx == 1包裹(当前工程宏均为 0),唯一例外是ct.c:798的u32_irq_dma_cnt。- 8 个信号量指针与
g_t_fast_dispatch_flag:本文件只在event_init()中写一次(创建),此后由各硬件 ISR 与任务读写;main.h里的extern声明让这些句柄变成全局单例。
5. 对外接口
本文件导出(供外部使用)
| 名称 | 类型 | 使用方 |
|---|---|---|
g_t_task_run_status | 全局变量 | 各任务的调试计数自增;extern 声明在 UCOSII/uCOS-CONFIG/includes.h:49。midware/auxiliary/system_aux.c:1746-1801 有整段被注释的"任务存活检测"消费者 |
g_t_uart0_rcv_sem … g_t_uart5_rcv_sem | 全局变量 | hardware/usart0…usart5/*.c、midware/ethernt/wireless/elink_parse.c、midware/interface/interface.c(经 user/main.h 的 extern) |
g_t_ct_sample_sem | 全局变量 | midware/meter/ct.c |
g_t_power_down_sem | 全局变量 | hardware/exti/exti.c:95(投递)、data/data.c:263(等待) |
g_t_fast_dispatch_flag | 全局变量 | net/server.c:838、logic/logic.c:2912/2953、midware/inverter/inverter.c:1054/1185/1207 |
main | 函数 | 由启动代码 user/startup_gd32f407.s 的 Reset_Handler 调用 |
event_init、start_task | static | 不导出,仅本文件内使用 |
本文件调用(外部符号)
| 调用 | 来源模块 |
|---|---|
INTX_ENABLE、systick_config | system/sys/chip.c |
delay_init | system/delay/delay.c |
Board_init | system/board_init/board_init.c |
OSInit、OSTaskCreateExt、OSTaskNameSet、OSSemCreate、OSEventNameSet、OSFlagCreate、OSFlagNameSet、OSTaskSuspend、OSStart、OSStatInit、CPU_IntDisMeasMaxCurReset、OS_ENTER_CRITICAL / OS_EXIT_CRITICAL | UCOSII/uCOS-II + UCOSII/uCOS-II/Ports/ARM-Cortex-M4/Generic/RealView |
| 15 个任务函数 | data/data.c、midware/auxiliary/system_aux.c、midware/meter/meter.c、midware/meter/ct.c、midware/inverter/inverter.c、midware/bms/bms.c、logic/logic.c、midware/interface/interface.c、midware/ethernt/ethernet.c、net/ems.c、hmi/key.c、midware/debug/shell_usmart.c |
6. 依赖关系
依赖(本文件 #include):chip.h、delay.h、board_init.h、ethernet.h、key.h、logic.h、ems.h、meter.h、bms.h、inverter.h、data.h、interface.h、system_aux.h、ct.h、shell_usmart.h(main.c:13-27)。其中 logic.h 再 #include "includes.h"(logic.h:13),SYSTEM_TASK_CNT_T 与 g_t_task_run_status 的 extern 正是从 includes.h:29-49 得到的——除此以外 chip.h 只引入 gd32f4xx.h,并不提供 includes.h 链。
被依赖(谁 include user/main.h,共 20 个文件):
data/data.c、hardware/exti/exti.c、hardware/sdram/sdram.c、hardware/usart0/usart0.c、hardware/usart1/usart1.c、hardware/usart2/usart2.c、hardware/usart3/usart3.c、hardware/usart4/usart4.c、hardware/usart5/usart5.chardware/can/can0.h、hardware/dma/dma.h、hardware/iic/iic2.h、hardware/spi/spi1.h、hardware/spi/spi2.h、hardware/timer/timer1.hmidware/debug/shell_usmart.c、midware/ethernt/lan/w5500.c、midware/ethernt/wireless/elink_parse.c、midware/interface/interface.c、midware/meter/ct.c
user/main.c 本身不被任何文件 include;它由工程文件 user/EMS_3_0.uvprojx(<FileName>main.c</FileName>,路径 .\main.c)直接编译。
7. 备注与风险点
- 任务名复制粘贴错误:
main.c:308把并机 SCI 任务命名为"task_modbus_rtu",与main.c:297的 Modbus 任务重名。两个任务共享同一OSTaskNameGet/调试视图名,任何按名字定位任务的调试工具都会认错;而该任务的优先级TASK_PARALLEL_SCI_PRIO = 20与名字也不匹配。应改为"task_parallel_sci"。 - 启动任务永不删除:
main.c:338用OSTaskSuspend(OS_PRIO_SELF)而非OSTaskDel(OS_PRIO_SELF),start_task永久占用 1 个 TCB。当前 18/20 已用(开启DEBUG_SUMART为 19/20),余量仅 1~2 个;后续若再增加任务会撞到OS_MAX_TASKS上限,OSTaskCreateExt将返回OS_ERR_TASK_NO_MORE_TCB而本文件完全不检查返回值,失败时静默无声,只表现为"某个功能永远不跑"。 - 所有
OSTaskCreateExt返回值均未校验:main.c:156-332共 16 处创建调用,OSTaskNameSet的错误码也只是丢弃在err里。创建失败时任务不会运行,也不会打印任何信息(DEBUG_OS_EVENT只打印事件对象,不打印任务)。 START_TASK_PRIO与OS_TASK_TMR_PRIO同域但无序依赖:START_TASK_PRIO = 30,而OS_TASK_TMR_PRIO = OS_LOWEST_PRIO - 10 = 53。当前OS_TMR_EN = 0,不冲突;但如果哪天打开定时器管理,需要重新核对优先级合法性(uCOS-II 要求 0..63 且不与系统任务重叠,30 仍在合法范围,只是语义上"启动任务比定时器任务优先级高")。- 关中断窗口偏长:
main.c:154到main.c:336之间约 180 行、16 次任务创建 + 8 次OSSemCreate+ 9 次OSEventNameSet/OSFlagNameSet全部在中断关闭状态下执行。得益于OS_CRITICAL_METHOD == 3(save/restore CPU_SR,可嵌套),功能正确;但这段时间内 SysTick 与所有串口/CAN 中断都被屏蔽,若某一帧在此时到达会丢失。这是上电一次性的行为,风险可接受,但把event_init()移到临界区外(OSFlagCreate/OSSemCreate自身是原子操作)可以显著缩短关中断时间。 p_arg = p_arg;(main.c:144):自赋值语句,实际作用是压制"未使用参数"告警。uCOS-II 的惯例写法是(void)p_arg;(data.c:253等文件就是这么写的),本文件与工程其余部分风格不一致,可读性差。OS_CPU_SR cpu_sr = 0;(main.c:142):仅在OS_CRITICAL_METHOD==3时被宏使用;若切换到 method 1/2,该变量会变成未使用变量。属于对 uCOS 配置的隐式耦合。- 事件名带
g_t_前缀的不一致:8 个信号量里 7 个名字与变量名一致,唯独g_t_power_down_sem的名字是"g_t_power_down_sem"(main.c:124)——即故意带上了g_t_前缀(其余为"uart0_rcv_sem"这种去掉前缀的写法)。无功能影响,仅名字风格混乱。 OSEventNameSet的&err未检查:main.c:82-130共 9 处,err反复覆盖。若OS_EVENT_NAME_EN被关掉,这些调用会返回错误但无人知晓(当前os_cfg.h:37为 1,安全)。main()中的delay_init(SystemCoreClock / 1000000U)(main.c:352):SystemCoreClock由SystemInit()在启动文件中设置,若时钟树未按预期配置(例如外部 HXTAL 起振失败回落),这里的除法基数是错的,会导致 us 级延时全部失准。当前工程依赖system_gd32f4xx.c的默认配置,属隐含假设。g_t_task_run_status的消费者已全部被注释:midware/auxiliary/system_aux.c:1746-1801的"任务死掉检测"整段被注释掉,而这个结构体的一半写操作本身又被DEBUG_*宏(当前为 0)包裹,导致该诊断机制实际上是完全失效的死代码:既不采集也不上报。DEBUG_SUMART全局为 0:midware/debug/shell_usmart.h:13定义为 0,因此TASK_USMART_STK(main.c:51)和task_usmart创建(main.c:321-332)都不编译。USMART shell 在量产固件中不可用,现场调试只能靠 usart0 的printf。