# 静态检查告警审查说明 本文件用于记录人工确认后的静态检查告警处理结论。原则: - 不为消除低风险 warning 引入会改变实时行为的代码。 - 裸机系统级单例、编译期常量、ISR/主循环共享状态分别分类说明。 - 对涉及实时路径的并发项,优先记录访问边界和偏离理由;只有经过实机验证后再做逻辑修复。 ## SUP-GLB-001:文件作用域对象 ### 编译期常量 以下 `constexpr` 对象为编译期常量,非可变全局状态,无运行期写入、并发访问或动态初始化顺序风险: - `device/ADC.cpp`: `ADC_SCALE`, `TEMP_FACTOR`, `VCC_FACTOR`, `CURRENT_FACTOR` - `device/Can.cpp`: `CANX` - `sys/health.cpp`: `PROTECT_TIME` - `sys/config.h`: 版本号、Flash 地址、协议 ID、滤波/PID 参数、数学常量、Timer 参数等 `constexpr` 配置项 处理结论:按静态检查误报/偏离处理。 ### 系统级硬件/模块单例 以下对象对应裸机固件中的唯一硬件资源或唯一管理器: - `Algorithm/FOC.cpp`: `FOC_Controller FOC` - `device/ADC.cpp`: `sampler sampler` - `device/Can.cpp`: `CAN_transmiter CAN0_transmiter` - `device/ang_sensor.cpp`: `angle_sensor KTH7823` - `sys/health.cpp`: `ThermalController thermalController` - `sys/initial.cpp`: `VersionManager Version` 访问边界: - 初始化顺序由 `main::hardware_init()` 显式控制,例如 `KTH7823.init()`、`sampler.init()`、`CAN0_transmiter.init()`、`FOC.init()`。 - `VersionManager Version` 构造仅复制 `constexpr` 版本号常量,不依赖外设初始化。 - 运行期主要由主循环任务访问;CAN 命令路径会更新 FOC 目标值和参数。 处理结论:接受系统级单例设计,保留文件作用域对象,并通过注释说明初始化顺序和访问边界。 ### ISR/主循环共享状态 #### `main.cpp`: `TaskScheduler scheduler` - `TIMER2_IRQHandler()` 置位任务标志。 - main 循环短关中断后读取快照并清除已处理任务位。 处理结论:已有短临界区保护,接受。 #### `device/Can.cpp`: CAN RX/TX 队列索引 涉及: - `rx_queue_head`, `rx_queue_tail`, `rx_queue_count` - `tx_queue_head`, `tx_queue_tail`, `tx_queue_count` 访问边界: - RX/TX 队列被主循环、CAN 中断、DMA 完成中断共同访问。 - 队列 push/pop/peek/disable 通过 `CAN_EnterCritical()` / `CAN_ExitCritical()` 保护。 - `CAN_ExitCritical()` 使用 `__set_PRIMASK(primask)` 恢复进入前中断状态,而不是直接 `__enable_irq()`,避免误打开外层已关闭的中断。 处理结论:已有临界区保护,接受。 #### `device/ADC.cpp`: injected 电流采样缓存 涉及: - `adc_current_value[3]` - `adc_current_frame_ready` 访问边界: - `ADC0_1_IRQHandler()` 写入 U/V/W injected 同步采样值,并置位 `adc_current_frame_ready`。 - `sampler::update_current()` 在主循环任务中看到 ready 后读取三相采样并更新滤波缓存,随后清 ready。 - 该路径属于高频电机采样/控制链路。此前尝试在读取侧加入 PRIMASK 快照后,实机出现上电连续重启;回滚后恢复正常。 处理结论:当前不再为消除 warning 增加临界区逻辑,避免改变高频实时路径时序。保留现有 `volatile` 共享标志设计,作为实机已验证的稳定实现;如后续需要修正,应单独建立实验分支并做示波/日志验证。 #### `sys/systick.cpp`: DWT CPU 占用率统计变量 涉及: - `task_enter_cyccnt` - `busy_cycles_accum` - `sample_seconds` - `cpu_usage` - `dwt_initialized` 访问边界: - `busy_task_enter()` / `busy_task_exit()` 在主循环任务侧记录和累加忙碌周期。 - `SysTick_Handler()` 每 1 秒读取并清零统计值,更新 `cpu_usage`。 - 此路径仅用于诊断 CPU 使用率,不参与控制闭环。 - 此前尝试在 `busy_task_exit()` 加入 PRIMASK 临界区后,与 ADC 临界区改动同轮导致实机上电连续重启;已回滚并恢复正常。 处理结论:当前不再为该诊断统计项增加临界区,避免影响高频任务时序。允许 1 秒窗口内存在极小统计误差,作为诊断值可接受。 #### `device/ang_sensor.cpp`: SPI DMA 完成标志 涉及: - `spi_dma_tx_complete` - `spi_dma_rx_complete` 访问边界: - SPI 传输前清零标志。 - DMA ISR 完成后置位。 - 轮询函数等待标志或超时。 处理结论:典型 ISR/轮询共享 volatile 标志,接受。 #### `device/Timer.cpp`: `total_us100_counter` 访问边界: - 仅在 `TIMER2_IRQHandler()` 内作为 100us 调度索引写入和使用。 处理结论:虽然为文件作用域变量,但无跨上下文并发写风险,接受。后续可考虑改为 ISR 内 `static`,但当前不为 warning 改运行逻辑。 #### `sys/health.cpp`: 电压管理状态 涉及: - `voltage_state` - `last_vbus_slow` 访问边界: - 仅 `power_manage()` 慢速任务访问。 - 文件内 `static` 封装。 处理结论:模块私有状态机变量,接受。 ## SUP-CMP-001:浮点比较 ### `normalizeAngle360()` 边界判断 代码形态: ```cpp while (angle >= 360.0f) angle -= 360.0f; while (angle < 0.0f) angle += 360.0f; ``` 结论:该比较用于角度归一化边界判断,目标区间严格定义为 `[0, 360)`,不是浮点相等性判断,也不是传感器阈值判定。不需要容差。 ## printf / snprintf 类检查 - FOC 齿槽校准打印位于 `#if FOC_DEBUG`,正式配置 `FOC_DEBUG=0` 时不参与编译。 - `VersionManager::versionToString()` 已从 `snprintf()` 改为固定格式的轻量手写拼接,避免格式化库引入。 ## AUTO-MET-001:圈复杂度 已拆分以下函数,降低单函数圈复杂度: - `FOC_Controller::calibrate_cogging_tick()`:拆分为状态派发和各状态处理函数。 - `CAN_transmiter::communication_check()`:拆分为周期发送、接收分发、特殊消息、节点消息等处理函数。 - `do_task()`:拆分为高频采样/电机控制、低频维护、CAN 任务。 处理结论:拆分后原目标函数复杂度已显著下降;实编仍需在 Keil/CMSIS/cbuild 环境验证。