دمج PVS-Studio في PlatformIO

صورة 5

في الآونة الأخيرة ، في بيئة تطوير النظام المضمنة PlatformIO ، ظهر دعم PVS-Studio. في هذه المقالة ، ستتعلم كيفية اختبار التعليمات البرمجية الخاصة بك باستخدام محلل ثابت باستخدام مشروع مفتوح كمثال.

ما هو برنامج PlatformIO؟


PlatformIO هي أداة برمجة متحكم عبر الأنظمة الأساسية. جوهر PlatformIO هو أداة سطر أوامر ، ولكن يوصى باستخدامه كمكون إضافي لبرنامج Visual Studio Code. يتم دعم عدد كبير من الرقائق واللوحات الأم الحديثة المعتمدة عليها. إنه قادر على تنزيل أنظمة التجميع المناسبة تلقائيًا ، ويحتوي الموقع على مجموعة كبيرة من المكتبات لإدارة المكونات الإلكترونية الإضافية. هناك دعم للعديد من أجهزة تحليل الشفرة الثابتة ، بما في ذلك PVS-Studio.

مشروع استيراد


للتوضيح ، لنأخذ برنامج التحكم ArduPod hexapod على لوحة Arduino Mega.


أنشئ مشروعًا جديدًا للوحة مناسبة وانسخ كود المصدر:

الصورة 2

في المجلد / arduino / AP_Utils / أمثلة / هناك العديد من الأمثلة على برامج تكوين وتشغيل hexapod ، سنستخدم 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

نتيجة فحص برنامج سداسي الأرجل


هذه المرة ، الهدف من المقالة هو إظهار تكامل 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));
    ....
  }
  ....
}

يتم طرح تعبيرين متطابقين من بعضهما البعض. من غير الواضح ما هو المعنى الرياضي لهذا الاختلاف. ربما لم يقلل المبرمج التعبير. أو ربما يُسمح بالخطأ المطبعي ، ويجب أن تكون هناك حجة أخرى بدلاً من أحد هذه الكلمات .

V550 مقارنة دقيقة غريبة: القيمة! = - 1. ربما يكون من الأفضل استخدام مقارنة بدقة محددة: fabs (A - B)> Epsilon. 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. دمج PVS-Studio في PlatformIO .

All Articles