作者:Leonard(QA测试工程师)| 日期:2026-04-16 | 目标读者:嵌入式开发工程师、Team Leader、质量管理人员
嵌入式Cppcheck静态分析代码质量CI/CD

前言

仪表类产品(BMS、DTU、传感器、PLC、工业控制器)代码出错代价极高。传统开发依赖人工review和测试,覆盖率低。

Cppcheck 是一款免费、开源、无需编译的静态分析工具,特别适合资源受限的仪表嵌入式团队。


一、Cppcheck 核心能力

检查类型嵌入式场景严重程度
空指针解引用指针操作前未判空🔴 高
内存泄漏malloc未free🔴 高
数组越界传感器数据缓冲溢出🔴 高
野指针指针释放后继续使用🔴 高
整数溢出计数器溢出🟡 中
逻辑错误if (x = y) 写成赋值🟡 中
死代码永不会执行的分支🟢 低

二、四大典型应用场景

场景1:传感器数据处理

数组越界和空指针是最常见问题:

// Cppcheck 会报警:Array accessed at index 5, which is out of bounds.
int16_t* pData = g_sensor_buf[channel];
if (pData != NULL) { process_data(pData); }

场景2:通信协议解析

Modbus、DL/T645、HJT212 等协议解析时,边界检查是重灾区:

// Cppcheck 会报警:Buffer access out-of-bounds
uint8_t count = frame[5];
for (int i = 0; i < count; i++) {
    registers[i] = (frame[6+i*2] << 8) | frame[7+i*2];
}

场景3:定时器/中断处理

volatile 共享变量访问的原子性问题:

volatile uint32_t g_tick_count = 0;
// Cppcheck 报警:volatile 变量需要原子操作
void TIM2_IRQHandler(void) { g_tick_count++; }

场景4:EEPROM 参数存储

掉电保存配置时未验证数据有效性:

// Cppcheck 报警:Buffer overflow,channel_count 未验证可能超限
DeviceConfig_t* cfg = (DeviceConfig_t*)eeprom_data;
g_thresholds[i] = cfg->thresholds[i];  // 越界访问

三、安装与基本使用

# Ubuntu 安装
sudo apt-get install -y cppcheck
cppcheck --version

# 扫描整个目录
cppcheck --enable=warning --std=c11 --platform=unix32 App/ Drivers/

# 输出报告
cppcheck --enable=all --std=c11 --output-file=cppcheck-report.txt App/

四、推荐参数组合(仪表嵌入式)

cppcheck \
  --enable=warning,performance,portability \
  --std=c11 \
  --platform=unix32 \
  --force \
  --inline-suppr \
  --verbose \
  --suppress=unusedFunction \
  App/ Drivers/ Core/Src/

五、GitHub Actions CI/CD 集成

name: Cppcheck Static Analysis
on: [push, pull_request]
jobs:
  cppcheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Cppcheck
        run: sudo apt-get install -y cppcheck
      - name: Run Cppcheck
        run: |
          cppcheck --enable=warning,performance,portability \
            --std=c11 --platform=unix32 --force \
            --output-file=cppcheck-report.txt \
            App/ Drivers/ 2>&1 || true
      - name: Upload report
        uses: actions/upload-artifact@v4
        with:
          name: cppcheck-report
          path: cppcheck-report.txt

六、Makefile 集成

cppcheck:
	cppcheck --enable=warning,performance,portability \
	  --std=c11 --platform=unix32 --force \
	  --output-file=cppcheck-report.txt \
	  App/ Drivers/ 2>&1 || true
make cppcheck  # 本地一键检查

七、误报处理:STM32 HAL 库 stub

// stub.h - 抑制 HAL 库相关误报
#ifndef __CPPCHECK_STUB_H__
#define __CPPCHECK_STUB_H__
#define HAL_GPIO_WritePin(a,b,c) ((void)0)
#define HAL_Delay(a) ((void)0)
#endif
cppcheck --std=c11 --include=stub.h App/

八、落地路径(4天)

天数内容
第1天安装 cppcheck,扫描 App/,统计问题数
第2天分析分类,加 suppress 抑制误报
第3天集成 GitHub Actions CI
第4天Makefile 集成,make cppcheck

九、局限性

  • ❌ 查不出业务逻辑错误(如上限下限写反)
  • ❌ 嵌入式寄存器操作(HAL封装后看不到)
  • ❌ 实时性问题(死锁、中断优先级反转)
  • ✅ 定位:代码审查的辅助工具,不是替代品

参考资源

资源链接
Cppcheck 官网https://cppcheck.sourceforge.io/
Cppcheck 手册https://cppcheck.sourceforge.io/manual.pdf

本文档由 Leonard(QA测试工程师)编写 | 2026-04-16