Files
Motor_v2/STATIC_ANALYSIS_NOTES.md
cbb 7c4aaa5ee6 feat(FOC): 优化FOC控制算法并修复多个控制环路问题
- 重构cal_Iq_Id函数,移除电角度参数传递,改用预计算的sin/cos值
  以避免重复三角函数计算,提升性能约15-300周期
- 修复角度同步Uq前馈学习中的运动方向判断逻辑,解决反转时的
  震荡问题和正转正常反转震荡的根本原因
- 实现低速缩放因子函数get_mode3_velocity_scale,改进静摩擦
  hunting抑制效果
- 优化电压检测逻辑,将阻塞式ADC读取改为连续模式零等待,
  提升实时性能
- 修复初始化期间电压分母为零的问题,添加下限保护防止P增益
  无穷大
- 实现PID控制器测量微分功能,消除目标阶跃时的微分冲击
- 改进积分抗饱和策略,添加外部饱和泄放功能,优化到位稳定
  性能

perf(Filter): 优化中值滤波算法性能

- 针对ADC_FILTER_SIZE=6的固定场景实现最优排序网络,
  用12次比较替代通用std::nth_element算法,显著提升性能
- 保留通用回退路径处理其他尺寸情况
2026-09-01 02:46:25 +08:00

162 lines
6.0 KiB
Markdown

# 静态检查告警审查说明
本文件用于记录人工确认后的静态检查告警处理结论。原则:
- 不为消除低风险 warning 引入会改变实时行为的代码。
- 裸机系统级单例、编译期常量、ISR/主循环共享状态分别分类说明。
- 对涉及实时路径的并发项,优先记录访问边界和偏离理由;只有经过实机验证后再做逻辑修复。
## SUP-GLB-001:文件作用域对象
### 编译期常量
以下 `constexpr` 对象为编译期常量,非可变全局状态,无运行期写入、并发访问或动态初始化顺序风险:
- `device/ADC.cpp`: `ADC_SCALE`, `TEMP_FACTOR`, `VCC_FACTOR`, `CURRENT_FACTOR`
- `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 环境验证。