在PlatformIO中集成PVS-Studio

图片5

最近,在PlatformIO嵌入式系统开发环境中,已经出现了对PVS-Studio的支持。在本文中,您将学习如何使用静态分析器以打开的项目为例来测试代码。

什么是PlatformIO?


PlatformIO是跨平台的微控制器编程工具。PlatformIO的核心是命令行工具,但建议将其用作Visual Studio Code的插件。支持大量现代芯片和基于它们的主板。它能够自动下载合适的装配系统,并且该站点具有大量用于管理插入式电子组件的库。支持多种静态代码分析器,包括PVS-Studio。

导入项目


为了演示,让我们在Arduino Mega板上使用ArduPod 脚控制程序


为合适的电路板创建一个新项目,然后复制源代码:

图片2

/ arduino / AP_Utils / examples /文件夹中有几个用于配置和运行六脚架的程序示例,我们将使用Servo_test.ino。通常,用于Arduino的程序以INO格式的草图形式创建,在这种情况下并不完全适合。要从中制作出正确的.cpp文件,通常只需更改文件扩展名,在开头添加#include <Arduino.h>标头,并确保在访问函数和全局变量之前已声明它们。

图片3

在组装过程中,可能会因缺少所需的第三方库而发生错误。但是,PlatformIO将帮助您在存储库中找到它们。

In file included from src\servo_test.cpp:20:0:
src/AP_Utils.h:10:37: fatal error: Adafruit_PWMServoDriver.h:
No such file or directory
*******************************************************************************
* Looking for Adafruit_PWMServoDriver.h dependency? Check our library registry!
*
* CLI> platformio lib search "header:Adafruit_PWMServoDriver.h"
* Web> https://platformio.org/lib/search?query=header:Adafruit_PWMServoDriver.h
*
*******************************************************************************
compilation terminated.

该链接将显示适当的选项,并且依赖项的安装是通过终端中的一个命令完成的:

pio lib install "Adafruit PWM Servo Driver Library"

配置分析仪并开始测试


要配置分析器,您需要像这样编辑platformio.ini配置:

[env:megaatmega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino
check_tool = pvs-studio
check_flags =
  pvs-studio:
    --analysis-mode=4 ; General analysis mode. Set to 32 for MISRA
    --exclude-path=/.pio/libdeps ; Ignore dependency libraries

check_tool 参数指示要使用的代码分析器,其配置在check_flags参数中完成可以在官方网站的文档中找到更详细的说明:https : //docs.platformio.org/en/latest/plus/check-tools/pvs-studio.html

最后,您可以在终端中使用命令运行项目检查。在第一次测试之前,环境本身会下载当前的分析器发行版。

pio check

检查hexapod程序的结果


这次,本文的目的是演示PVS-Studio与PlatformIO的集成,而不是演示分析仪的诊断功能。但是,一旦对项目进行了验证,请考虑发现的一些错误,以表明已成功分析了该项目。

V519'- '运算符的左侧和右侧有相同的子表达式:pow(t,2)-pow(t,2)。 AP_Utils.cpp 176

pointLeg* AP_Utils::traceLeg(uint8_t leg, float phi, float z,
  int resolution, uint8_t shape) {
  ....
  if(shape == ELLIPTIC) {
    ....
    float v = sqrt(pow(phi - legs[leg].phi, 2) + pow(z - legs[leg].z, 2));
    float u = sqrt(pow(phi - phi0, 2) + pow(z - z0, 2));
    float t = sqrt(pow(phi0 - legs[leg].phi, 2) + pow(z0 - legs[leg].z, 2));
    theta = acos((pow(t, 2) - pow(t, 2) - pow(v, 2))/(-2.0*t*u));
    ....
  }
  ....
}

彼此减去两个相同的表达式。目前尚不清楚这种差异的数学含义是什么。也许程序员只是没有简化表达式。或者也许允许输入错误,并且必须用另一个论点代替这些t之一

V550一个奇怪的精确比较:值!=-1.使用具有定义的精确度的比较可能更好:晶圆厂(A-B)> Epsilon。AP_Utils.cpp 574

float AP_Utils::sr04_average(uint8_t trig, uint8_t echo,
  int unit, int samples, int time) {
  ....
  float average, pause, value;
  ....
  for(int i=0; i<samples; i++) {
    value = sr04(trig, echo, unit);
    if(value != -1) { // <=
      total += value;
      delay(pause);
    } else {
      i--;
    }
  }
  average = total/samples;
  ....
  return average;
}

警告表示浮点数比较不正确。由于不可能用有限的位数来精确表示实数,因此通过将分数的差与给定的精度指标进行比较来确定分数的相等性是更安全的。例如,如下所示:

bool is_equal(double x, double y) {
  return std::fabs(x - y) < 0.001f;
}

直接比较非整数数字的唯一安全选择是将常量分配给变量,然后将它们的值与这些常量进行比较。在这种情况下,变量值的值任何地方专门分配为-1。这就是所谓的AP_Utils :: sr04方法的工作方式,该方法返回检查的值:

float AP_Utils::sr04(uint8_t trig, uint8_t echo, int unit) {
  ....
  float duration, distance;
  ....
  duration = pulseIn(echo, HIGH);
  distance = (346.3*duration*0.000001*unit)/2; // <=
  
  if((distance >= 0.02*unit) && (distance <= 4*unit)) {
    ....
    return(distance);
  } else {
    ....
    return 0;
  }
}

如您所见,该写入了一些计算的结果。分配-1无处可见,但是AP_Utils :: sr04可以返回0,这表明未与结果进行比较。

结论


在本文中,我们检查了在嵌入式PlatformIO系统的编程环境中使用静态代码分析器检查微控制器上的项目的过程。让我提醒您,每个想尝试PVS-Studio的人都可以使用试用模式,对于开放项目,有机会获得免费许可证

对于那些想详细了解PVS-Studio功能的人,建议您阅读以下文章:




如果您想与讲英语的读者分享这篇文章,请使用翻译链接:Alexey Govorov。PlatformIO中的PVS-Studio集成

All Articles