From 7786a0da0097884da4e3680e2c7ba1e7012e5389 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Tue, 11 Jun 2024 00:42:24 +0100 Subject: [PATCH 01/13] Add gnu.cfg library. Make Cppcheck work without system headers (faster). - gnu.cfg replaces __typeof__ with typeof() and triggered some misra-c2012-10.4 - fixed by making both function args the same essential type --- board/safety/safety_hyundai_canfd.h | 4 ++-- board/safety/safety_hyundai_common.h | 12 ++++++------ board/safety/safety_nissan.h | 2 +- board/safety/safety_subaru_preglobal.h | 2 +- board/safety/safety_tesla.h | 6 +++--- board/safety_declarations.h | 2 ++ crypto/hash-internal.h | 2 +- tests/misra/test_misra.sh | 6 +++--- 8 files changed, 19 insertions(+), 17 deletions(-) diff --git a/board/safety/safety_hyundai_canfd.h b/board/safety/safety_hyundai_canfd.h index fb6ccf55a0..05832a2848 100644 --- a/board/safety/safety_hyundai_canfd.h +++ b/board/safety/safety_hyundai_canfd.h @@ -127,8 +127,8 @@ RxCheck hyundai_canfd_hda2_long_rx_checks[] = { -const int HYUNDAI_PARAM_CANFD_ALT_BUTTONS = 32; -const int HYUNDAI_PARAM_CANFD_HDA2_ALT_STEERING = 128; +const uint16_t HYUNDAI_PARAM_CANFD_ALT_BUTTONS = 32; +const uint16_t HYUNDAI_PARAM_CANFD_HDA2_ALT_STEERING = 128; bool hyundai_canfd_alt_buttons = false; bool hyundai_canfd_hda2_alt_steering = false; diff --git a/board/safety/safety_hyundai_common.h b/board/safety/safety_hyundai_common.h index 54ea0f024a..f81cff1be2 100644 --- a/board/safety/safety_hyundai_common.h +++ b/board/safety/safety_hyundai_common.h @@ -1,12 +1,12 @@ #ifndef SAFETY_HYUNDAI_COMMON_H #define SAFETY_HYUNDAI_COMMON_H -const int HYUNDAI_PARAM_EV_GAS = 1; -const int HYUNDAI_PARAM_HYBRID_GAS = 2; -const int HYUNDAI_PARAM_LONGITUDINAL = 4; -const int HYUNDAI_PARAM_CAMERA_SCC = 8; -const int HYUNDAI_PARAM_CANFD_HDA2 = 16; -const int HYUNDAI_PARAM_ALT_LIMITS = 64; // TODO: shift this down with the rest of the common flags +const uint8_t HYUNDAI_PARAM_EV_GAS = 1; +const uint8_t HYUNDAI_PARAM_HYBRID_GAS = 2; +const uint8_t HYUNDAI_PARAM_LONGITUDINAL = 4; +const uint8_t HYUNDAI_PARAM_CAMERA_SCC = 8; +const uint8_t HYUNDAI_PARAM_CANFD_HDA2 = 16; +const uint8_t HYUNDAI_PARAM_ALT_LIMITS = 64; // TODO: shift this down with the rest of the common flags const uint8_t HYUNDAI_PREV_BUTTON_SAMPLES = 8; // roughly 160 ms const uint32_t HYUNDAI_STANDSTILL_THRSLD = 12; // 0.375 kph diff --git a/board/safety/safety_nissan.h b/board/safety/safety_nissan.h index c2406260fe..458584ea94 100644 --- a/board/safety/safety_nissan.h +++ b/board/safety/safety_nissan.h @@ -36,7 +36,7 @@ RxCheck nissan_rx_checks[] = { }; // EPS Location. false = V-CAN, true = C-CAN -const int NISSAN_PARAM_ALT_EPS_BUS = 1; +const uint8_t NISSAN_PARAM_ALT_EPS_BUS = 1; bool nissan_alt_eps = false; diff --git a/board/safety/safety_subaru_preglobal.h b/board/safety/safety_subaru_preglobal.h index 1047814ac3..1b1271cfa5 100644 --- a/board/safety/safety_subaru_preglobal.h +++ b/board/safety/safety_subaru_preglobal.h @@ -37,7 +37,7 @@ RxCheck subaru_preglobal_rx_checks[] = { }; -const int SUBARU_PG_PARAM_REVERSED_DRIVER_TORQUE = 1; +const uint8_t SUBARU_PG_PARAM_REVERSED_DRIVER_TORQUE = 1; bool subaru_pg_reversed_driver_torque = false; diff --git a/board/safety/safety_tesla.h b/board/safety/safety_tesla.h index 652161ff2c..9ca098031e 100644 --- a/board/safety/safety_tesla.h +++ b/board/safety/safety_tesla.h @@ -17,9 +17,9 @@ const LongitudinalLimits TESLA_LONG_LIMITS = { }; -const int TESLA_FLAG_POWERTRAIN = 1; -const int TESLA_FLAG_LONGITUDINAL_CONTROL = 2; -const int TESLA_FLAG_RAVEN = 4; +const uint8_t TESLA_FLAG_POWERTRAIN = 1; +const uint8_t TESLA_FLAG_LONGITUDINAL_CONTROL = 2; +const uint8_t TESLA_FLAG_RAVEN = 4; const CanMsg TESLA_TX_MSGS[] = { {0x488, 0, 4}, // DAS_steeringControl diff --git a/board/safety_declarations.h b/board/safety_declarations.h index e3cdc47cde..428107d6bb 100644 --- a/board/safety_declarations.h +++ b/board/safety_declarations.h @@ -2,6 +2,8 @@ #define GET_BIT(msg, b) ((bool)!!(((msg)->data[((b) / 8U)] >> ((b) % 8U)) & 0x1U)) #define GET_BYTE(msg, b) ((msg)->data[(b)]) + +// cppcheck-suppress-macro misra-c2012-17.3 ; misra addon doesn't know __typeof__ symbol https://github.com/danmar/cppcheck/pull/5568#discussion_r1632304897 #define GET_FLAG(value, mask) (((__typeof__(mask))(value) & (mask)) == (mask)) // cppcheck-suppress misra-c2012-1.2; allow __typeof__ #define BUILD_SAFETY_CFG(rx, tx) ((safety_config){(rx), (sizeof((rx)) / sizeof((rx)[0])), \ diff --git a/crypto/hash-internal.h b/crypto/hash-internal.h index 05ec3ec9fd..c813b449f9 100644 --- a/crypto/hash-internal.h +++ b/crypto/hash-internal.h @@ -27,7 +27,7 @@ #ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_HASH_INTERNAL_H_ #define SYSTEM_CORE_INCLUDE_MINCRYPT_HASH_INTERNAL_H_ -#include "stdint.h" +#include #ifdef __cplusplus extern "C" { diff --git a/tests/misra/test_misra.sh b/tests/misra/test_misra.sh index e65f6a5e5a..61e1783e8c 100755 --- a/tests/misra/test_misra.sh +++ b/tests/misra/test_misra.sh @@ -36,7 +36,7 @@ echo "Cppcheck checkers list from test_misra.sh:" > $CHECKLIST cppcheck() { # get all gcc defines: arm-none-eabi-gcc -dM -E - < /dev/null - COMMON_DEFINES="-D__GNUC__=9 -UCMSIS_NVIC_VIRTUAL -UCMSIS_VECTAB_VIRTUAL" + COMMON_DEFINES="-D__GNUC__=9" # note that cppcheck build cache results in inconsistent results as of v2.13.0 OUTPUT=$DIR/.output.log @@ -45,10 +45,10 @@ cppcheck() { echo -e ""${@//$PANDA_DIR/}"\n\n" >> $CHECKLIST # (absolute path removed) $CPPCHECK_DIR/cppcheck --inline-suppr -I $PANDA_DIR/board/ \ - -I "$(arm-none-eabi-gcc -print-file-name=include)" \ + --library=gnu.cfg --suppress=missingIncludeSystem \ -I $PANDA_DIR/board/stm32f4/inc/ -I $PANDA_DIR/board/stm32h7/inc/ \ --suppressions-list=$DIR/suppressions.txt --suppress=*:*inc/* \ - --suppress=*:*include/* --error-exitcode=2 --check-level=exhaustive \ + --error-exitcode=2 --check-level=exhaustive \ --platform=arm32-wchar_t4 $COMMON_DEFINES --checkers-report=$CHECKLIST.tmp \ --std=c11 "$@" |& tee $OUTPUT From 15e70dfdbae57b469b70f89db0addc52a708a139 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Mon, 10 Jun 2024 22:07:32 +0100 Subject: [PATCH 02/13] simplify stm32 header include --- SConscript | 2 -- board/stm32f4/stm32f4_config.h | 4 ++-- board/stm32h7/stm32h7_config.h | 4 ++-- tests/misra/test_misra.sh | 1 - 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/SConscript b/SConscript index 8f4db59935..4c86d0cfab 100644 --- a/SConscript +++ b/SConscript @@ -136,7 +136,6 @@ base_project_f4 = { "-mhard-float", "-DSTM32F4", "-DSTM32F413xx", - "-Iboard/stm32f4/inc", "-mfpu=fpv4-sp-d16", "-fsingle-precision-constant", "-Os", @@ -154,7 +153,6 @@ base_project_h7 = { "-mhard-float", "-DSTM32H7", "-DSTM32H725xx", - "-Iboard/stm32h7/inc", "-mfpu=fpv5-d16", "-fsingle-precision-constant", "-Os", diff --git a/board/stm32f4/stm32f4_config.h b/board/stm32f4/stm32f4_config.h index 85baff25b5..2fdba9005e 100644 --- a/board/stm32f4/stm32f4_config.h +++ b/board/stm32f4/stm32f4_config.h @@ -1,5 +1,5 @@ -#include "stm32f4/inc/stm32f4xx.h" -#include "stm32f4/inc/stm32f4xx_hal_gpio_ex.h" +#include "inc/stm32f4xx.h" +#include "inc/stm32f4xx_hal_gpio_ex.h" #define MCU_IDCODE 0x463U // from the linker script diff --git a/board/stm32h7/stm32h7_config.h b/board/stm32h7/stm32h7_config.h index 64f149848d..935655da4c 100644 --- a/board/stm32h7/stm32h7_config.h +++ b/board/stm32h7/stm32h7_config.h @@ -1,5 +1,5 @@ -#include "stm32h7/inc/stm32h7xx.h" -#include "stm32h7/inc/stm32h7xx_hal_gpio_ex.h" +#include "inc/stm32h7xx.h" +#include "inc/stm32h7xx_hal_gpio_ex.h" #define MCU_IDCODE 0x483U // from the linker script diff --git a/tests/misra/test_misra.sh b/tests/misra/test_misra.sh index 61e1783e8c..f47930a864 100755 --- a/tests/misra/test_misra.sh +++ b/tests/misra/test_misra.sh @@ -46,7 +46,6 @@ cppcheck() { $CPPCHECK_DIR/cppcheck --inline-suppr -I $PANDA_DIR/board/ \ --library=gnu.cfg --suppress=missingIncludeSystem \ - -I $PANDA_DIR/board/stm32f4/inc/ -I $PANDA_DIR/board/stm32h7/inc/ \ --suppressions-list=$DIR/suppressions.txt --suppress=*:*inc/* \ --error-exitcode=2 --check-level=exhaustive \ --platform=arm32-wchar_t4 $COMMON_DEFINES --checkers-report=$CHECKLIST.tmp \ From 084fb517ee809407ffbf026e7ef18ccb79b6b934 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Mon, 10 Jun 2024 22:34:28 +0100 Subject: [PATCH 03/13] cppcheck panda whole program analysis - combines panda build configurations Increase mutation test timeout --- .github/workflows/test.yaml | 2 +- tests/misra/checkers.txt | 435 +------------------------------ tests/misra/panda_macro_config.h | 16 ++ tests/misra/test_misra.sh | 23 +- 4 files changed, 29 insertions(+), 447 deletions(-) create mode 100644 tests/misra/panda_macro_config.h diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 97c9e07f0e..fe0b0c1b29 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -100,7 +100,7 @@ jobs: timeout-minutes: 1 run: ${{ env.RUN }} "cd tests/misra && ./test_misra.sh" - name: MISRA mutation tests - timeout-minutes: 5 + timeout-minutes: 7 run: ${{ env.RUN }} "cd tests/misra && pytest -n8 test_mutation.py" python_linter: diff --git a/tests/misra/checkers.txt b/tests/misra/checkers.txt index a9cc72173c..4b39ceffd3 100644 --- a/tests/misra/checkers.txt +++ b/tests/misra/checkers.txt @@ -5,440 +5,7 @@ Cppcheck checkers list from test_misra.sh: TEST variant options: ---enable=all --disable=unusedFunction -DPANDA --addon=misra -DSTM32F4 -DSTM32F413xx /board/main.c - - -Critical errors ---------------- -No critical errors, all files were checked. -Important: Analysis is still not guaranteed to be 'complete' it is possible there are false negatives. - - -Open source checkers --------------------- -Yes Check64BitPortability::pointerassignment -Yes CheckAssert::assertWithSideEffects -Yes CheckAutoVariables::assignFunctionArg -Yes CheckAutoVariables::autoVariables -Yes CheckAutoVariables::checkVarLifetime -No CheckBool::checkAssignBoolToFloat require:style,c++ -Yes CheckBool::checkAssignBoolToPointer -No CheckBool::checkBitwiseOnBoolean require:style,inconclusive -Yes CheckBool::checkComparisonOfBoolExpressionWithInt -No CheckBool::checkComparisonOfBoolWithBool require:style,c++ -No CheckBool::checkComparisonOfBoolWithInt require:warning,c++ -No CheckBool::checkComparisonOfFuncReturningBool require:style,c++ -Yes CheckBool::checkIncrementBoolean -Yes CheckBool::pointerArithBool -Yes CheckBool::returnValueOfFunctionReturningBool -No CheckBoost::checkBoostForeachModification -Yes CheckBufferOverrun::analyseWholeProgram -Yes CheckBufferOverrun::argumentSize -Yes CheckBufferOverrun::arrayIndex -Yes CheckBufferOverrun::arrayIndexThenCheck -Yes CheckBufferOverrun::bufferOverflow -Yes CheckBufferOverrun::negativeArraySize -Yes CheckBufferOverrun::objectIndex -Yes CheckBufferOverrun::pointerArithmetic -No CheckBufferOverrun::stringNotZeroTerminated require:warning,inconclusive -Yes CheckClass::analyseWholeProgram -No CheckClass::checkConst require:style,inconclusive -No CheckClass::checkConstructors require:style,warning -No CheckClass::checkCopyConstructors require:warning -No CheckClass::checkDuplInheritedMembers require:warning -No CheckClass::checkExplicitConstructors require:style -No CheckClass::checkMemset -No CheckClass::checkMissingOverride require:style,c++03 -No CheckClass::checkReturnByReference require:performance -No CheckClass::checkSelfInitialization -No CheckClass::checkThisUseAfterFree require:warning -No CheckClass::checkUnsafeClassRefMember require:warning,safeChecks -No CheckClass::checkUselessOverride require:style -No CheckClass::checkVirtualFunctionCallInConstructor require:warning -No CheckClass::initializationListUsage require:performance -No CheckClass::initializerListOrder require:style,inconclusive -No CheckClass::operatorEqRetRefThis require:style -No CheckClass::operatorEqToSelf require:warning -No CheckClass::privateFunctions require:style -No CheckClass::thisSubtraction require:warning -No CheckClass::virtualDestructor -Yes CheckCondition::alwaysTrueFalse -Yes CheckCondition::assignIf -Yes CheckCondition::checkAssignmentInCondition -Yes CheckCondition::checkBadBitmaskCheck -Yes CheckCondition::checkCompareValueOutOfTypeRange -Yes CheckCondition::checkDuplicateConditionalAssign -Yes CheckCondition::checkIncorrectLogicOperator -Yes CheckCondition::checkInvalidTestForOverflow -Yes CheckCondition::checkModuloAlwaysTrueFalse -Yes CheckCondition::checkPointerAdditionResultNotNull -Yes CheckCondition::clarifyCondition -Yes CheckCondition::comparison -Yes CheckCondition::duplicateCondition -Yes CheckCondition::multiCondition -Yes CheckCondition::multiCondition2 -No CheckExceptionSafety::checkCatchExceptionByValue require:style -No CheckExceptionSafety::checkRethrowCopy require:style -No CheckExceptionSafety::deallocThrow require:warning -No CheckExceptionSafety::destructors require:warning -No CheckExceptionSafety::nothrowThrows -No CheckExceptionSafety::rethrowNoCurrentException -No CheckExceptionSafety::unhandledExceptionSpecification require:style,inconclusive -Yes CheckFunctions::checkIgnoredReturnValue -Yes CheckFunctions::checkMathFunctions -Yes CheckFunctions::checkMissingReturn -Yes CheckFunctions::checkProhibitedFunctions -Yes CheckFunctions::invalidFunctionUsage -Yes CheckFunctions::memsetInvalid2ndParam -Yes CheckFunctions::memsetZeroBytes -No CheckFunctions::returnLocalStdMove require:performance,c++11 -Yes CheckFunctions::useStandardLibrary -No CheckIO::checkCoutCerrMisusage require:c -Yes CheckIO::checkFileUsage -Yes CheckIO::checkWrongPrintfScanfArguments -Yes CheckIO::invalidScanf -Yes CheckLeakAutoVar::check -No CheckMemoryLeakInClass::check -Yes CheckMemoryLeakInFunction::checkReallocUsage -Yes CheckMemoryLeakNoVar::check -No CheckMemoryLeakNoVar::checkForUnsafeArgAlloc -Yes CheckMemoryLeakStructMember::check -Yes CheckNullPointer::analyseWholeProgram -Yes CheckNullPointer::arithmetic -Yes CheckNullPointer::nullConstantDereference -Yes CheckNullPointer::nullPointer -No CheckOther::checkAccessOfMovedVariable require:c++11,warning -Yes CheckOther::checkCastIntToCharAndBack -Yes CheckOther::checkCharVariable -Yes CheckOther::checkComparePointers -Yes CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalse -Yes CheckOther::checkConstPointer -No CheckOther::checkConstVariable require:style,c++ -No CheckOther::checkDuplicateBranch require:style,inconclusive -Yes CheckOther::checkDuplicateExpression -Yes CheckOther::checkEvaluationOrder -Yes CheckOther::checkFuncArgNamesDifferent -No CheckOther::checkIncompleteArrayFill require:warning,portability,inconclusive -Yes CheckOther::checkIncompleteStatement -No CheckOther::checkInterlockedDecrement require:windows-platform -Yes CheckOther::checkInvalidFree -Yes CheckOther::checkKnownArgument -Yes CheckOther::checkKnownPointerToBool -No CheckOther::checkMisusedScopedObject require:style,c++ -Yes CheckOther::checkModuloOfOne -Yes CheckOther::checkNanInArithmeticExpression -Yes CheckOther::checkNegativeBitwiseShift -Yes CheckOther::checkOverlappingWrite -No CheckOther::checkPassByReference require:performance,c++ -Yes CheckOther::checkRedundantAssignment -No CheckOther::checkRedundantCopy require:c++,performance,inconclusive -Yes CheckOther::checkRedundantPointerOp -Yes CheckOther::checkShadowVariables -Yes CheckOther::checkSignOfUnsignedVariable -No CheckOther::checkSuspiciousCaseInSwitch require:warning,inconclusive -No CheckOther::checkSuspiciousSemicolon require:warning,inconclusive -Yes CheckOther::checkUnreachableCode -Yes CheckOther::checkUnusedLabel -Yes CheckOther::checkVarFuncNullUB -Yes CheckOther::checkVariableScope -Yes CheckOther::checkZeroDivision -Yes CheckOther::clarifyCalculation -Yes CheckOther::clarifyStatement -Yes CheckOther::invalidPointerCast -Yes CheckOther::redundantBitwiseOperationInSwitch -No CheckOther::warningOldStylePointerCast require:style,c++ -No CheckPostfixOperator::postfixOperator require:performance -Yes CheckSizeof::checkSizeofForArrayParameter -Yes CheckSizeof::checkSizeofForNumericParameter -Yes CheckSizeof::checkSizeofForPointerSize -Yes CheckSizeof::sizeofCalculation -Yes CheckSizeof::sizeofFunction -Yes CheckSizeof::sizeofVoid -Yes CheckSizeof::sizeofsizeof -No CheckSizeof::suspiciousSizeofCalculation require:warning,inconclusive -No CheckStl::checkDereferenceInvalidIterator require:warning -No CheckStl::checkDereferenceInvalidIterator2 -No CheckStl::checkFindInsert require:performance -No CheckStl::checkMutexes require:warning -No CheckStl::erase -No CheckStl::eraseIteratorOutOfBounds -No CheckStl::if_find require:warning,performance -No CheckStl::invalidContainer -No CheckStl::iterators -No CheckStl::knownEmptyContainer require:style -No CheckStl::misMatchingContainerIterator -No CheckStl::misMatchingContainers -No CheckStl::missingComparison require:warning -No CheckStl::negativeIndex -No CheckStl::outOfBounds -No CheckStl::outOfBoundsIndexExpression -No CheckStl::redundantCondition require:style -No CheckStl::size require:performance,c++03 -No CheckStl::stlBoundaries -No CheckStl::stlOutOfBounds -No CheckStl::string_c_str -No CheckStl::useStlAlgorithm require:style -No CheckStl::uselessCalls require:performance,warning -Yes CheckString::checkAlwaysTrueOrFalseStringCompare -Yes CheckString::checkIncorrectStringCompare -Yes CheckString::checkSuspiciousStringCompare -Yes CheckString::overlappingStrcmp -Yes CheckString::sprintfOverlappingData -Yes CheckString::strPlusChar -Yes CheckString::stringLiteralWrite -Yes CheckType::checkFloatToIntegerOverflow -Yes CheckType::checkIntegerOverflow -Yes CheckType::checkLongCast -Yes CheckType::checkSignConversion -Yes CheckType::checkTooBigBitwiseShift -Yes CheckUninitVar::check -Yes CheckUninitVar::valueFlowUninit -No CheckUnusedFunctions::check require:unusedFunction -Yes CheckUnusedVar::checkFunctionVariableUsage -Yes CheckUnusedVar::checkStructMemberUsage -Yes CheckVaarg::va_list_usage -Yes CheckVaarg::va_start_argument - - -Premium checkers ----------------- -Not available, Cppcheck Premium is not used - - -Autosar -------- -Not available, Cppcheck Premium is not used - - -Cert C ------- -Not available, Cppcheck Premium is not used - - -Cert C++ --------- -Not available, Cppcheck Premium is not used - - -Misra C 2012 ------------- -Yes Misra C 2012: 1.1 -Yes Misra C 2012: 1.2 -Yes Misra C 2012: 1.3 -Yes Misra C 2012: 1.4 amendment:2 -No Misra C 2012: 1.5 amendment:3 require:premium -Yes Misra C 2012: 2.1 -Yes Misra C 2012: 2.2 -Yes Misra C 2012: 2.3 -Yes Misra C 2012: 2.4 -Yes Misra C 2012: 2.5 -Yes Misra C 2012: 2.6 -Yes Misra C 2012: 2.7 -Yes Misra C 2012: 2.8 -Yes Misra C 2012: 3.1 -Yes Misra C 2012: 3.2 -Yes Misra C 2012: 4.1 -Yes Misra C 2012: 4.2 -Yes Misra C 2012: 5.1 -Yes Misra C 2012: 5.2 -Yes Misra C 2012: 5.3 -Yes Misra C 2012: 5.4 -Yes Misra C 2012: 5.5 -Yes Misra C 2012: 5.6 -Yes Misra C 2012: 5.7 -Yes Misra C 2012: 5.8 -Yes Misra C 2012: 5.9 -Yes Misra C 2012: 6.1 -Yes Misra C 2012: 6.2 -No Misra C 2012: 6.3 -Yes Misra C 2012: 7.1 -Yes Misra C 2012: 7.2 -Yes Misra C 2012: 7.3 -Yes Misra C 2012: 7.4 -No Misra C 2012: 7.5 -No Misra C 2012: 7.6 -Yes Misra C 2012: 8.1 -Yes Misra C 2012: 8.2 -No Misra C 2012: 8.3 -Yes Misra C 2012: 8.4 -Yes Misra C 2012: 8.5 -Yes Misra C 2012: 8.6 -Yes Misra C 2012: 8.7 -Yes Misra C 2012: 8.8 -Yes Misra C 2012: 8.9 -Yes Misra C 2012: 8.10 -Yes Misra C 2012: 8.11 -Yes Misra C 2012: 8.12 -Yes Misra C 2012: 8.13 -Yes Misra C 2012: 8.14 -No Misra C 2012: 8.15 -No Misra C 2012: 8.16 -No Misra C 2012: 8.17 -Yes Misra C 2012: 9.1 -Yes Misra C 2012: 9.2 -Yes Misra C 2012: 9.3 -Yes Misra C 2012: 9.4 -Yes Misra C 2012: 9.5 -No Misra C 2012: 9.6 -No Misra C 2012: 9.7 -Yes Misra C 2012: 10.1 -Yes Misra C 2012: 10.2 -Yes Misra C 2012: 10.3 -Yes Misra C 2012: 10.4 -Yes Misra C 2012: 10.5 -Yes Misra C 2012: 10.6 -Yes Misra C 2012: 10.7 -Yes Misra C 2012: 10.8 -Yes Misra C 2012: 11.1 -Yes Misra C 2012: 11.2 -Yes Misra C 2012: 11.3 -Yes Misra C 2012: 11.4 -Yes Misra C 2012: 11.5 -Yes Misra C 2012: 11.6 -Yes Misra C 2012: 11.7 -Yes Misra C 2012: 11.8 -Yes Misra C 2012: 11.9 -No Misra C 2012: 11.10 -Yes Misra C 2012: 12.1 -Yes Misra C 2012: 12.2 -Yes Misra C 2012: 12.3 -Yes Misra C 2012: 12.4 -Yes Misra C 2012: 12.5 amendment:1 -No Misra C 2012: 12.6 amendment:4 require:premium -Yes Misra C 2012: 13.1 -No Misra C 2012: 13.2 -Yes Misra C 2012: 13.3 -Yes Misra C 2012: 13.4 -Yes Misra C 2012: 13.5 -Yes Misra C 2012: 13.6 -Yes Misra C 2012: 14.1 -Yes Misra C 2012: 14.2 -Yes Misra C 2012: 14.3 -Yes Misra C 2012: 14.4 -Yes Misra C 2012: 15.1 -Yes Misra C 2012: 15.2 -Yes Misra C 2012: 15.3 -Yes Misra C 2012: 15.4 -Yes Misra C 2012: 15.5 -Yes Misra C 2012: 15.6 -Yes Misra C 2012: 15.7 -Yes Misra C 2012: 16.1 -Yes Misra C 2012: 16.2 -Yes Misra C 2012: 16.3 -Yes Misra C 2012: 16.4 -Yes Misra C 2012: 16.5 -Yes Misra C 2012: 16.6 -Yes Misra C 2012: 16.7 -Yes Misra C 2012: 17.1 -Yes Misra C 2012: 17.2 -Yes Misra C 2012: 17.3 -No Misra C 2012: 17.4 -Yes Misra C 2012: 17.5 -Yes Misra C 2012: 17.6 -Yes Misra C 2012: 17.7 -Yes Misra C 2012: 17.8 -No Misra C 2012: 17.9 -No Misra C 2012: 17.10 -No Misra C 2012: 17.11 -No Misra C 2012: 17.12 -No Misra C 2012: 17.13 -Yes Misra C 2012: 18.1 -Yes Misra C 2012: 18.2 -Yes Misra C 2012: 18.3 -Yes Misra C 2012: 18.4 -Yes Misra C 2012: 18.5 -Yes Misra C 2012: 18.6 -Yes Misra C 2012: 18.7 -Yes Misra C 2012: 18.8 -No Misra C 2012: 18.9 -No Misra C 2012: 18.10 -Yes Misra C 2012: 19.1 -Yes Misra C 2012: 19.2 -Yes Misra C 2012: 20.1 -Yes Misra C 2012: 20.2 -Yes Misra C 2012: 20.3 -Yes Misra C 2012: 20.4 -Yes Misra C 2012: 20.5 -Yes Misra C 2012: 20.6 -Yes Misra C 2012: 20.7 -Yes Misra C 2012: 20.8 -Yes Misra C 2012: 20.9 -Yes Misra C 2012: 20.10 -Yes Misra C 2012: 20.11 -Yes Misra C 2012: 20.12 -Yes Misra C 2012: 20.13 -Yes Misra C 2012: 20.14 -Yes Misra C 2012: 21.1 -Yes Misra C 2012: 21.2 -Yes Misra C 2012: 21.3 -Yes Misra C 2012: 21.4 -Yes Misra C 2012: 21.5 -Yes Misra C 2012: 21.6 -Yes Misra C 2012: 21.7 -Yes Misra C 2012: 21.8 -Yes Misra C 2012: 21.9 -Yes Misra C 2012: 21.10 -Yes Misra C 2012: 21.11 -Yes Misra C 2012: 21.12 -Yes Misra C 2012: 21.13 amendment:1 -Yes Misra C 2012: 21.14 amendment:1 -Yes Misra C 2012: 21.15 amendment:1 -Yes Misra C 2012: 21.16 amendment:1 -Yes Misra C 2012: 21.17 amendment:1 -Yes Misra C 2012: 21.18 amendment:1 -Yes Misra C 2012: 21.19 amendment:1 -Yes Misra C 2012: 21.20 amendment:1 -Yes Misra C 2012: 21.21 amendment:3 -No Misra C 2012: 21.22 amendment:3 require:premium -No Misra C 2012: 21.23 amendment:3 require:premium -No Misra C 2012: 21.24 amendment:3 require:premium -No Misra C 2012: 21.25 amendment:4 require:premium -No Misra C 2012: 21.26 amendment:4 require:premium -Yes Misra C 2012: 22.1 -Yes Misra C 2012: 22.2 -Yes Misra C 2012: 22.3 -Yes Misra C 2012: 22.4 -Yes Misra C 2012: 22.5 -Yes Misra C 2012: 22.6 -Yes Misra C 2012: 22.7 amendment:1 -Yes Misra C 2012: 22.8 amendment:1 -Yes Misra C 2012: 22.9 amendment:1 -Yes Misra C 2012: 22.10 amendment:1 -No Misra C 2012: 22.11 amendment:4 require:premium -No Misra C 2012: 22.12 amendment:4 require:premium -No Misra C 2012: 22.13 amendment:4 require:premium -No Misra C 2012: 22.14 amendment:4 require:premium -No Misra C 2012: 22.15 amendment:4 require:premium -No Misra C 2012: 22.16 amendment:4 require:premium -No Misra C 2012: 22.17 amendment:4 require:premium -No Misra C 2012: 22.18 amendment:4 require:premium -No Misra C 2012: 22.19 amendment:4 require:premium -No Misra C 2012: 22.20 amendment:4 require:premium -No Misra C 2012: 23.1 amendment:3 require:premium -No Misra C 2012: 23.2 amendment:3 require:premium -No Misra C 2012: 23.3 amendment:3 require:premium -No Misra C 2012: 23.4 amendment:3 require:premium -No Misra C 2012: 23.5 amendment:3 require:premium -No Misra C 2012: 23.6 amendment:3 require:premium -No Misra C 2012: 23.7 amendment:3 require:premium -No Misra C 2012: 23.8 amendment:3 require:premium - - -Misra C++ 2008 --------------- -Not available, Cppcheck Premium is not used - - -Misra C++ 2023 --------------- -Not available, Cppcheck Premium is not used - - - - - -TEST variant options: ---enable=all --disable=unusedFunction -DPANDA --addon=misra -DSTM32H7 -DSTM32H725xx /board/main.c +/board/main.c -I/board/ -DPANDA -DALLOW_DEBUG -UPANDA_JUNGLE -UFINAL_PROVISIONING -UBOOTSTUB -UDEBUG -UDEBUG_COMMS -UDEBUG_FAULTS -UDEBUG_FAN -UDEBUG_SPI -UDEBUG_UART -UDEBUG_USB --config-exclude=/board/stm32f4/inc --config-exclude=/board/stm32h7/inc --include=/tests/misra/panda_macro_config.h -i/tests/misra --enable=all --addon=misra --disable=unusedFunction --force --suppress=unknownMacro Critical errors diff --git a/tests/misra/panda_macro_config.h b/tests/misra/panda_macro_config.h new file mode 100644 index 0000000000..30ba1cfc8f --- /dev/null +++ b/tests/misra/panda_macro_config.h @@ -0,0 +1,16 @@ +// This is a dummy structure to allow cppcheck to test certain macro combinations +// together and in one seesion (needed for things like unused macros) +// The structure should represents macro configurations used in scons + +#ifdef STM32H7 + #ifdef STM32H725xx + #elif defined(STM32H723) + #else + #endif +#elif defined(STM32F4) + #ifdef STM32F413xx + #ifdef ENABLE_SPI + #endif + #endif +#else +#endif diff --git a/tests/misra/test_misra.sh b/tests/misra/test_misra.sh index f47930a864..df3e023243 100755 --- a/tests/misra/test_misra.sh +++ b/tests/misra/test_misra.sh @@ -61,18 +61,17 @@ cppcheck() { fi } -PANDA_OPTS="--enable=all --disable=unusedFunction -DPANDA --addon=misra" - -printf "\n${GREEN}** PANDA F4 CODE **${NC}\n" -cppcheck $PANDA_OPTS -DSTM32F4 -DSTM32F413xx $PANDA_DIR/board/main.c - -printf "\n${GREEN}** PANDA H7 CODE **${NC}\n" -cppcheck $PANDA_OPTS -DSTM32H7 -DSTM32H725xx $PANDA_DIR/board/main.c - -# unused needs to run globally -#printf "\n${GREEN}** UNUSED ALL CODE **${NC}\n" -#cppcheck --enable=unusedFunction --quiet $PANDA_DIR/board/ - +# --force checks different macro combinations to avoid reporting macros and functions used by only one panda configuration +# panda_macro_config.h lets cppcheck know macro combinations used for the build +printf "\n${GREEN}** Panda tests: cppcheck whole program anlysis + Misra addon system level analysis **${NC}\n" +UNDEBUG="-UDEBUG -UDEBUG_COMMS -UDEBUG_FAULTS -UDEBUG_FAN -UDEBUG_SPI -UDEBUG_UART -UDEBUG_USB" +cppcheck $PANDA_DIR/board/main.c -I$PANDA_DIR/board/ \ + -DPANDA -DALLOW_DEBUG \ + -UPANDA_JUNGLE -UFINAL_PROVISIONING -UBOOTSTUB $UNDEBUG \ + --config-exclude=$PANDA_DIR/board/stm32f4/inc --config-exclude=$PANDA_DIR/board/stm32h7/inc \ + --include=$DIR/panda_macro_config.h -i$DIR \ + --enable=all --addon=misra --disable=unusedFunction \ + --force --suppress=unknownMacro printf "\n${GREEN}Success!${NC} took $SECONDS seconds\n" From f604fc6919f9f30115b8b82e9fd85d14a857fc97 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Mon, 10 Jun 2024 20:57:11 +0100 Subject: [PATCH 04/13] enable unusedFunction check for Panda program remove Panda specific functions --- board/drivers/can_common.h | 2 ++ board/drivers/gpio.h | 12 +++++++----- board/stm32f4/peripherals.h | 5 +++++ board/stm32h7/peripherals.h | 11 +++++++---- tests/misra/checkers.txt | 4 ++-- tests/misra/test_misra.sh | 2 +- tests/misra/test_mutation.py | 2 ++ 7 files changed, 26 insertions(+), 12 deletions(-) diff --git a/board/drivers/can_common.h b/board/drivers/can_common.h index 3a829c69ab..d34751ebf7 100644 --- a/board/drivers/can_common.h +++ b/board/drivers/can_common.h @@ -191,9 +191,11 @@ void can_set_orientation(bool flipped) { bus_config[2].can_num_lookup = flipped ? 0U : 2U; } +#ifdef FINAL_PROVISIONING // only used in jungle final provisioning void can_set_forwarding(uint8_t from, uint8_t to) { bus_config[from].forwarding_bus = to; } +#endif void ignition_can_hook(CANPacket_t *to_push) { int bus = GET_BUS(to_push); diff --git a/board/drivers/gpio.h b/board/drivers/gpio.h index 0b8fc091b1..aea604254e 100644 --- a/board/drivers/gpio.h +++ b/board/drivers/gpio.h @@ -10,11 +10,6 @@ #define OUTPUT_TYPE_PUSH_PULL 0U #define OUTPUT_TYPE_OPEN_DRAIN 1U -typedef struct { - GPIO_TypeDef * const bank; - uint8_t pin; -} gpio_t; - void set_gpio_mode(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int mode) { ENTER_CRITICAL(); uint32_t tmp = GPIO->MODER; @@ -68,6 +63,12 @@ int get_gpio_input(const GPIO_TypeDef *GPIO, unsigned int pin) { return (GPIO->IDR & (1UL << pin)) == (1UL << pin); } +#ifdef PANDA_JUNGLE +typedef struct { + GPIO_TypeDef * const bank; + uint8_t pin; +} gpio_t; + void gpio_set_all_output(gpio_t *pins, uint8_t num_pins, bool enabled) { for (uint8_t i = 0; i < num_pins; i++) { set_gpio_output(pins[i].bank, pins[i].pin, enabled); @@ -79,6 +80,7 @@ void gpio_set_bitmask(gpio_t *pins, uint8_t num_pins, uint32_t bitmask) { set_gpio_output(pins[i].bank, pins[i].pin, (bitmask >> i) & 1U); } } +#endif // Detection with internal pullup #define PULL_EFFECTIVE_DELAY 4096 diff --git a/board/stm32f4/peripherals.h b/board/stm32f4/peripherals.h index 711f1b82a0..04832536d6 100644 --- a/board/stm32f4/peripherals.h +++ b/board/stm32f4/peripherals.h @@ -14,11 +14,13 @@ void gpio_spi_init(void) { register_set_bits(&(GPIOA->OSPEEDR), GPIO_OSPEEDER_OSPEEDR4 | GPIO_OSPEEDER_OSPEEDR5 | GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7); } +#ifdef BOOTSTUB void gpio_usart2_init(void) { // A2,A3: USART 2 for debugging set_gpio_alternate(GPIOA, 2, GPIO_AF7_USART2); set_gpio_alternate(GPIOA, 3, GPIO_AF7_USART2); } +#endif // Common GPIO initialization void common_init_gpio(void) { @@ -41,12 +43,14 @@ void common_init_gpio(void) { set_gpio_alternate(GPIOB, 9, GPIO_AF8_CAN1); } +#ifdef BOOTSTUB void flasher_peripherals_init(void) { RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN; RCC->APB1ENR |= RCC_APB1ENR_USART2EN; } +#else // Peripheral initialization void peripherals_init(void) { @@ -84,6 +88,7 @@ void peripherals_init(void) { RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; // interrupt timer RCC->APB2ENR |= RCC_APB2ENR_TIM9EN; // slow loop } +#endif void enable_interrupt_timer(void) { register_set_bits(&(RCC->APB1ENR), RCC_APB1ENR_TIM6EN); // Enable interrupt timer peripheral diff --git a/board/stm32h7/peripherals.h b/board/stm32h7/peripherals.h index b60f19016d..22c3775d32 100644 --- a/board/stm32h7/peripherals.h +++ b/board/stm32h7/peripherals.h @@ -13,11 +13,13 @@ void gpio_spi_init(void) { register_set_bits(&(GPIOE->OSPEEDR), GPIO_OSPEEDR_OSPEED11 | GPIO_OSPEEDR_OSPEED12 | GPIO_OSPEEDR_OSPEED13 | GPIO_OSPEEDR_OSPEED14); } +#ifdef BOOTSTUB void gpio_usart2_init(void) { // A2,A3: USART 2 for debugging set_gpio_alternate(GPIOA, 2, GPIO_AF7_USART2); set_gpio_alternate(GPIOA, 3, GPIO_AF7_USART2); } +#endif void gpio_uart7_init(void) { // E7,E8: UART 7 for debugging @@ -78,6 +80,7 @@ void common_init_gpio(void) { set_gpio_alternate(GPIOG, 10, GPIO_AF2_FDCAN3); } +#ifdef BOOTSTUB void flasher_peripherals_init(void) { RCC->AHB1ENR |= RCC_AHB1ENR_USB1OTGHSEN; @@ -85,7 +88,7 @@ void flasher_peripherals_init(void) { RCC->APB2ENR |= RCC_APB2ENR_SPI4EN; RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; } - +#else // Peripheral initialization void peripherals_init(void) { // enable GPIO(A,B,C,D,E,F,G,H) @@ -126,12 +129,12 @@ void peripherals_init(void) { RCC->APB1LENR |= RCC_APB1LENR_TIM7EN; // DMA trigger timer RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; // tick timer RCC->APB1LENR |= RCC_APB1LENR_TIM12EN; // slow loop - -#ifdef PANDA_JUNGLE + #ifdef PANDA_JUNGLE RCC->AHB3ENR |= RCC_AHB3ENR_SDMMC1EN; // SDMMC RCC->AHB4ENR |= RCC_AHB4ENR_ADC3EN; // Enable ADC3 clocks -#endif + #endif } +#endif void enable_interrupt_timer(void) { register_set_bits(&(RCC->APB1LENR), RCC_APB1LENR_TIM6EN); // Enable interrupt timer peripheral diff --git a/tests/misra/checkers.txt b/tests/misra/checkers.txt index 4b39ceffd3..714bde0210 100644 --- a/tests/misra/checkers.txt +++ b/tests/misra/checkers.txt @@ -5,7 +5,7 @@ Cppcheck checkers list from test_misra.sh: TEST variant options: -/board/main.c -I/board/ -DPANDA -DALLOW_DEBUG -UPANDA_JUNGLE -UFINAL_PROVISIONING -UBOOTSTUB -UDEBUG -UDEBUG_COMMS -UDEBUG_FAULTS -UDEBUG_FAN -UDEBUG_SPI -UDEBUG_UART -UDEBUG_USB --config-exclude=/board/stm32f4/inc --config-exclude=/board/stm32h7/inc --include=/tests/misra/panda_macro_config.h -i/tests/misra --enable=all --addon=misra --disable=unusedFunction --force --suppress=unknownMacro +/board/main.c -I/board/ -DPANDA -DALLOW_DEBUG -UPANDA_JUNGLE -UFINAL_PROVISIONING -UBOOTSTUB -UDEBUG -UDEBUG_COMMS -UDEBUG_FAULTS -UDEBUG_FAN -UDEBUG_SPI -UDEBUG_UART -UDEBUG_USB --config-exclude=/board/stm32f4/inc --config-exclude=/board/stm32h7/inc --include=/tests/misra/panda_macro_config.h -i/tests/misra --enable=all --addon=misra --force --suppress=unknownMacro Critical errors @@ -193,7 +193,7 @@ Yes CheckType::checkSignConversion Yes CheckType::checkTooBigBitwiseShift Yes CheckUninitVar::check Yes CheckUninitVar::valueFlowUninit -No CheckUnusedFunctions::check require:unusedFunction +Yes CheckUnusedFunctions::check Yes CheckUnusedVar::checkFunctionVariableUsage Yes CheckUnusedVar::checkStructMemberUsage Yes CheckVaarg::va_list_usage diff --git a/tests/misra/test_misra.sh b/tests/misra/test_misra.sh index df3e023243..e930fa41aa 100755 --- a/tests/misra/test_misra.sh +++ b/tests/misra/test_misra.sh @@ -70,7 +70,7 @@ cppcheck $PANDA_DIR/board/main.c -I$PANDA_DIR/board/ \ -UPANDA_JUNGLE -UFINAL_PROVISIONING -UBOOTSTUB $UNDEBUG \ --config-exclude=$PANDA_DIR/board/stm32f4/inc --config-exclude=$PANDA_DIR/board/stm32h7/inc \ --include=$DIR/panda_macro_config.h -i$DIR \ - --enable=all --addon=misra --disable=unusedFunction \ + --enable=all --addon=misra \ --force --suppress=unknownMacro printf "\n${GREEN}Success!${NC} took $SECONDS seconds\n" diff --git a/tests/misra/test_mutation.py b/tests/misra/test_mutation.py index 796b93dd27..c804135b81 100755 --- a/tests/misra/test_mutation.py +++ b/tests/misra/test_mutation.py @@ -57,6 +57,8 @@ r"$a #define auto 1\n", # misra-c2012-20.5 r"$a #define TEST 1\n#undef TEST\n", + # unusedFunction + r"$a void test(void) {}", ] all_files = glob.glob('board/**', root_dir=ROOT, recursive=True) From a4f9e2a2228d54a9ff78d70d9d16e66e9ff431c6 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Thu, 30 May 2024 21:54:07 +0100 Subject: [PATCH 05/13] removed globally unused functions STMF4 doesn't use uart interrupt DAC and watchdog are not used --- board/drivers/uart.h | 15 --------- board/drivers/usb.h | 8 ----- board/drivers/watchdog.h | 24 --------------- board/stm32f4/lluart.h | 56 ---------------------------------- board/stm32f4/stm32f4_config.h | 1 - board/stm32h7/board.h | 1 - board/stm32h7/lldac.h | 42 ------------------------- board/stm32h7/stm32h7_config.h | 1 - 8 files changed, 148 deletions(-) delete mode 100644 board/drivers/watchdog.h delete mode 100644 board/stm32h7/lldac.h diff --git a/board/drivers/uart.h b/board/drivers/uart.h index 01d8c2ac05..4836889779 100644 --- a/board/drivers/uart.h +++ b/board/drivers/uart.h @@ -37,7 +37,6 @@ typedef struct uart_ring { // ***************************** Function prototypes ***************************** void debug_ring_callback(uart_ring *ring); void uart_tx_ring(uart_ring *q); -void uart_send_break(uart_ring *u); // ******************************** UART buffers ******************************** @@ -151,20 +150,6 @@ void print(const char *a) { } } -void putui(uint32_t i) { - uint32_t i_copy = i; - char str[11]; - uint8_t idx = 10; - str[idx] = '\0'; - idx--; - do { - str[idx] = (i_copy % 10U) + 0x30U; - idx--; - i_copy /= 10; - } while (i_copy != 0U); - print(&str[idx + 1U]); -} - void puthx(uint32_t i, uint8_t len) { const char c[] = "0123456789abcdef"; for (int pos = ((int)len * 4) - 4; pos > -4; pos -= 4) { diff --git a/board/drivers/usb.h b/board/drivers/usb.h index e006372216..a719910d77 100644 --- a/board/drivers/usb.h +++ b/board/drivers/usb.h @@ -914,11 +914,3 @@ void can_tx_comms_resume_usb(void) { } EXIT_CRITICAL(); } - -void usb_soft_disconnect(bool enable) { - if (enable) { - USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS; - } else { - USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS; - } -} diff --git a/board/drivers/watchdog.h b/board/drivers/watchdog.h deleted file mode 100644 index 89cf01e07e..0000000000 --- a/board/drivers/watchdog.h +++ /dev/null @@ -1,24 +0,0 @@ -typedef enum { - WATCHDOG_50_MS = (400U - 1U), - WATCHDOG_500_MS = 4000U, -} WatchdogTimeout; - -void watchdog_feed(void) { - IND_WDG->KR = 0xAAAAU; -} - -void watchdog_init(WatchdogTimeout timeout) { - // enable watchdog - IND_WDG->KR = 0xCCCCU; - IND_WDG->KR = 0x5555U; - - // 32KHz / 4 prescaler = 8000Hz - register_set(&(IND_WDG->PR), 0x0U, IWDG_PR_PR_Msk); - register_set(&(IND_WDG->RLR), timeout, IWDG_RLR_RL_Msk); - - // wait for watchdog to be updated - while (IND_WDG->SR != 0U); - - // start the countdown - watchdog_feed(); -} diff --git a/board/stm32f4/lluart.h b/board/stm32f4/lluart.h index 64094119f4..872f23c7bd 100644 --- a/board/stm32f4/lluart.h +++ b/board/stm32f4/lluart.h @@ -20,65 +20,9 @@ void uart_tx_ring(uart_ring *q){ EXIT_CRITICAL(); } -void uart_rx_ring(uart_ring *q){ - ENTER_CRITICAL(); - - // Read out RX buffer - uint8_t c = q->uart->DR; // This read after reading SR clears a bunch of interrupts - - uint16_t next_w_ptr = (q->w_ptr_rx + 1U) % q->rx_fifo_size; - - if ((next_w_ptr == q->r_ptr_rx) && q->overwrite) { - // overwrite mode: drop oldest byte - q->r_ptr_rx = (q->r_ptr_rx + 1U) % q->rx_fifo_size; - } - - // Do not overwrite buffer data - if (next_w_ptr != q->r_ptr_rx) { - q->elems_rx[q->w_ptr_rx] = c; - q->w_ptr_rx = next_w_ptr; - if (q->callback != NULL) { - q->callback(q); - } - } - - EXIT_CRITICAL(); -} - -void uart_send_break(uart_ring *u) { - while ((u->uart->CR1 & USART_CR1_SBK) != 0U); - u->uart->CR1 |= USART_CR1_SBK; -} - // This read after reading SR clears all error interrupts. We don't want compiler warnings, nor optimizations #define UART_READ_DR(uart) volatile uint8_t t = (uart)->DR; UNUSED(t); -void uart_interrupt_handler(uart_ring *q) { - ENTER_CRITICAL(); - - // Read UART status. This is also the first step necessary in clearing most interrupts - uint32_t status = q->uart->SR; - - // If RXNE is set, perform a read. This clears RXNE, ORE, IDLE, NF and FE - if((status & USART_SR_RXNE) != 0U){ - uart_rx_ring(q); - } - - // Detect errors and clear them - uint32_t err = (status & USART_SR_ORE) | (status & USART_SR_NE) | (status & USART_SR_FE) | (status & USART_SR_PE); - if(err != 0U){ - #ifdef DEBUG_UART - print("Encountered UART error: "); puth(err); print("\n"); - #endif - UART_READ_DR(q->uart) - } - // Send if necessary - uart_tx_ring(q); - - EXIT_CRITICAL(); -} - -void USART2_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_debug); } // ***************************** Hardware setup ***************************** diff --git a/board/stm32f4/stm32f4_config.h b/board/stm32f4/stm32f4_config.h index 2fdba9005e..ea382e682f 100644 --- a/board/stm32f4/stm32f4_config.h +++ b/board/stm32f4/stm32f4_config.h @@ -55,7 +55,6 @@ #include "drivers/timers.h" #include "stm32f4/board.h" #include "stm32f4/clock.h" -#include "drivers/watchdog.h" #include "drivers/spi.h" #include "stm32f4/llspi.h" diff --git a/board/stm32h7/board.h b/board/stm32h7/board.h index f5a8e55aa8..c8e6f3a968 100644 --- a/board/stm32h7/board.h +++ b/board/stm32h7/board.h @@ -9,7 +9,6 @@ #include "drivers/harness.h" #include "drivers/fan.h" #include "stm32h7/llfan.h" -#include "stm32h7/lldac.h" #include "drivers/fake_siren.h" #include "drivers/clock_source.h" #include "boards/red.h" diff --git a/board/stm32h7/lldac.h b/board/stm32h7/lldac.h deleted file mode 100644 index 5726f62413..0000000000 --- a/board/stm32h7/lldac.h +++ /dev/null @@ -1,42 +0,0 @@ -void dac_init(DAC_TypeDef *dac, uint8_t channel, bool dma) { - register_set(&dac->CR, 0U, 0xFFFFU); - register_set(&dac->MCR, 0U, 0xFFFFU); - - switch(channel) { - case 1: - if (dma) { - register_set_bits(&dac->CR, DAC_CR_DMAEN1); - // register_set(&DAC->CR, (6U << DAC_CR_TSEL1_Pos), DAC_CR_TSEL1); - register_set_bits(&dac->CR, DAC_CR_TEN1); - } else { - register_clear_bits(&dac->CR, DAC_CR_DMAEN1); - } - register_set_bits(&dac->CR, DAC_CR_EN1); - break; - case 2: - if (dma) { - register_set_bits(&dac->CR, DAC_CR_DMAEN2); - } else { - register_clear_bits(&dac->CR, DAC_CR_DMAEN2); - } - register_set_bits(&dac->CR, DAC_CR_EN2); - break; - default: - break; - } -} - -// Set channel 1 value, in mV -void dac_set(DAC_TypeDef *dac, uint8_t channel, uint32_t value) { - uint32_t raw_val = MAX(MIN(value * (1UL << 8U) / 3300U, (1UL << 8U)), 0U); - switch(channel) { - case 1: - register_set(&dac->DHR8R1, raw_val, 0xFFU); - break; - case 2: - register_set(&dac->DHR8R2, raw_val, 0xFFU); - break; - default: - break; - } -} diff --git a/board/stm32h7/stm32h7_config.h b/board/stm32h7/stm32h7_config.h index 935655da4c..08e94f61a0 100644 --- a/board/stm32h7/stm32h7_config.h +++ b/board/stm32h7/stm32h7_config.h @@ -66,7 +66,6 @@ separate IRQs for RX and TX. #include "stm32h7/peripherals.h" #include "stm32h7/interrupt_handlers.h" #include "drivers/timers.h" -#include "drivers/watchdog.h" #if !defined(BOOTSTUB) #include "drivers/uart.h" From 9390319a2b175dc4a096daf4d8172f7a3f3378ac Mon Sep 17 00:00:00 2001 From: dzid26 Date: Sun, 26 May 2024 17:13:05 +0100 Subject: [PATCH 06/13] moved hundai canfd checksum into canfd header --- board/safety/safety_hyundai_canfd.h | 25 +++++++++++++++++++++++++ board/safety/safety_hyundai_common.h | 25 ------------------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/board/safety/safety_hyundai_canfd.h b/board/safety/safety_hyundai_canfd.h index 05832a2848..ac7c9ab333 100644 --- a/board/safety/safety_hyundai_canfd.h +++ b/board/safety/safety_hyundai_canfd.h @@ -152,6 +152,31 @@ static uint32_t hyundai_canfd_get_checksum(const CANPacket_t *to_push) { return chksum; } +uint32_t hyundai_common_canfd_compute_checksum(const CANPacket_t *to_push) { + int len = GET_LEN(to_push); + uint32_t address = GET_ADDR(to_push); + + uint16_t crc = 0; + + for (int i = 2; i < len; i++) { + crc = (crc << 8U) ^ hyundai_canfd_crc_lut[(crc >> 8U) ^ GET_BYTE(to_push, i)]; + } + + // Add address to crc + crc = (crc << 8U) ^ hyundai_canfd_crc_lut[(crc >> 8U) ^ ((address >> 0U) & 0xFFU)]; + crc = (crc << 8U) ^ hyundai_canfd_crc_lut[(crc >> 8U) ^ ((address >> 8U) & 0xFFU)]; + + if (len == 24) { + crc ^= 0x819dU; + } else if (len == 32) { + crc ^= 0x9f5bU; + } else { + + } + + return crc; +} + static void hyundai_canfd_rx_hook(const CANPacket_t *to_push) { int bus = GET_BUS(to_push); int addr = GET_ADDR(to_push); diff --git a/board/safety/safety_hyundai_common.h b/board/safety/safety_hyundai_common.h index f81cff1be2..a2e9d01b97 100644 --- a/board/safety/safety_hyundai_common.h +++ b/board/safety/safety_hyundai_common.h @@ -86,29 +86,4 @@ void hyundai_common_cruise_buttons_check(const int cruise_button, const bool mai } } -uint32_t hyundai_common_canfd_compute_checksum(const CANPacket_t *to_push) { - int len = GET_LEN(to_push); - uint32_t address = GET_ADDR(to_push); - - uint16_t crc = 0; - - for (int i = 2; i < len; i++) { - crc = (crc << 8U) ^ hyundai_canfd_crc_lut[(crc >> 8U) ^ GET_BYTE(to_push, i)]; - } - - // Add address to crc - crc = (crc << 8U) ^ hyundai_canfd_crc_lut[(crc >> 8U) ^ ((address >> 0U) & 0xFFU)]; - crc = (crc << 8U) ^ hyundai_canfd_crc_lut[(crc >> 8U) ^ ((address >> 8U) & 0xFFU)]; - - if (len == 24) { - crc ^= 0x819dU; - } else if (len == 32) { - crc ^= 0x9f5bU; - } else { - - } - - return crc; -} - #endif From 2cb7be1c2dc7004cf5e0d5f8446eb9d03a2b6ba3 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Thu, 30 May 2024 21:57:50 +0100 Subject: [PATCH 07/13] memset() - suppress "unusedFunction" memset is needed by the linker --- board/libc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/board/libc.h b/board/libc.h index 7f669b95ab..8af22775f2 100644 --- a/board/libc.h +++ b/board/libc.h @@ -6,6 +6,7 @@ void delay(uint32_t a) { } // cppcheck-suppress misra-c2012-21.2 +// cppcheck-suppress unusedFunction ; gcc uses memset to initialize structures void *memset(void *str, int c, unsigned int n) { uint8_t *s = str; for (unsigned int i = 0; i < n; i++) { From 29acdd6647d662c5b7d81ceca95aef5d9d86c4a7 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Sun, 9 Jun 2024 23:05:35 +0100 Subject: [PATCH 08/13] ENABLE_SPI is only used in Dos config and nowhere in H7 --- board/SConscript | 2 +- board/main.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/board/SConscript b/board/SConscript index 93fd47b07e..2fad2e05f8 100644 --- a/board/SConscript +++ b/board/SConscript @@ -12,7 +12,7 @@ for project_name, project in build_projects.items(): flags = [ "-DPANDA", ] - if ("ENABLE_SPI" in os.environ or "h7" in project_name): + if ("ENABLE_SPI" in os.environ): flags.append('-DENABLE_SPI') if "H723" in os.environ: diff --git a/board/main.c b/board/main.c index b481c28b46..d4b5f20b46 100644 --- a/board/main.c +++ b/board/main.c @@ -353,11 +353,9 @@ int main(void) { // enable USB (right before interrupts or enum can fail!) usb_init(); -#ifdef ENABLE_SPI if (current_board->has_spi) { spi_init(); } -#endif current_board->set_led(LED_RED, false); current_board->set_led(LED_GREEN, false); From feeee1115e93b2fdf61b36da2cdaf4c173d6f943 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Mon, 10 Jun 2024 14:29:12 +0100 Subject: [PATCH 09/13] suppress interrupt_handlers also in mutation test --- tests/misra/.gitignore | 2 -- tests/misra/suppressions.txt | 2 +- tests/misra/test_mutation.py | 4 ++++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/misra/.gitignore b/tests/misra/.gitignore index fc9ac228cb..4e6a1f2909 100644 --- a/tests/misra/.gitignore +++ b/tests/misra/.gitignore @@ -1,5 +1,3 @@ *.pdf -*.txt .output.log -new_table cppcheck/ diff --git a/tests/misra/suppressions.txt b/tests/misra/suppressions.txt index 5c0b953b51..4b79e109f5 100644 --- a/tests/misra/suppressions.txt +++ b/tests/misra/suppressions.txt @@ -13,7 +13,7 @@ misra-c2012-20.10 unmatchedSuppression # All interrupt handlers are defined, including ones we don't use -unusedFunction:*/interrupt_handlers*.h +unusedFunction:*/interrupt_handlers.h # all of the below suppressions are from new checks introduced after updating # cppcheck from 2.5 -> 2.13. they are listed here to separate the update from diff --git a/tests/misra/test_mutation.py b/tests/misra/test_mutation.py index c804135b81..e8f336badf 100755 --- a/tests/misra/test_mutation.py +++ b/tests/misra/test_mutation.py @@ -17,6 +17,10 @@ 'board/stm32f4/inc', 'board/fake_stm.h', + # suppresed + 'board/stm32f4/interrupt_handlers.h', + 'board/stm32h7/interrupt_handlers.h', + # bootstub only files 'board/flasher.h', 'board/bootstub.c', From ca3d384f0bd90ae73ea16500165df3cc0f63d560 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Thu, 13 Jun 2024 02:36:50 +0100 Subject: [PATCH 10/13] use built in tmp_path pytest fixture for managing temp paths --- tests/misra/test_mutation.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/tests/misra/test_mutation.py b/tests/misra/test_mutation.py index e8f336badf..da6aa85bde 100755 --- a/tests/misra/test_mutation.py +++ b/tests/misra/test_mutation.py @@ -4,7 +4,6 @@ import pytest import shutil import subprocess -import tempfile import random HERE = os.path.abspath(os.path.dirname(__file__)) @@ -73,16 +72,15 @@ mutations.append((random.choice(files), p, True)) @pytest.mark.parametrize("fn, patch, should_fail", mutations) -def test_misra_mutation(fn, patch, should_fail): - with tempfile.TemporaryDirectory() as tmp: - shutil.copytree(ROOT, tmp, dirs_exist_ok=True) +def test_misra_mutation(fn, patch, should_fail, tmp_path): + shutil.copytree(ROOT, tmp_path, dirs_exist_ok=True) - # apply patch - if fn is not None: - r = os.system(f"cd {tmp} && sed -i '{patch}' {fn}") - assert r == 0 + # apply patch + if fn is not None: + r = os.system(f"cd {tmp_path} && sed -i '{patch}' {fn}") + assert r == 0 - # run test - r = subprocess.run("SKIP_TABLES_DIFF=1 tests/misra/test_misra.sh", cwd=tmp, shell=True) - failed = r.returncode != 0 - assert failed == should_fail + # run test + r = subprocess.run("SKIP_TABLES_DIFF=1 tests/misra/test_misra.sh", cwd=tmp_path, shell=True) + failed = r.returncode != 0 + assert failed == should_fail From 624e2b11afb586338351e2f7d2412df3ed88cb85 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Sun, 15 Sep 2024 19:32:30 -0700 Subject: [PATCH 11/13] Squashed commit of the following: commit 8545c68e4d51eab55803c9c28cdf8bb7bfaa261e Author: Radek Date: Fri Sep 13 15:12:35 2024 -0700 Fix USB errors (#2011) Fix LIBUSB_ERROR_PIPE [-9] when resetting over USB hubs or jungle V2 commit b8a2a8678fc201d7c02453a4fb819389d0fbf53b Author: Maxime Desroches Date: Tue Sep 10 21:49:03 2024 -0700 fix python setup (#2018) * fix * comment commit fcccbb3a131cc8f60025fc7da9b9fdb7a4e3acf7 Author: dzid26 Date: Sat Sep 7 19:57:19 2024 -0700 revert shorter MISRA mutation CI timeout - test_misra.sh only got faster locally commit 2aaab401177bd16828d3d8f64d0777a7d8c3addc Author: Radek Date: Fri Sep 6 13:30:05 2024 -0700 fix test_mutation.py performace (#2012) stop pytest from executing test_misra.sh in test collections - in each test_mutation.py worker commit 6f0d1efbd9d9d4624dbbe1f839b0607e3fb7b091 Author: dzid26 Date: Thu Sep 5 21:49:30 2024 -0700 stricter misra config check - prevent quiet bail out commit 93776fd5bf5beb6e5a4cecfec8367c957143372c Author: Greg Hogan Date: Tue Sep 3 20:42:12 2024 -0700 CCP: fix upload response size and getting seed (#2009) commit aac60b8a7938d4d32c0c02608058022e4d876156 Author: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Sun Sep 1 09:51:30 2024 -0700 pre-commit: autoupdate hooks (#2010) Update pre-commit hook versions Co-authored-by: adeebshihadeh commit 9ec02e74f53a0a76d54e33142c045492a3acfc04 Author: Adeeb Shihadeh Date: Sat Aug 31 13:17:55 2024 -0700 socketcan: skip install in CI for now commit 160ea08e8f791954e7323c21ca3880600e357506 Author: Adeeb Shihadeh Date: Sat Aug 31 13:09:58 2024 -0700 misra: bump to cppcheck 2.15.0 (#2008) * misra: bump to latest cppcheck * update checkers commit a36ca220fa0d5e12b7d65a6c31c97a8982b6f25a Author: MarinkoMagla <159032106+MarinkoMagla@users.noreply.github.com> Date: Sat Aug 31 22:01:28 2024 +0200 Defining types in return dictionaries (#1923) * Defining types in return dictionaries * Correcting indent * Returning the class instead of dict * Fixing failing linter * Fixing whitespace error commit bd6cec3b2972fda7435c6030a88f0f97cab4c4b9 Author: Robbe Derks Date: Fri Aug 30 15:35:50 2024 +0200 cuatro LED (#2005) * Revert "cuatro: disable LED for now" This reverts commit 866bd9c3bc44a362a64f0104b5e555a064335009. * re-enable and make sure to use open-drain * use gpio function --------- Co-authored-by: Comma Device commit 8587ae3fc00d561c5d5d0c9def0a4de69cff7224 Author: Shane Smiskol Date: Mon Aug 26 17:56:46 2024 -0700 drivers: log can core reset when switching multiplexing (#1972) fdcan: log lost tx messages when resetting can core for multiplexing commit 0a0912234e4d3c67682109eb54c1d673770fc783 Author: Andrei Radulescu Date: Tue Aug 27 03:25:15 2024 +0300 update bash scripts to #!/usr/bin/env bash (#1987) * update bash shebang for better compatibility including macOS * can't have anything after #bash commit 2b94e4fef710a22313b99d8c5b723d8db5e9c8bd Author: dzid26 Date: Tue Aug 27 00:15:29 2024 +0000 Enable CAN3 printer (#1991) * panda has 3 can peripherals * enable printing CAN3 commit 866bd9c3bc44a362a64f0104b5e555a064335009 Author: Adeeb Shihadeh Date: Fri Aug 23 20:41:53 2024 -0700 cuatro: disable LED for now commit 30d0434380d314f72fe84a767622dde585d44eb3 Author: Comma Device Date: Fri Aug 23 04:57:34 2024 +0000 cuatro: disable SOM reset commit e53c8025a0204d4ff3a6937c642b1497256c86e1 Author: Adeeb Shihadeh Date: Thu Aug 22 21:55:02 2024 -0700 tres: fix SOM reset line blinking (#2003) Co-authored-by: Comma Device commit 080e53f04d45d5ca9348591e676c80a7149510f5 Author: Robbe Derks Date: Sun Aug 18 17:43:27 2024 -0700 Cuatro fan (#1999) * cuatro fan debugging * fix * faster fan, faster interrupts * fix comment --------- Co-authored-by: Comma Device commit cfa8b796f7fff01963b02fe51c6f7a0022cb8897 Author: Adeeb Shihadeh Date: Sun Aug 18 12:01:17 2024 -0700 cleanup dependencies (#2001) * cleanup dependencies * in the real spot * fix jenkins commit c4e75ee89cdd18e181fd78f8b8e1ed5af3fe8fc0 Author: Adeeb Shihadeh Date: Sun Aug 18 11:40:54 2024 -0700 remove cereal dependence (#2000) * remove cereal * rm more shit * add back make * python3 * python3 * fix that * put that back * rename * fix that * can't move it commit e7a04b54b039307c33f542efd21ce936c45756be Author: Shane Smiskol Date: Fri Aug 16 23:01:54 2024 -0700 make uds and isotp general imports (#1998) commit 0234e756e3fe1fdf222260ae6b782b8ce66377ef Author: Robbe Derks Date: Thu Aug 15 21:33:07 2024 -0700 STM32H7: add missing interrupt handlers (#1997) add missing interrupts Co-authored-by: Comma Device commit 87572e0b7592051c11536b57333d08e228712d93 Author: geeth345 <92386308+geeth345@users.noreply.github.com> Date: Tue Aug 13 18:34:46 2024 +0100 Update README.md to fix dead link (#1996) Changed C++ library link to reflect boardd -> pandad change commit 1cbcc13c35429b06e9d36c55b9ab46df73a8b51a Author: Shane Smiskol Date: Mon Aug 5 14:51:56 2024 -0700 use and configure custom logger (#1994) * prepare to log logs * utils * discoverability * forgot commit 3c1def1cc57f3fb37399a25d0e8088c70985c5ec Author: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Fri Aug 2 15:51:37 2024 -0700 pre-commit: autoupdate hooks (#1979) Update pre-commit hook versions Co-authored-by: adeebshihadeh commit 5d815231ea3858c958ecdd96ac3080169b407452 Author: Adeeb Shihadeh Date: Fri Aug 2 13:52:28 2024 -0700 1min is all you need commit b70ba5ecde9c734ba3880804c0488ef4b120d11b Author: Robbe Derks Date: Fri Aug 2 20:26:16 2024 +0200 Detect H723 in firmware (#1988) * determine H723 based on package type * wrong way round * misra... * enable SYSCFG clock before reading * whitelist certain package types commit ee7b385be7cef3bc1de4f9dd17017dddefb4cbb5 Author: Adeeb Shihadeh Date: Fri Aug 2 11:02:38 2024 -0700 CI: add jenkins-trigger commit daa739efb76e2908bf1b2ee064be9034a8e299c3 Author: Shane Smiskol Date: Wed Jul 31 14:30:53 2024 -0700 missed a busTime (#1990) * whoops * addr dat src commit 8c3bb0151e8907ade344ccb293d58cd543e28baa Author: Shane Smiskol Date: Tue Jul 30 21:20:48 2024 -0700 deprecate busTime (#1989) * deprecate busTime * fix test_comms.py * update opendbc * way more than i thought * and here * oops commit f6375848ca393a9483921665b6a2d131d7ec9b20 Author: Hoang Bui <47828508+bongbui321@users.noreply.github.com> Date: Wed Jul 17 23:49:10 2024 -0400 add `set_gas_pressed_prev()` helper (#1986) add set_gas_pressed_prev helper commit 5ee262f3cbcc0bc780e015c3d9d101ef290cda3a Author: Adeeb Shihadeh Date: Wed Jul 17 11:19:24 2024 -0700 H7 CR3 notes (#1985) commit b4e3d5cdd2dec2a58807b0d710a5d3561a59529d Author: Adeeb Shihadeh Date: Sun Jul 14 15:56:18 2024 -0700 Revert "H7: detect board type with second ID pin group (#1975)" This reverts commit 376408bb4f6706b682eb6d607bedd14958665084. commit 481d2bec595b64bb44ad70455b69fd3dd148ed4b Author: pantew869 <173707415+pantew869@users.noreply.github.com> Date: Sat Jul 13 23:34:25 2024 +0300 Use numpy instead of numpy-stubs in pre-commit (#1984) * delete numpy-stubs from additional_dependencies(it's deprecated and causes git issues) * use numpy directly commit 376408bb4f6706b682eb6d607bedd14958665084 Author: Adeeb Shihadeh Date: Wed Jun 26 18:20:51 2024 -0700 H7: detect board type with second ID pin group (#1975) * H7: detect board type based on package * detect smps * misra fix * jungle? * pkg isn't reliable, need syscfg enabled --------- Co-authored-by: Comma Device commit 29f2f30a323f89d84d16f93c1c42fcbb84543ce1 Author: Adeeb Shihadeh Date: Wed Jun 26 17:08:35 2024 -0700 jenkins: run jungles first (#1977) * jenkins: run jungles first * inside stage commit ee1d5ce8bce6d1031426ea06255b8826395432e5 Author: Adeeb Shihadeh Date: Wed Jun 26 16:59:08 2024 -0700 add assert_fatal function (#1976) * add assert function * fix * flip * rename * assert fatal commit cac94e3aa2d40f5931cf3dcd7c0b61b82f9815be Author: JJ Date: Tue Jun 25 06:53:31 2024 -0700 Update README.md (#1974) small spelling fix commit 7287ff0cbf3ab405a670405f2faca419d524387d Author: Shane Smiskol Date: Wed Jun 12 19:21:38 2024 -0700 query_fw_versions: ignore 29 bit addresses option (#1973) fix --- .github/workflows/drivers.yaml | 6 +- .github/workflows/jenkins-pr-trigger.yaml | 45 ++ .github/workflows/test.yaml | 8 +- .gitignore | 1 + .pre-commit-config.yaml | 6 +- Dockerfile | 54 +- Jenkinsfile | 77 +-- README.md | 6 +- __init__.py | 3 +- board/SConscript | 3 - board/boards/black.h | 1 + board/boards/board_declarations.h | 1 + board/boards/cuatro.h | 28 +- board/boards/dos.h | 1 + board/boards/grey.h | 1 + board/boards/red.h | 1 + board/boards/tres.h | 4 +- board/boards/uno.h | 1 + board/boards/white.h | 1 + board/debug/debug_h7.sh | 3 +- board/drivers/bxcan.h | 8 +- board/drivers/fan.h | 2 +- board/drivers/fdcan.h | 10 +- board/gdb.sh | 3 + board/jungle/main.c | 5 +- board/jungle/scripts/can_printer.py | 2 +- board/jungle/scripts/echo_loopback_test.py | 2 +- board/jungle/scripts/loopback_test.py | 4 +- board/libc.h | 10 + board/main.c | 15 +- board/stm32h7/board.h | 37 +- board/stm32h7/clock.h | 54 +- board/stm32h7/interrupt_handlers.h | 83 ++- board/stm32h7/llfan.h | 4 +- drivers/spi/load.sh | 2 +- drivers/spi/pull-src.sh | 2 +- examples/can_logger.py | 2 +- examples/query_fw_versions.py | 4 +- examples/tesla_tester.py | 2 +- pyproject.toml | 2 +- python/__init__.py | 62 ++- python/ccp.py | 75 +-- python/isotp.py | 6 +- python/spi.py | 26 +- python/uds.py | 4 +- python/utils.py | 11 + python/xcp.py | 2 +- release/make_release.sh | 2 +- requirements.txt | 18 - setup.py | 25 +- tests/black_white_loopback_test.py | 6 +- tests/black_white_relay_endurance.py | 6 +- tests/black_white_relay_test.py | 4 +- tests/bulk_write_test.py | 2 +- tests/can_printer.py | 7 +- tests/canfd/test_canfd.py | 4 +- tests/ci_shell.sh | 3 +- tests/echo.py | 2 +- tests/elm_car_simulator.py | 6 +- tests/hitl/3_usb_to_can.py | 12 +- tests/hitl/4_can_loopback.py | 18 +- tests/hitl/6_safety.py | 4 +- tests/hitl/9_harness.py | 2 +- tests/hitl/helpers.py | 12 +- tests/hitl/run_parallel_tests.sh | 2 +- tests/hitl/run_serial_tests.sh | 2 +- tests/libpanda/safety_helpers.h | 4 + tests/libpanda/safety_helpers.py | 2 + tests/loopback_test.py | 12 +- tests/message_drop_test.py | 4 +- tests/misra/checkers.txt | 561 +++++++++++++++++++-- tests/misra/install.sh | 4 +- tests/misra/test_misra.sh | 8 +- tests/read_st_flash.sh | 2 +- tests/safety/common.py | 2 +- tests/safety/test_ford.py | 4 +- tests/safety/test_hyundai.py | 4 +- tests/setup_device_ci.sh | 4 +- tests/som_debug.sh | 2 +- tests/usbprotocol/test.sh | 2 +- tests/usbprotocol/test_comms.py | 16 +- tests/usbprotocol/test_pandalib.py | 2 +- 82 files changed, 1071 insertions(+), 389 deletions(-) create mode 100644 .github/workflows/jenkins-pr-trigger.yaml create mode 100755 board/gdb.sh create mode 100644 python/utils.py delete mode 100644 requirements.txt diff --git a/.github/workflows/drivers.yaml b/.github/workflows/drivers.yaml index 78efcdeab2..1af13d9196 100644 --- a/.github/workflows/drivers.yaml +++ b/.github/workflows/drivers.yaml @@ -5,7 +5,7 @@ jobs: build_socketcan: name: socketcan build runs-on: ubuntu-latest - timeout-minutes: 5 + timeout-minutes: 1 steps: - uses: actions/checkout@v2 - name: Install dependencies @@ -16,7 +16,9 @@ jobs: cd drivers/linux make link make build - make install + + # FIXME: install doesn't work sometimes in GH Actions + #make install - name: Print make log if: always() continue-on-error: true diff --git a/.github/workflows/jenkins-pr-trigger.yaml b/.github/workflows/jenkins-pr-trigger.yaml new file mode 100644 index 0000000000..db1d524018 --- /dev/null +++ b/.github/workflows/jenkins-pr-trigger.yaml @@ -0,0 +1,45 @@ +name: jenkins scan + +on: + issue_comment: + types: [created, edited] + +jobs: + # TODO: gc old branches in a separate job in this workflow + scan-comments: + runs-on: ubuntu-latest + if: ${{ github.event.issue.pull_request }} + steps: + - name: Check for trigger phrase + id: check_comment + uses: actions/github-script@v7 + with: + script: | + const triggerPhrase = "trigger-jenkins"; + const comment = context.payload.comment.body; + const commenter = context.payload.comment.user.login; + + const { data: permissions } = await github.rest.repos.getCollaboratorPermissionLevel({ + owner: context.repo.owner, + repo: context.repo.repo, + username: commenter + }); + + const hasWriteAccess = permissions.permission === 'write' || permissions.permission === 'admin'; + + return (hasWriteAccess && comment.includes(triggerPhrase)); + result-encoding: json + + - name: Checkout repository + if: steps.check_comment.outputs.result == 'true' + uses: actions/checkout@v4 + with: + ref: refs/pull/${{ github.event.issue.number }}/head + + - name: Push to tmp-jenkins branch + if: steps.check_comment.outputs.result == 'true' + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b tmp-jenkins-${{ github.event.issue.number }} + GIT_LFS_SKIP_PUSH=1 git push -f origin tmp-jenkins-${{ github.event.issue.number }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index fe0b0c1b29..d1d9f7605a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -11,7 +11,7 @@ concurrency: cancel-in-progress: true env: - RUN: docker run -v ${{ github.workspace }}:/tmp/openpilot/panda -w /tmp/openpilot/panda --rm panda /bin/bash -c + RUN: docker run -v ${{ github.workspace }}:/tmp/pythonpath/panda -w /tmp/pythonpath/panda --rm panda /bin/bash -c BUILD: | export DOCKER_BUILDKIT=1 docker build --pull --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from ghcr.io/commaai/panda:latest -t panda -f Dockerfile . @@ -45,7 +45,7 @@ jobs: - name: Build Docker image run: eval "$BUILD" - name: Test python package installer - run: ${{ env.RUN }} "python setup.py install" + run: ${{ env.RUN }} "python3 setup.py install" - name: Build panda images and bootstub run: ${{ env.RUN }} "scons -j4" - name: Build panda with SPI support @@ -103,8 +103,8 @@ jobs: timeout-minutes: 7 run: ${{ env.RUN }} "cd tests/misra && pytest -n8 test_mutation.py" - python_linter: - name: python linter + static_analysis: + name: static analysis runs-on: ubuntu-latest timeout-minutes: 20 steps: diff --git a/.gitignore b/.gitignore index 2dfa094768..640f25f8e0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ a.out *~ .#* dist/ +build/ pandacan.egg-info/ obj/ examples/output.csv diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9556231800..c2759df9c3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,12 +9,12 @@ repos: - id: check-executables-have-shebangs - id: check-shebang-scripts-are-executable - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.10.0 + rev: v1.11.2 hooks: - id: mypy - additional_dependencies: ['git+https://github.com/numpy/numpy-stubs', 'types-requests', 'types-atomicwrites', + additional_dependencies: ['numpy', 'types-requests', 'types-atomicwrites', 'types-pycurl'] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.7 + rev: v0.6.3 hooks: - id: ruff diff --git a/Dockerfile b/Dockerfile index 74afcb6b5e..5d3c1ffc1d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,67 +1,45 @@ FROM ubuntu:24.04 -ENV PYTHONUNBUFFERED 1 -ENV PYTHONPATH /tmp/openpilot:$PYTHONPATH +ENV PYTHONUNBUFFERED=1 +ENV PYTHONPATH=/tmp/pythonpath ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ make \ - bzip2 \ - ca-certificates \ - capnproto \ - clang \ g++ \ gcc-arm-none-eabi libnewlib-arm-none-eabi \ git \ - libarchive-dev \ - libbz2-dev \ - libcapnp-dev \ libffi-dev \ - libtool \ libusb-1.0-0 \ - libzmq3-dev \ - locales \ - opencl-headers \ - ocl-icd-opencl-dev \ python3 \ python3-dev \ python3-pip \ - python-is-python3 \ - zlib1g-dev \ && rm -rf /var/lib/apt/lists/* && \ apt clean && \ cd /usr/lib/gcc/arm-none-eabi/* && \ rm -rf arm/ && \ rm -rf thumb/nofp thumb/v6* thumb/v8* thumb/v7+fp thumb/v7-r+fp.sp -RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen -ENV LANG en_US.UTF-8 -ENV LANGUAGE en_US:en -ENV LC_ALL en_US.UTF-8 - -COPY requirements.txt /tmp/ -RUN pip3 install --break-system-packages --no-cache-dir -r /tmp/requirements.txt - ENV CPPCHECK_DIR=/tmp/cppcheck COPY tests/misra/install.sh /tmp/ RUN /tmp/install.sh && rm -rf $CPPCHECK_DIR/.git/ ENV SKIP_CPPCHECK_INSTALL=1 -ENV CEREAL_REF="861144c136c91f70dcbc652c2ffe99f57440ad47" -ENV OPENDBC_REF="e0d4be4a6215d44809718dc84efe1b9f0299ad63" +COPY setup.py __init__.py $PYTHONPATH/panda/ +COPY python/__init__.py $PYTHONPATH/panda/python/ +RUN pip3 install --break-system-packages --no-cache-dir $PYTHONPATH/panda/[dev] -RUN git config --global --add safe.directory /tmp/openpilot/panda -RUN mkdir -p /tmp/openpilot/ && \ - cd /tmp/openpilot/ && \ - git clone --depth 1 https://github.com/commaai/cereal && \ - git clone --depth 1 https://github.com/commaai/opendbc && \ - cd cereal && git fetch origin $CEREAL_REF && git checkout FETCH_HEAD && rm -rf .git/ && cd .. && \ - cd opendbc && git fetch origin $OPENDBC_REF && git checkout FETCH_HEAD && rm -rf .git/ && cd .. && \ - cp -pR opendbc/SConstruct opendbc/site_scons/ . && \ - pip3 install --break-system-packages --no-cache-dir -r opendbc/requirements.txt && \ - scons -j8 --minimal opendbc/ cereal/ +# TODO: this should be a "pip install" or not even in this repo at all +RUN git config --global --add safe.directory $PYTHONPATH/panda +ENV OPENDBC_REF="5ed7a834a4e0e24c3968dd1e98ceb4b9d5f9791a" +RUN cd /tmp/ && \ + git clone --depth 1 https://github.com/commaai/opendbc opendbc_repo && \ + cd opendbc_repo && git fetch origin $OPENDBC_REF && git checkout FETCH_HEAD && rm -rf .git/ && \ + pip3 install --break-system-packages --no-cache-dir Cython numpy && \ + scons -j8 --minimal opendbc/ && \ + ln -s $PWD/opendbc $PYTHONPATH/opendbc # for Jenkins COPY README.md panda.tar.* /tmp/ -RUN mkdir /tmp/openpilot/panda && \ - tar -xvf /tmp/panda.tar.gz -C /tmp/openpilot/panda/ || true +RUN mkdir -p /tmp/pythonpath/panda && \ + tar -xvf /tmp/panda.tar.gz -C /tmp/pythonpath/panda/ || true diff --git a/Jenkinsfile b/Jenkinsfile index 2d4c615dfe..2ccf6be116 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -4,7 +4,7 @@ def docker_run(String step_label, int timeout_mins, String cmd) { --env PYTHONWARNINGS=error \ --volume /dev/bus/usb:/dev/bus/usb \ --volume /var/run/dbus:/var/run/dbus \ - --workdir /tmp/openpilot/panda \ + --workdir /tmp/pythonpath/panda \ --net host \ ${env.DOCKER_IMAGE_TAG} \ bash -c 'scons -j8 && ${cmd}'", \ @@ -73,56 +73,57 @@ pipeline { } stages { - stage('panda tests') { - parallel { - stage('test dos') { - agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } } + stage ('Acquire resource locks') { + options { + lock(resource: "pandas") + } + stages { + stage('Build Docker Image') { steps { - phone_steps("panda-dos", [ - ["build", "scons -j4"], - ["flash", "cd tests/ && ./reflash_internal_panda.py"], - ["flash jungle", "cd board/jungle && ./flash.py"], - ["test", "cd tests/hitl && HW_TYPES=6 pytest -n0 --durations=0 [2-9]*.py -k 'not test_send_recv'"], - ]) + timeout(time: 20, unit: 'MINUTES') { + script { + sh 'git archive -v -o panda.tar.gz --format=tar.gz HEAD' + dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}") + } + } } } - - stage('test tres') { - agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } } + stage('jungle tests') { steps { - phone_steps("panda-tres", [ - ["build", "scons -j4"], - ["flash", "cd tests/ && ./reflash_internal_panda.py"], - ["flash jungle", "cd board/jungle && ./flash.py"], - ["test", "cd tests/hitl && HW_TYPES=9 pytest -n0 --durations=0 2*.py [5-9]*.py"], - ]) + script { + retry (3) { + docker_run("reset hardware", 3, "python3 ./tests/hitl/reset_jungles.py") + } + } } } - stage ('Acquire resource locks') { - options { - lock(resource: "pandas") - } - stages { - stage('Build Docker Image') { + stage('parallel tests') { + parallel { + stage('test tres') { + agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } } steps { - timeout(time: 20, unit: 'MINUTES') { - script { - sh 'git archive -v -o panda.tar.gz --format=tar.gz HEAD' - dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}") - } - } + phone_steps("panda-tres", [ + ["build", "scons -j4"], + ["flash", "cd tests/ && ./reflash_internal_panda.py"], + ["flash jungle", "cd board/jungle && ./flash.py"], + ["test", "cd tests/hitl && HW_TYPES=9 pytest -n0 --durations=0 2*.py [5-9]*.py"], + ]) } } - stage('jungle tests') { + + stage('test dos') { + agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } } steps { - script { - retry (3) { - docker_run("reset hardware", 3, "python ./tests/hitl/reset_jungles.py") - } - } + phone_steps("panda-dos", [ + ["build", "scons -j4"], + ["flash", "cd tests/ && ./reflash_internal_panda.py"], + ["flash jungle", "cd board/jungle && ./flash.py"], + ["test", "cd tests/hitl && HW_TYPES=6 pytest -n0 --durations=0 [2-9]*.py -k 'not test_send_recv'"], + ]) } } + stage('bootkick tests') { steps { script { diff --git a/README.md b/README.md index b2830b21ef..618a5b70d6 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Safety modes optionally support `controls_allowed`, which allows or blocks a sub ## Code Rigor -The panda firmware is written for its use in conjuction with [openpilot](https://github.com/commaai/openpilot). The panda firmware, through its safety model, provides and enforces the +The panda firmware is written for its use in conjunction with [openpilot](https://github.com/commaai/openpilot). The panda firmware, through its safety model, provides and enforces the [openpilot safety](https://github.com/commaai/openpilot/blob/master/docs/SAFETY.md). Due to its critical function, it's important that the application code rigor within the `board` folder is held to high standards. These are the [CI regression tests](https://github.com/commaai/panda/actions) we have in place: @@ -62,7 +62,7 @@ git clone https://github.com/commaai/panda.git cd panda # install dependencies -pip install -r requirements.txt +pip install -e .[dev] # install panda python setup.py install @@ -97,7 +97,7 @@ The panda jungle uses different udev rules. See [the repo](https://github.com/co As a universal car interface, it should support every reasonable software interface. - [Python library](https://github.com/commaai/panda/tree/master/python) -- [C++ library](https://github.com/commaai/openpilot/tree/master/selfdrive/boardd) +- [C++ library](https://github.com/commaai/openpilot/tree/master/selfdrive/pandad) - [socketcan in kernel](https://github.com/commaai/panda/tree/master/drivers/linux) (alpha) ## Licensing diff --git a/__init__.py b/__init__.py index bf487fddcc..665682521f 100644 --- a/__init__.py +++ b/__init__.py @@ -2,7 +2,8 @@ from .python.spi import PandaSpiException, PandaProtocolMismatch, STBootloaderSPIHandle # noqa: F401 from .python.serial import PandaSerial # noqa: F401 from .python.canhandle import CanHandle # noqa: F401 -from .python import (Panda, PandaDFU, # noqa: F401 +from .python.utils import logger # noqa: F401 +from .python import (Panda, PandaDFU, uds, isotp, # noqa: F401 pack_can_buffer, unpack_can_buffer, calculate_checksum, DLC_TO_LEN, LEN_TO_DLC, ALTERNATIVE_EXPERIENCE, CANPACKET_HEAD_SIZE) diff --git a/board/SConscript b/board/SConscript index 2fad2e05f8..715a141ade 100644 --- a/board/SConscript +++ b/board/SConscript @@ -15,7 +15,4 @@ for project_name, project in build_projects.items(): if ("ENABLE_SPI" in os.environ): flags.append('-DENABLE_SPI') - if "H723" in os.environ: - flags.append('-DSTM32H723') - build_project(project_name, project, flags) diff --git a/board/boards/black.h b/board/boards/black.h index c860d1401d..ae6e0160df 100644 --- a/board/boards/black.h +++ b/board/boards/black.h @@ -162,6 +162,7 @@ board board_black = { .has_spi = false, .has_canfd = false, .fan_max_rpm = 0U, + .fan_max_pwm = 100U, .avdd_mV = 3300U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 0U, diff --git a/board/boards/board_declarations.h b/board/boards/board_declarations.h index a9ff9297ba..22f55883f4 100644 --- a/board/boards/board_declarations.h +++ b/board/boards/board_declarations.h @@ -29,6 +29,7 @@ struct board { const uint16_t avdd_mV; const bool fan_stall_recovery; const uint8_t fan_enable_cooldown_time; + const uint8_t fan_max_pwm; board_init init; board_init_bootloader init_bootloader; board_enable_can_transceiver enable_can_transceiver; diff --git a/board/boards/cuatro.h b/board/boards/cuatro.h index 43a5dfc505..49c207ebed 100644 --- a/board/boards/cuatro.h +++ b/board/boards/cuatro.h @@ -7,7 +7,7 @@ void cuatro_set_led(uint8_t color, bool enabled) { case LED_RED: set_gpio_output(GPIOD, 15, !enabled); break; - case LED_GREEN: + case LED_GREEN: set_gpio_output(GPIOD, 14, !enabled); break; case LED_BLUE: @@ -57,9 +57,24 @@ uint32_t cuatro_read_current_mA(void) { return adc_get_mV(3) * 2U; } +void cuatro_set_fan_enabled(bool enabled) { + set_gpio_output(GPIOD, 3, !enabled); +} + +void cuatro_set_bootkick(BootState state) { + set_gpio_output(GPIOA, 0, state != BOOT_BOOTKICK); + // only use if we have to + //set_gpio_output(GPIOC, 12, state != BOOT_RESET); +} + void cuatro_init(void) { red_chiplet_init(); + // init LEDs as open drain + set_gpio_output_type(GPIOE, 2, OUTPUT_TYPE_OPEN_DRAIN); + set_gpio_output_type(GPIOD, 14, OUTPUT_TYPE_OPEN_DRAIN); + set_gpio_output_type(GPIOD, 15, OUTPUT_TYPE_OPEN_DRAIN); + // Power readout set_gpio_mode(GPIOC, 5, MODE_ANALOG); set_gpio_mode(GPIOA, 6, MODE_ANALOG); @@ -81,8 +96,7 @@ void cuatro_init(void) { set_gpio_pullup(GPIOC, 2, PULL_DOWN); // SOM bootkick + reset lines - set_gpio_mode(GPIOC, 12, MODE_OUTPUT); - tres_set_bootkick(BOOT_BOOTKICK); + cuatro_set_bootkick(BOOT_BOOTKICK); // SOM debugging UART gpio_uart7_init(); @@ -93,6 +107,7 @@ void cuatro_init(void) { // fan setup set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3); + register_set_bits(&(GPIOC->OTYPER), GPIO_OTYPER_OT8); // open drain // Initialize IR PWM and set to 0% set_gpio_alternate(GPIOC, 9, GPIO_AF2_TIM3); @@ -108,7 +123,8 @@ board board_cuatro = { .has_obd = true, .has_spi = true, .has_canfd = true, - .fan_max_rpm = 6600U, + .fan_max_rpm = 12500U, + .fan_max_pwm = 99U, // it can go up to 14k RPM, but 99% -> 100% is very non-linear .avdd_mV = 1800U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 3U, @@ -121,9 +137,9 @@ board board_cuatro = { .check_ignition = red_check_ignition, .read_voltage_mV = cuatro_read_voltage_mV, .read_current_mA = cuatro_read_current_mA, - .set_fan_enabled = tres_set_fan_enabled, + .set_fan_enabled = cuatro_set_fan_enabled, .set_ir_power = tres_set_ir_power, .set_siren = unused_set_siren, - .set_bootkick = tres_set_bootkick, + .set_bootkick = cuatro_set_bootkick, .read_som_gpio = tres_read_som_gpio }; diff --git a/board/boards/dos.h b/board/boards/dos.h index 0164f2b262..62e83c6882 100644 --- a/board/boards/dos.h +++ b/board/boards/dos.h @@ -190,6 +190,7 @@ board board_dos = { #endif .has_canfd = false, .fan_max_rpm = 6500U, + .fan_max_pwm = 100U, .avdd_mV = 3300U, .fan_stall_recovery = true, .fan_enable_cooldown_time = 3U, diff --git a/board/boards/grey.h b/board/boards/grey.h index 516d0fa70f..cbbd8e9c89 100644 --- a/board/boards/grey.h +++ b/board/boards/grey.h @@ -11,6 +11,7 @@ board board_grey = { .has_spi = false, .has_canfd = false, .fan_max_rpm = 0U, + .fan_max_pwm = 100U, .avdd_mV = 3300U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 0U, diff --git a/board/boards/red.h b/board/boards/red.h index 746c54b622..3a12fdb705 100644 --- a/board/boards/red.h +++ b/board/boards/red.h @@ -174,6 +174,7 @@ board board_red = { .has_spi = false, .has_canfd = true, .fan_max_rpm = 0U, + .fan_max_pwm = 100U, .avdd_mV = 3300U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 0U, diff --git a/board/boards/tres.h b/board/boards/tres.h index 91b94f68e2..d3b5f0caa9 100644 --- a/board/boards/tres.h +++ b/board/boards/tres.h @@ -42,8 +42,9 @@ void tres_init(void) { set_gpio_pullup(GPIOC, 2, PULL_DOWN); // SOM bootkick + reset lines - set_gpio_mode(GPIOC, 12, MODE_OUTPUT); + // WARNING: make sure output state is set before configuring as output tres_set_bootkick(BOOT_BOOTKICK); + set_gpio_mode(GPIOC, 12, MODE_OUTPUT); // SOM debugging UART gpio_uart7_init(); @@ -76,6 +77,7 @@ board board_tres = { .has_spi = true, .has_canfd = true, .fan_max_rpm = 6600U, + .fan_max_pwm = 100U, .avdd_mV = 1800U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 3U, diff --git a/board/boards/uno.h b/board/boards/uno.h index a2e1e98354..8e86c98fac 100644 --- a/board/boards/uno.h +++ b/board/boards/uno.h @@ -197,6 +197,7 @@ board board_uno = { .has_spi = false, .has_canfd = false, .fan_max_rpm = 5100U, + .fan_max_pwm = 100U, .avdd_mV = 3300U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 0U, diff --git a/board/boards/white.h b/board/boards/white.h index 8d22afbc9b..08f62e5226 100644 --- a/board/boards/white.h +++ b/board/boards/white.h @@ -191,6 +191,7 @@ board board_white = { .has_spi = false, .has_canfd = false, .fan_max_rpm = 0U, + .fan_max_pwm = 100U, .avdd_mV = 3300U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 0U, diff --git a/board/debug/debug_h7.sh b/board/debug/debug_h7.sh index a2bd88434e..126a9c378c 100755 --- a/board/debug/debug_h7.sh +++ b/board/debug/debug_h7.sh @@ -1,3 +1,4 @@ -#!/bin/bash -e +#!/usr/bin/env bash +set -e sudo openocd -f "interface/stlink.cfg" -c "transport select hla_swd" -f "target/stm32h7x.cfg" -c "init" diff --git a/board/drivers/bxcan.h b/board/drivers/bxcan.h index 27ffcee525..89fdd96057 100644 --- a/board/drivers/bxcan.h +++ b/board/drivers/bxcan.h @@ -23,6 +23,11 @@ bool can_set_speed(uint8_t can_number) { return ret; } +void can_clear_send(CAN_TypeDef *CANx, uint8_t can_number) { + can_health[can_number].can_core_reset_cnt += 1U; + llcan_clear_send(CANx); +} + void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) { CAN_TypeDef *CANx = CANIF_FROM_CAN_NUM(can_number); uint32_t esr_reg = CANx->ESR; @@ -52,8 +57,7 @@ void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) { can_health[can_number].total_rx_lost_cnt += 1U; CANx->RF0R &= ~(CAN_RF0R_FOVR0); } - can_health[can_number].can_core_reset_cnt += 1U; - llcan_clear_send(CANx); + can_clear_send(CANx, can_number); } } diff --git a/board/drivers/fan.h b/board/drivers/fan.h index 15296079ae..e0946aac34 100644 --- a/board/drivers/fan.h +++ b/board/drivers/fan.h @@ -86,7 +86,7 @@ void fan_tick(void) { float error = fan_state.target_rpm - fan_rpm_fast; fan_state.error_integral += FAN_I * error; } - fan_state.power = CLAMP(fan_state.error_integral, 0U, 100U); + fan_state.power = CLAMP(fan_state.error_integral, 0U, current_board->fan_max_pwm); // Set PWM and enable line pwm_set(TIM3, 3, fan_state.power); diff --git a/board/drivers/fdcan.h b/board/drivers/fdcan.h index 0ba228a9e6..00bc1a3489 100644 --- a/board/drivers/fdcan.h +++ b/board/drivers/fdcan.h @@ -35,6 +35,12 @@ bool can_set_speed(uint8_t can_number) { return ret; } +void can_clear_send(FDCAN_GlobalTypeDef *FDCANx, uint8_t can_number) { + can_health[can_number].can_core_reset_cnt += 1U; + can_health[can_number].total_tx_lost_cnt += (FDCAN_TX_FIFO_EL_CNT - (FDCANx->TXFQS & FDCAN_TXFQS_TFFL)); // TX FIFO msgs will be lost after reset + llcan_clear_send(FDCANx); +} + void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) { FDCAN_GlobalTypeDef *FDCANx = CANIF_FROM_CAN_NUM(can_number); uint32_t psr_reg = FDCANx->PSR; @@ -75,9 +81,7 @@ void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) { // 2. H7 gets stuck in bus off recovery state indefinitely if ((((can_health[can_number].last_error == CAN_ACK_ERROR) || (can_health[can_number].last_data_error == CAN_ACK_ERROR)) && (can_health[can_number].transmit_error_cnt > 127U)) || ((ir_reg & FDCAN_IR_BO) != 0U)) { - can_health[can_number].can_core_reset_cnt += 1U; - can_health[can_number].total_tx_lost_cnt += (FDCAN_TX_FIFO_EL_CNT - (FDCANx->TXFQS & FDCAN_TXFQS_TFFL)); // TX FIFO msgs will be lost after reset - llcan_clear_send(FDCANx); + can_clear_send(FDCANx, can_number); } } } diff --git a/board/gdb.sh b/board/gdb.sh new file mode 100755 index 0000000000..aa695d6ab7 --- /dev/null +++ b/board/gdb.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +gdb-multiarch --eval-command="target extended-remote localhost:3333" diff --git a/board/jungle/main.c b/board/jungle/main.c index 40777d9965..329ee98a1f 100644 --- a/board/jungle/main.c +++ b/board/jungle/main.c @@ -156,10 +156,7 @@ int main(void) { print("\n\n\n************************ MAIN START ************************\n"); // check for non-supported board types - if (hw_type == HW_TYPE_UNKNOWN) { - print("Unsupported board type\n"); - while (1) { /* hang */ } - } + assert_fatal(hw_type != HW_TYPE_UNKNOWN, "Unsupported board type\n"); print("Config:\n"); print(" Board type: 0x"); puth(hw_type); print("\n"); diff --git a/board/jungle/scripts/can_printer.py b/board/jungle/scripts/can_printer.py index 675fc508a1..f620d6f122 100755 --- a/board/jungle/scripts/can_printer.py +++ b/board/jungle/scripts/can_printer.py @@ -19,7 +19,7 @@ def can_printer(): canbus = int(os.getenv("CAN", "0")) while True: can_recv = p.can_recv() - for address, _, dat, src in can_recv: + for address, dat, src in can_recv: if src == canbus: msgs[address].append(dat) diff --git a/board/jungle/scripts/echo_loopback_test.py b/board/jungle/scripts/echo_loopback_test.py index 78b65b5341..2cc523c8fa 100755 --- a/board/jungle/scripts/echo_loopback_test.py +++ b/board/jungle/scripts/echo_loopback_test.py @@ -37,7 +37,7 @@ def test_loopback(): incoming = jungle.can_recv() found = False for message in incoming: - incomingAddress, _, incomingData, incomingBus = message + incomingAddress, incomingData, incomingBus = message if incomingAddress == address and incomingData == data[::-1] and incomingBus == bus: found = True break diff --git a/board/jungle/scripts/loopback_test.py b/board/jungle/scripts/loopback_test.py index 10caf42cc4..b7be5586b9 100755 --- a/board/jungle/scripts/loopback_test.py +++ b/board/jungle/scripts/loopback_test.py @@ -74,11 +74,11 @@ def can_loopback(sender): raise Exception("Amount of received CAN messages (" + str(len(content)) + ") does not equal 1. Bus: " + str(bus) +" OBD: " + str(obd)) # Check content - if content[0][0] != addr or content[0][2] != string: + if content[0][0] != addr or content[0][1] != string: raise Exception("Received CAN message content or address does not match") # Check bus - if content[0][3] != bus: + if content[0][2] != bus: raise Exception("Received CAN message bus does not match") ################################################################# diff --git a/board/libc.h b/board/libc.h index 8af22775f2..d324981d3a 100644 --- a/board/libc.h +++ b/board/libc.h @@ -5,6 +5,16 @@ void delay(uint32_t a) { for (i = 0; i < a; i++); } +void assert_fatal(bool condition, const char *msg) { + if (!condition) { + print("ASSERT FAILED\n"); + print(msg); + while (1) { + // hang + } + } +} + // cppcheck-suppress misra-c2012-21.2 // cppcheck-suppress unusedFunction ; gcc uses memset to initialize structures void *memset(void *str, int c, unsigned int n) { diff --git a/board/main.c b/board/main.c index d4b5f20b46..b3cff83e29 100644 --- a/board/main.c +++ b/board/main.c @@ -67,12 +67,8 @@ void set_safety_mode(uint16_t mode, uint16_t param) { print("Error: safety set mode failed. Falling back to SILENT\n"); mode_copy = SAFETY_SILENT; err = set_safety_hooks(mode_copy, 0U); - if (err == -1) { - print("Error: Failed setting SILENT mode. Hanging\n"); - while (true) { - // TERMINAL ERROR: we can't continue if SILENT safety mode isn't succesfully set - } - } + // TERMINAL ERROR: we can't continue if SILENT safety mode isn't succesfully set + assert_fatal(err == 0, "Error: Failed setting SILENT mode. Hanging\n"); } safety_tx_blocked = 0; safety_rx_invalid = 0; @@ -99,7 +95,7 @@ void set_safety_mode(uint16_t mode, uint16_t param) { if (current_board->has_obd) { // Clear any pending messages in the can core (i.e. sending while comma power is unplugged) // TODO: rewrite using hardware queues rather than fifo to cancel specific messages - llcan_clear_send(CANIF_FROM_CAN_NUM(1)); + can_clear_send(CANIF_FROM_CAN_NUM(1), 1); if (param == 0U) { current_board->set_can_mode(CAN_MODE_OBD_CAN2); } else { @@ -314,10 +310,7 @@ int main(void) { print("\n\n\n************************ MAIN START ************************\n"); // check for non-supported board types - if(hw_type == HW_TYPE_UNKNOWN){ - print("Unsupported board type\n"); - while (1) { /* hang */ } - } + assert_fatal(hw_type != HW_TYPE_UNKNOWN, "Unsupported board type"); print("Config:\n"); print(" Board type: 0x"); puth(hw_type); print("\n"); diff --git a/board/stm32h7/board.h b/board/stm32h7/board.h index c8e6f3a968..711497a373 100644 --- a/board/stm32h7/board.h +++ b/board/stm32h7/board.h @@ -17,36 +17,33 @@ #include "boards/cuatro.h" -uint8_t get_board_id(void) { - return detect_with_pull(GPIOF, 7, PULL_UP) | - (detect_with_pull(GPIOF, 8, PULL_UP) << 1U) | - (detect_with_pull(GPIOF, 9, PULL_UP) << 2U) | - (detect_with_pull(GPIOF, 10, PULL_UP) << 3U); -} - void detect_board_type(void) { - const uint8_t board_id = get_board_id(); + // On STM32H7 pandas, we use two different sets of pins. + const uint8_t id1 = detect_with_pull(GPIOF, 7, PULL_UP) | + (detect_with_pull(GPIOF, 8, PULL_UP) << 1U) | + (detect_with_pull(GPIOF, 9, PULL_UP) << 2U) | + (detect_with_pull(GPIOF, 10, PULL_UP) << 3U); - if (board_id == 0U) { + const uint8_t id2 = detect_with_pull(GPIOD, 4, PULL_UP) | + (detect_with_pull(GPIOD, 5, PULL_UP) << 1U) | + (detect_with_pull(GPIOD, 6, PULL_UP) << 2U) | + (detect_with_pull(GPIOD, 7, PULL_UP) << 3U); + + if (id2 == 3U) { + hw_type = HW_TYPE_CUATRO; + current_board = &board_cuatro; + } else if (id1 == 0U) { hw_type = HW_TYPE_RED_PANDA; current_board = &board_red; - } else if (board_id == 1U) { + } else if (id1 == 1U) { // deprecated //hw_type = HW_TYPE_RED_PANDA_V2; - } else if (board_id == 2U) { + hw_type = HW_TYPE_UNKNOWN; + } else if (id1 == 2U) { hw_type = HW_TYPE_TRES; current_board = &board_tres; - } else if (board_id == 3U) { - hw_type = HW_TYPE_CUATRO; - current_board = &board_tres; } else { hw_type = HW_TYPE_UNKNOWN; print("Hardware type is UNKNOWN!\n"); } - - // TODO: detect this live -#ifdef STM32H723 - hw_type = HW_TYPE_CUATRO; - current_board = &board_cuatro; -#endif } diff --git a/board/stm32h7/clock.h b/board/stm32h7/clock.h index 2e3ab701d8..b68fcc1c26 100644 --- a/board/stm32h7/clock.h +++ b/board/stm32h7/clock.h @@ -17,13 +17,55 @@ APB4 per: 60MHz PCLK1: 60MHz (for USART2,3,4,5,7,8) */ +typedef enum { + PACKAGE_UNKNOWN = 0, + PACKAGE_WITH_SMPS = 1, + PACKAGE_WITHOUT_SMPS = 2, +} PackageSMPSType; + +// TODO: find a better way to distinguish between H725 (using SMPS) and H723 (lacking SMPS) +// The package will do for now, since we have only used TFBGA100 for H723 +PackageSMPSType get_package_smps_type(void) { + PackageSMPSType ret; + RCC->APB4ENR |= RCC_APB4ENR_SYSCFGEN; // make sure SYSCFG clock is enabled. does seem to read fine without too though + + switch(SYSCFG->PKGR & 0xFU) { + case 0b0001U: // TFBGA100 Legacy + case 0b0011U: // TFBGA100 + ret = PACKAGE_WITHOUT_SMPS; + break; + case 0b0101U: // LQFP144 Legacy + case 0b0111U: // LQFP144 Industrial + case 0b1000U: // UFBGA169 + ret = PACKAGE_WITH_SMPS; + break; + default: + ret = PACKAGE_UNKNOWN; + } + return ret; +} + void clock_init(void) { - // Set power mode to direct SMPS power supply(depends on the board layout) -#ifndef STM32H723 - register_set(&(PWR->CR3), PWR_CR3_SMPSEN, 0xFU); // powered only by SMPS -#else - register_set(&(PWR->CR3), PWR_CR3_LDOEN, 0xFU); -#endif + /* + WARNING: PWR->CR3's lower byte can only be written once + * subsequent writes will silently fail + * only cleared with a full power-on-reset, not soft reset or reset pin + * some H7 have a bootrom with a DFU routine that writes (and locks) CR3 + * if the CR3 config doesn't match the HW, the core will deadlock and require immediately going into DFU from a cold boot + + In a normal bootup, the bootstub will be the first to write this. The app section calls clock_init again, but the CR3 write will silently fail. This is fine for most cases, but caution should be taken that the bootstub and app always write the same config. + */ + + // Set power mode to direct SMPS power supply (depends on the board layout) + PackageSMPSType package_smps = get_package_smps_type(); + if (package_smps == PACKAGE_WITHOUT_SMPS) { + register_set(&(PWR->CR3), PWR_CR3_LDOEN, 0xFU); // no SMPS, so powered by LDO + } else if (package_smps == PACKAGE_WITH_SMPS) { + register_set(&(PWR->CR3), PWR_CR3_SMPSEN, 0xFU); // powered only by SMPS + } else { + while(true); // unknown package, let's hang here + } + // Set VOS level (VOS3 to 170Mhz, VOS2 to 300Mhz, VOS1 to 400Mhz, VOS0 to 550Mhz) register_set(&(PWR->D3CR), PWR_D3CR_VOS_1 | PWR_D3CR_VOS_0, 0xC000U); //VOS1, needed for 80Mhz CAN FD while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0U); diff --git a/board/stm32h7/interrupt_handlers.h b/board/stm32h7/interrupt_handlers.h index fb1298d77b..8148021d69 100644 --- a/board/stm32h7/interrupt_handlers.h +++ b/board/stm32h7/interrupt_handlers.h @@ -20,6 +20,10 @@ void DMA1_Stream4_IRQHandler(void) {handle_interrupt(DMA1_Stream4_IRQn);} void DMA1_Stream5_IRQHandler(void) {handle_interrupt(DMA1_Stream5_IRQn);} void DMA1_Stream6_IRQHandler(void) {handle_interrupt(DMA1_Stream6_IRQn);} void ADC_IRQHandler(void) {handle_interrupt(ADC_IRQn);} +void FDCAN1_IT0_IRQHandler(void) {handle_interrupt(FDCAN1_IT0_IRQn);} +void FDCAN2_IT0_IRQHandler(void) {handle_interrupt(FDCAN2_IT0_IRQn);} +void FDCAN1_IT1_IRQHandler(void) {handle_interrupt(FDCAN1_IT1_IRQn);} +void FDCAN2_IT1_IRQHandler(void) {handle_interrupt(FDCAN2_IT1_IRQn);} void EXTI9_5_IRQHandler(void) {handle_interrupt(EXTI9_5_IRQn);} void TIM1_BRK_IRQHandler(void) {handle_interrupt(TIM1_BRK_IRQn);} void TIM1_UP_TIM10_IRQHandler(void) {handle_interrupt(TIM1_UP_TIM10_IRQn);} @@ -44,9 +48,10 @@ void TIM8_UP_TIM13_IRQHandler(void) {handle_interrupt(TIM8_UP_TIM13_IRQn);} void TIM8_TRG_COM_TIM14_IRQHandler(void) {handle_interrupt(TIM8_TRG_COM_TIM14_IRQn);} void TIM8_CC_IRQHandler(void) {handle_interrupt(TIM8_CC_IRQn);} void DMA1_Stream7_IRQHandler(void) {handle_interrupt(DMA1_Stream7_IRQn);} +void FMC_IRQHandler(void) {handle_interrupt(FMC_IRQn);} +void SDMMC1_IRQHandler(void) {handle_interrupt(SDMMC1_IRQn);} void TIM5_IRQHandler(void) {handle_interrupt(TIM5_IRQn);} void SPI3_IRQHandler(void) {handle_interrupt(SPI3_IRQn);} -void SPI4_IRQHandler(void) {handle_interrupt(SPI4_IRQn);} void UART4_IRQHandler(void) {handle_interrupt(UART4_IRQn);} void UART5_IRQHandler(void) {handle_interrupt(UART5_IRQn);} void TIM6_DAC_IRQHandler(void) {handle_interrupt(TIM6_DAC_IRQn);} @@ -56,21 +61,83 @@ void DMA2_Stream1_IRQHandler(void) {handle_interrupt(DMA2_Stream1_IRQn);} void DMA2_Stream2_IRQHandler(void) {handle_interrupt(DMA2_Stream2_IRQn);} void DMA2_Stream3_IRQHandler(void) {handle_interrupt(DMA2_Stream3_IRQn);} void DMA2_Stream4_IRQHandler(void) {handle_interrupt(DMA2_Stream4_IRQn);} +void ETH_IRQHandler(void) {handle_interrupt(ETH_IRQn);} +void ETH_WKUP_IRQHandler(void) {handle_interrupt(ETH_WKUP_IRQn);} +void FDCAN_CAL_IRQHandler(void) {handle_interrupt(FDCAN_CAL_IRQn);} void DMA2_Stream5_IRQHandler(void) {handle_interrupt(DMA2_Stream5_IRQn);} void DMA2_Stream6_IRQHandler(void) {handle_interrupt(DMA2_Stream6_IRQn);} void DMA2_Stream7_IRQHandler(void) {handle_interrupt(DMA2_Stream7_IRQn);} void USART6_IRQHandler(void) {handle_interrupt(USART6_IRQn);} void I2C3_EV_IRQHandler(void) {handle_interrupt(I2C3_EV_IRQn);} void I2C3_ER_IRQHandler(void) {handle_interrupt(I2C3_ER_IRQn);} -void FDCAN1_IT0_IRQHandler(void) {handle_interrupt(FDCAN1_IT0_IRQn);} -void FDCAN1_IT1_IRQHandler(void) {handle_interrupt(FDCAN1_IT1_IRQn);} -void FDCAN2_IT0_IRQHandler(void) {handle_interrupt(FDCAN2_IT0_IRQn);} -void FDCAN2_IT1_IRQHandler(void) {handle_interrupt(FDCAN2_IT1_IRQn);} -void FDCAN3_IT0_IRQHandler(void) {handle_interrupt(FDCAN3_IT0_IRQn);} -void FDCAN3_IT1_IRQHandler(void) {handle_interrupt(FDCAN3_IT1_IRQn);} -void FDCAN_CAL_IRQHandler(void) {handle_interrupt(FDCAN_CAL_IRQn);} void OTG_HS_EP1_OUT_IRQHandler(void) {handle_interrupt(OTG_HS_EP1_OUT_IRQn);} void OTG_HS_EP1_IN_IRQHandler(void) {handle_interrupt(OTG_HS_EP1_IN_IRQn);} void OTG_HS_WKUP_IRQHandler(void) {handle_interrupt(OTG_HS_WKUP_IRQn);} void OTG_HS_IRQHandler(void) {handle_interrupt(OTG_HS_IRQn);} +void DCMI_PSSI_IRQHandler(void) {handle_interrupt(DCMI_PSSI_IRQn);} +void CRYP_IRQHandler(void) {handle_interrupt(CRYP_IRQn);} +void HASH_RNG_IRQHandler(void) {handle_interrupt(HASH_RNG_IRQn);} +void FPU_IRQHandler(void) {handle_interrupt(FPU_IRQn);} void UART7_IRQHandler(void) {handle_interrupt(UART7_IRQn);} +void UART8_IRQHandler(void) {handle_interrupt(UART8_IRQn);} +void SPI4_IRQHandler(void) {handle_interrupt(SPI4_IRQn);} +void SPI5_IRQHandler(void) {handle_interrupt(SPI5_IRQn);} +void SPI6_IRQHandler(void) {handle_interrupt(SPI6_IRQn);} +void SAI1_IRQHandler(void) {handle_interrupt(SAI1_IRQn);} +void LTDC_IRQHandler(void) {handle_interrupt(LTDC_IRQn);} +void LTDC_ER_IRQHandler(void) {handle_interrupt(LTDC_ER_IRQn);} +void DMA2D_IRQHandler(void) {handle_interrupt(DMA2D_IRQn);} +void OCTOSPI1_IRQHandler(void) {handle_interrupt(OCTOSPI1_IRQn);} +void LPTIM1_IRQHandler(void) {handle_interrupt(LPTIM1_IRQn);} +void CEC_IRQHandler(void) {handle_interrupt(CEC_IRQn);} +void I2C4_EV_IRQHandler(void) {handle_interrupt(I2C4_EV_IRQn);} +void I2C4_ER_IRQHandler(void) {handle_interrupt(I2C4_ER_IRQn);} +void SPDIF_RX_IRQHandler(void) {handle_interrupt(SPDIF_RX_IRQn);} +void DMAMUX1_OVR_IRQHandler(void) {handle_interrupt(DMAMUX1_OVR_IRQn);} +void DFSDM1_FLT0_IRQHandler(void) {handle_interrupt(DFSDM1_FLT0_IRQn);} +void DFSDM1_FLT1_IRQHandler(void) {handle_interrupt(DFSDM1_FLT1_IRQn);} +void DFSDM1_FLT2_IRQHandler(void) {handle_interrupt(DFSDM1_FLT2_IRQn);} +void DFSDM1_FLT3_IRQHandler(void) {handle_interrupt(DFSDM1_FLT3_IRQn);} +void SWPMI1_IRQHandler(void) {handle_interrupt(SWPMI1_IRQn);} +void TIM15_IRQHandler(void) {handle_interrupt(TIM15_IRQn);} +void TIM16_IRQHandler(void) {handle_interrupt(TIM16_IRQn);} +void TIM17_IRQHandler(void) {handle_interrupt(TIM17_IRQn);} +void MDIOS_WKUP_IRQHandler(void) {handle_interrupt(MDIOS_WKUP_IRQn);} +void MDIOS_IRQHandler(void) {handle_interrupt(MDIOS_IRQn);} +void MDMA_IRQHandler(void) {handle_interrupt(MDMA_IRQn);} +void SDMMC2_IRQHandler(void) {handle_interrupt(SDMMC2_IRQn);} +void HSEM1_IRQHandler(void) {handle_interrupt(HSEM1_IRQn);} +void ADC3_IRQHandler(void) {handle_interrupt(ADC3_IRQn);} +void DMAMUX2_OVR_IRQHandler(void) {handle_interrupt(DMAMUX2_OVR_IRQn);} +void BDMA_Channel0_IRQHandler(void) {handle_interrupt(BDMA_Channel0_IRQn);} +void BDMA_Channel1_IRQHandler(void) {handle_interrupt(BDMA_Channel1_IRQn);} +void BDMA_Channel2_IRQHandler(void) {handle_interrupt(BDMA_Channel2_IRQn);} +void BDMA_Channel3_IRQHandler(void) {handle_interrupt(BDMA_Channel3_IRQn);} +void BDMA_Channel4_IRQHandler(void) {handle_interrupt(BDMA_Channel4_IRQn);} +void BDMA_Channel5_IRQHandler(void) {handle_interrupt(BDMA_Channel5_IRQn);} +void BDMA_Channel6_IRQHandler(void) {handle_interrupt(BDMA_Channel6_IRQn);} +void BDMA_Channel7_IRQHandler(void) {handle_interrupt(BDMA_Channel7_IRQn);} +void COMP_IRQHandler(void) {handle_interrupt(COMP_IRQn);} +void LPTIM2_IRQHandler(void) {handle_interrupt(LPTIM2_IRQn);} +void LPTIM3_IRQHandler(void) {handle_interrupt(LPTIM3_IRQn);} +void LPTIM4_IRQHandler(void) {handle_interrupt(LPTIM4_IRQn);} +void LPTIM5_IRQHandler(void) {handle_interrupt(LPTIM5_IRQn);} +void LPUART1_IRQHandler(void) {handle_interrupt(LPUART1_IRQn);} +void CRS_IRQHandler(void) {handle_interrupt(CRS_IRQn);} +void ECC_IRQHandler(void) {handle_interrupt(ECC_IRQn);} +void SAI4_IRQHandler(void) {handle_interrupt(SAI4_IRQn);} +void DTS_IRQHandler(void) {handle_interrupt(DTS_IRQn);} +void WAKEUP_PIN_IRQHandler(void) {handle_interrupt(WAKEUP_PIN_IRQn);} +void OCTOSPI2_IRQHandler(void) {handle_interrupt(OCTOSPI2_IRQn);} +void OTFDEC1_IRQHandler(void) {handle_interrupt(OTFDEC1_IRQn);} +void OTFDEC2_IRQHandler(void) {handle_interrupt(OTFDEC2_IRQn);} +void FMAC_IRQHandler(void) {handle_interrupt(FMAC_IRQn);} +void CORDIC_IRQHandler(void) {handle_interrupt(CORDIC_IRQn);} +void UART9_IRQHandler(void) {handle_interrupt(UART9_IRQn);} +void USART10_IRQHandler(void) {handle_interrupt(USART10_IRQn);} +void I2C5_EV_IRQHandler(void) {handle_interrupt(I2C5_EV_IRQn);} +void I2C5_ER_IRQHandler(void) {handle_interrupt(I2C5_ER_IRQn);} +void FDCAN3_IT0_IRQHandler(void) {handle_interrupt(FDCAN3_IT0_IRQn);} +void FDCAN3_IT1_IRQHandler(void) {handle_interrupt(FDCAN3_IT1_IRQn);} +void TIM23_IRQHandler(void) {handle_interrupt(TIM23_IRQn);} +void TIM24_IRQHandler(void) {handle_interrupt(TIM24_IRQn);} diff --git a/board/stm32h7/llfan.h b/board/stm32h7/llfan.h index dce622503a..04f0fc11c8 100644 --- a/board/stm32h7/llfan.h +++ b/board/stm32h7/llfan.h @@ -8,8 +8,8 @@ void EXTI2_IRQ_Handler(void) { } void llfan_init(void) { - // 5000RPM * 4 tach edges / 60 seconds - REGISTER_INTERRUPT(EXTI2_IRQn, EXTI2_IRQ_Handler, 700U, FAULT_INTERRUPT_RATE_TACH) + // 12000RPM * 4 tach edges / 60 seconds + REGISTER_INTERRUPT(EXTI2_IRQn, EXTI2_IRQ_Handler, 1000U, FAULT_INTERRUPT_RATE_TACH) // Init PWM speed control pwm_init(TIM3, 3); diff --git a/drivers/spi/load.sh b/drivers/spi/load.sh index b8efdbf708..910ac87282 100755 --- a/drivers/spi/load.sh +++ b/drivers/spi/load.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/drivers/spi/pull-src.sh b/drivers/spi/pull-src.sh index f74b94b9e7..64dac9bca0 100755 --- a/drivers/spi/pull-src.sh +++ b/drivers/spi/pull-src.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/examples/can_logger.py b/examples/can_logger.py index aed3ac9d6b..2bf4359cac 100755 --- a/examples/can_logger.py +++ b/examples/can_logger.py @@ -22,7 +22,7 @@ def can_logger(): while True: can_recv = p.can_recv() - for address, _, dat, src in can_recv: + for address, dat, src in can_recv: csvwriter.writerow( [str(src), str(hex(address)), f"0x{dat.hex()}", len(dat), str(time.time() - start_time)]) diff --git a/examples/query_fw_versions.py b/examples/query_fw_versions.py index fe70bf96ab..8064c86907 100755 --- a/examples/query_fw_versions.py +++ b/examples/query_fw_versions.py @@ -10,6 +10,7 @@ parser.add_argument("--rxoffset", default="") parser.add_argument("--nonstandard", action="store_true") parser.add_argument("--no-obd", action="store_true", help="Bus 1 will not be multiplexed to the OBD-II port") + parser.add_argument("--no-29bit", action="store_true", help="29 bit addresses will not be queried") parser.add_argument("--debug", action="store_true") parser.add_argument("--addr") parser.add_argument("--sub_addr", "--subaddr", help="A hex sub-address or `scan` to scan the full sub-address range") @@ -21,7 +22,8 @@ addrs = [int(args.addr, base=16)] else: addrs = [0x700 + i for i in range(256)] - addrs += [0x18da0000 + (i << 8) + 0xf1 for i in range(256)] + if not args.no_29bit: + addrs += [0x18da0000 + (i << 8) + 0xf1 for i in range(256)] results = {} sub_addrs: list[int | None] = [None] diff --git a/examples/tesla_tester.py b/examples/tesla_tester.py index 966e39d103..48a6b7de6f 100755 --- a/examples/tesla_tester.py +++ b/examples/tesla_tester.py @@ -34,7 +34,7 @@ def tesla_tester(): while True: #Read the VIN can_recv = p.can_recv() - for address, _, dat, src in can_recv: + for address, dat, src in can_recv: if src == body_bus_num: if address == 1384: # 0x568 is VIN vin_index = int(binascii.hexlify(dat)[:2]) # first byte is the index, 00, 01, 02 diff --git a/pyproject.toml b/pyproject.toml index 375885e54d..5b0697d67b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,4 +12,4 @@ flake8-implicit-str-concat.allow-multiline=false "pytest.main".msg = "pytest.main requires special handling that is easy to mess up!" [tool.pytest.ini_options] -addopts = "-n auto" +addopts = "-n auto --ignore-glob='*.sh'" diff --git a/python/__init__.py b/python/__init__.py index a18fdc5f91..0e531dfc75 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -6,7 +6,6 @@ import struct import hashlib import binascii -import logging from functools import wraps, partial from itertools import accumulate @@ -16,17 +15,14 @@ from .isotp import isotp_send, isotp_recv from .spi import PandaSpiHandle, PandaSpiException, PandaProtocolMismatch from .usb import PandaUsbHandle +from .utils import logger __version__ = '0.0.10' -# setup logging -LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper() -logging.basicConfig(level=LOGLEVEL, format='%(message)s') - CANPACKET_HEAD_SIZE = 0x6 DLC_TO_LEN = [0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64] LEN_TO_DLC = {length: dlc for (dlc, length) in enumerate(DLC_TO_LEN)} -PANDA_BUS_CNT = 4 +PANDA_BUS_CNT = 3 def calculate_checksum(data): @@ -37,9 +33,9 @@ def calculate_checksum(data): def pack_can_buffer(arr): snds = [b''] - for address, _, dat, bus in arr: + for address, dat, bus in arr: assert len(dat) in LEN_TO_DLC - #logging.debug(" W 0x%x: 0x%s", address, dat.hex()) + #logger.debug(" W 0x%x: 0x%s", address, dat.hex()) extended = 1 if address >= 0x800 else 0 data_len_code = LEN_TO_DLC[len(dat)] @@ -85,7 +81,7 @@ def unpack_can_buffer(dat): data = dat[CANPACKET_HEAD_SIZE:(CANPACKET_HEAD_SIZE+data_len)] dat = dat[(CANPACKET_HEAD_SIZE+data_len):] - ret.append((address, 0, data, bus)) + ret.append((address, data, bus)) return (ret, dat) @@ -259,7 +255,7 @@ def connect(self, claim=True, wait=False): self._handle = None while self._handle is None: # try USB first, then SPI - self._context, self._handle, serial, self.bootstub, bcd = self.usb_connect(self._connect_serial, claim=claim) + self._context, self._handle, serial, self.bootstub, bcd = self.usb_connect(self._connect_serial, claim=claim, no_error=wait) if self._handle is None: self._context, self._handle, serial, self.bootstub, bcd = self.spi_connect(self._connect_serial) if not wait: @@ -290,7 +286,7 @@ def connect(self, claim=True, wait=False): self._handle_open = True self._mcu_type = self.get_mcu_type() self.health_version, self.can_version, self.can_health_version = self.get_packets_versions() - logging.debug("connected") + logger.debug("connected") # disable openpilot's heartbeat checks if self._disable_checks: @@ -351,7 +347,7 @@ def spi_connect(cls, serial, ignore_version=False): return None, handle, spi_serial, bootstub, None @classmethod - def usb_connect(cls, serial, claim=True): + def usb_connect(cls, serial, claim=True, no_error=False): handle, usb_serial, bootstub, bcd = None, None, None, None context = usb1.USBContext() context.open() @@ -361,11 +357,13 @@ def usb_connect(cls, serial, claim=True): try: this_serial = device.getSerialNumber() except Exception: - logging.exception("failed to get serial number of panda") + # Allow to ignore errors on reconnect. USB hubs need some time to initialize after panda reset + if not no_error: + logger.exception("failed to get serial number of panda") continue if serial is None or this_serial == serial: - logging.debug("opening device %s %s", this_serial, hex(device.getProductID())) + logger.debug("opening device %s %s", this_serial, hex(device.getProductID())) usb_serial = this_serial bootstub = (device.getProductID() & 0xF0) == 0xe0 @@ -383,7 +381,7 @@ def usb_connect(cls, serial, claim=True): break except Exception: - logging.exception("USB connect error") + logger.exception("USB connect error") usb_handle = None if handle is not None: @@ -411,11 +409,11 @@ def usb_list(cls): if len(serial) == 24: ret.append(serial) else: - logging.warning(f"found device with panda descriptors but invalid serial: {serial}", RuntimeWarning) + logger.warning(f"found device with panda descriptors but invalid serial: {serial}", RuntimeWarning) except Exception: - logging.exception("error connecting to panda") + logger.exception("error connecting to panda") except Exception: - logging.exception("exception while listing pandas") + logger.exception("exception while listing pandas") return ret @classmethod @@ -455,7 +453,7 @@ def reconnect(self): # wait up to 15 seconds for _ in range(15*10): try: - self.connect() + self.connect(claim=False, wait=True) success = True break except Exception: @@ -483,22 +481,22 @@ def flash_static(handle, code, mcu_type): assert last_sector < 7, "Binary too large! Risk of overwriting provisioning chunk." # unlock flash - logging.warning("flash: unlocking") + logger.warning("flash: unlocking") handle.controlWrite(Panda.REQUEST_IN, 0xb1, 0, 0, b'') # erase sectors - logging.warning(f"flash: erasing sectors 1 - {last_sector}") + logger.warning(f"flash: erasing sectors 1 - {last_sector}") for i in range(1, last_sector + 1): handle.controlWrite(Panda.REQUEST_IN, 0xb2, i, 0, b'') # flash over EP2 STEP = 0x10 - logging.warning("flash: flashing") + logger.warning("flash: flashing") for i in range(0, len(code), STEP): handle.bulkWrite(2, code[i:i + STEP]) # reset - logging.warning("flash: resetting") + logger.warning("flash: resetting") try: handle.controlWrite(Panda.REQUEST_IN, 0xd8, 0, 0, b'', expect_disconnect=True) except Exception: @@ -506,13 +504,13 @@ def flash_static(handle, code, mcu_type): def flash(self, fn=None, code=None, reconnect=True): if self.up_to_date(fn=fn): - logging.debug("flash: already up to date") + logger.debug("flash: already up to date") return if not fn: fn = os.path.join(FW_PATH, self._mcu_type.config.app_fn) assert os.path.isfile(fn) - logging.debug("flash: main version is %s", self.get_version()) + logger.debug("flash: main version is %s", self.get_version()) if not self.bootstub: self.reset(enter_bootstub=True) assert(self.bootstub) @@ -522,7 +520,7 @@ def flash(self, fn=None, code=None, reconnect=True): code = f.read() # get version - logging.debug("flash: bootstub version is %s", self.get_version()) + logger.debug("flash: bootstub version is %s", self.get_version()) # do flash Panda.flash_static(self._handle, code, mcu_type=self._mcu_type) @@ -554,7 +552,7 @@ def wait_for_dfu(dfu_serial: str | None, timeout: int | None = None) -> bool: t_start = time.monotonic() dfu_list = PandaDFU.list() while (dfu_serial is None and len(dfu_list) == 0) or (dfu_serial is not None and dfu_serial not in dfu_list): - logging.debug("waiting for DFU...") + logger.debug("waiting for DFU...") time.sleep(0.1) if timeout is not None and (time.monotonic() - t_start) > timeout: return False @@ -566,7 +564,7 @@ def wait_for_panda(serial: str | None, timeout: int) -> bool: t_start = time.monotonic() serials = Panda.list() while (serial is None and len(serials) == 0) or (serial is not None and serial not in serials): - logging.debug("waiting for panda...") + logger.debug("waiting for panda...") time.sleep(0.1) if timeout is not None and (time.monotonic() - t_start) > timeout: return False @@ -806,13 +804,13 @@ def can_send_many(self, arr, timeout=CAN_SEND_TIMEOUT_MS): tx = tx[bs:] if len(tx) == 0: break - logging.error("CAN: PARTIAL SEND MANY, RETRYING") + logger.error("CAN: PARTIAL SEND MANY, RETRYING") break except (usb1.USBErrorIO, usb1.USBErrorOverflow): - logging.error("CAN: BAD SEND MANY, RETRYING") + logger.error("CAN: BAD SEND MANY, RETRYING") def can_send(self, addr, dat, bus, timeout=CAN_SEND_TIMEOUT_MS): - self.can_send_many([[addr, None, dat, bus]], timeout=timeout) + self.can_send_many([[addr, dat, bus]], timeout=timeout) @ensure_can_packet_version def can_recv(self): @@ -822,7 +820,7 @@ def can_recv(self): dat = self._handle.bulkRead(1, 16384) # Max receive batch size + 2 extra reserve frames break except (usb1.USBErrorIO, usb1.USBErrorOverflow): - logging.error("CAN: BAD RECV, RETRYING") + logger.error("CAN: BAD RECV, RETRYING") time.sleep(0.1) msgs, self.can_rx_overflow_buffer = unpack_can_buffer(self.can_rx_overflow_buffer + dat) return msgs diff --git a/python/ccp.py b/python/ccp.py index 50a5f87a3d..20ca3c62da 100644 --- a/python/ccp.py +++ b/python/ccp.py @@ -2,6 +2,35 @@ import time import struct from enum import IntEnum, Enum +from dataclasses import dataclass +from typing import Optional + +@dataclass +class ExchangeStationIdsReturn: + id_length: int + data_type: int + available: int + protected: int + +@dataclass +class GetDaqListSizeReturn: + list_size: int + first_pid: int + +@dataclass +class GetSessionStatusReturn: + status: int + info: Optional[int] + +@dataclass +class DiagnosticServiceReturn: + length: int + type: int + +@dataclass +class ActionServiceReturn: + length: int + type: int class COMMAND_CODE(IntEnum): CONNECT = 0x01 @@ -99,7 +128,7 @@ def _recv_dto(self, timeout: float) -> bytes: msgs = self._panda.can_recv() or [] if len(msgs) >= 256: print("CAN RX buffer overflow!!!", file=sys.stderr) - for rx_addr, _, rx_data_bytearray, rx_bus in msgs: + for rx_addr, rx_data_bytearray, rx_bus in msgs: if rx_bus == self.can_bus and rx_addr == self.rx_addr: rx_data = bytes(rx_data_bytearray) if self.debug: @@ -140,20 +169,15 @@ def connect(self, station_addr: int) -> None: self._send_cro(COMMAND_CODE.CONNECT, struct.pack(" dict: + def exchange_station_ids(self, device_id_info: bytes = b"") -> ExchangeStationIdsReturn: self._send_cro(COMMAND_CODE.EXCHANGE_ID, device_id_info) resp = self._recv_dto(0.025) - return { # TODO: define a type - "id_length": resp[0], - "data_type": resp[1], - "available": resp[2], - "protected": resp[3], - } + return ExchangeStationIdsReturn(id_length=resp[0], data_type=resp[1], available=resp[2], protected=resp[3]) def get_seed(self, resource_mask: int) -> bytes: if resource_mask > 255: raise ValueError("resource mask must be less than 256") - self._send_cro(COMMAND_CODE.GET_SEED) + self._send_cro(COMMAND_CODE.GET_SEED, bytes([resource_mask])) resp = self._recv_dto(0.025) # protected = resp[0] == 0 seed = resp[1:] @@ -197,7 +221,7 @@ def upload(self, size: int) -> bytes: if size > 5: raise ValueError("size must be less than 6") self._send_cro(COMMAND_CODE.UPLOAD, bytes([size])) - return self._recv_dto(0.025) + return self._recv_dto(0.025)[:size] def short_upload(self, size: int, addr_ext: int, addr: int) -> bytes: if size > 5: @@ -205,21 +229,18 @@ def short_upload(self, size: int, addr_ext: int, addr: int) -> bytes: if addr_ext > 255: raise ValueError("address extension must be less than 256") self._send_cro(COMMAND_CODE.SHORT_UP, bytes([size, addr_ext]) + struct.pack(f"{self.byte_order.value}I", addr)) - return self._recv_dto(0.025) + return self._recv_dto(0.025)[:size] def select_calibration_page(self) -> None: self._send_cro(COMMAND_CODE.SELECT_CAL_PAGE) self._recv_dto(0.025) - def get_daq_list_size(self, list_num: int, can_id: int = 0) -> dict: + def get_daq_list_size(self, list_num: int, can_id: int = 0) -> GetDaqListSizeReturn: if list_num > 255: raise ValueError("list number must be less than 256") self._send_cro(COMMAND_CODE.GET_DAQ_SIZE, bytes([list_num, 0]) + struct.pack(f"{self.byte_order.value}I", can_id)) resp = self._recv_dto(0.025) - return { # TODO: define a type - "list_size": resp[0], - "first_pid": resp[1], - } + return GetDaqListSizeReturn(list_size=resp[0], first_pid=resp[1]) def set_daq_list_pointer(self, list_num: int, odt_num: int, element_num: int) -> None: if list_num > 255: @@ -266,13 +287,11 @@ def set_session_status(self, status: int) -> None: self._send_cro(COMMAND_CODE.SET_S_STATUS, bytes([status])) self._recv_dto(0.025) - def get_session_status(self) -> dict: + def get_session_status(self) -> GetSessionStatusReturn: self._send_cro(COMMAND_CODE.GET_S_STATUS) resp = self._recv_dto(0.025) - return { # TODO: define a type - "status": resp[0], - "info": resp[2] if resp[1] else None, - } + info = resp[2] if resp[1] else None + return GetSessionStatusReturn(status=resp[0], info=info) def build_checksum(self, size: int) -> bytes: self._send_cro(COMMAND_CODE.BUILD_CHKSUM, struct.pack(f"{self.byte_order.value}I", size)) @@ -310,29 +329,23 @@ def move_memory_block(self, size: int) -> None: self._send_cro(COMMAND_CODE.MOVE, struct.pack(f"{self.byte_order.value}I", size)) self._recv_dto(0.025) - def diagnostic_service(self, service_num: int, data: bytes = b"") -> dict: + def diagnostic_service(self, service_num: int, data: bytes = b"") -> DiagnosticServiceReturn: if service_num > 65535: raise ValueError("service number must be less than 65536") if len(data) > 4: raise ValueError("max data size is 4 bytes") self._send_cro(COMMAND_CODE.DIAG_SERVICE, struct.pack(f"{self.byte_order.value}H", service_num) + data) resp = self._recv_dto(0.025) - return { # TODO: define a type - "length": resp[0], - "type": resp[1], - } + return DiagnosticServiceReturn(length=resp[0], type=resp[1]) - def action_service(self, service_num: int, data: bytes = b"") -> dict: + def action_service(self, service_num: int, data: bytes = b"") -> ActionServiceReturn: if service_num > 65535: raise ValueError("service number must be less than 65536") if len(data) > 4: raise ValueError("max data size is 4 bytes") self._send_cro(COMMAND_CODE.ACTION_SERVICE, struct.pack(f"{self.byte_order.value}H", service_num) + data) resp = self._recv_dto(0.025) - return { # TODO: define a type - "length": resp[0], - "type": resp[1], - } + return ActionServiceReturn(length=resp[0], type=resp[1]) def test_availability(self, station_addr: int) -> None: if station_addr > 65535: diff --git a/python/isotp.py b/python/isotp.py index d0bef7d942..ac64c413be 100644 --- a/python/isotp.py +++ b/python/isotp.py @@ -18,12 +18,12 @@ def recv(panda, cnt, addr, nbus): while len(ret) < cnt: kmsgs += panda.can_recv() nmsgs = [] - for ids, ts, dat, bus in kmsgs: + for ids, dat, bus in kmsgs: if ids == addr and bus == nbus and len(ret) < cnt: ret.append(dat) else: # leave around - nmsgs.append((ids, ts, dat, bus)) + nmsgs.append((ids, dat, bus)) kmsgs = nmsgs[-256:] return ret @@ -96,7 +96,7 @@ def isotp_send(panda, x, addr, bus=0, recvaddr=None, subaddr=None, rate=None): panda.can_send(addr, sends[-1], 0) else: if rate is None: - panda.can_send_many([(addr, None, s, bus) for s in sends]) + panda.can_send_many([(addr, s, bus) for s in sends]) else: for dat in sends: panda.can_send(addr, dat, bus) diff --git a/python/spi.py b/python/spi.py index be4f7dcf46..59e9018159 100644 --- a/python/spi.py +++ b/python/spi.py @@ -5,7 +5,6 @@ import math import time import struct -import logging import threading from contextlib import contextmanager from functools import reduce @@ -13,6 +12,7 @@ from .base import BaseHandle, BaseSTBootloaderHandle, TIMEOUT from .constants import McuType, MCU_TYPE_BY_IDCODE, USBPACKET_MAX_SIZE +from .utils import logger try: import spidev @@ -167,23 +167,23 @@ def _wait_for_ack(self, spi, ack_val: int, timeout: int, tx: int, length: int = def _transfer_spidev(self, spi, endpoint: int, data, timeout: int, max_rx_len: int = 1000, expect_disconnect: bool = False) -> bytes: max_rx_len = max(USBPACKET_MAX_SIZE, max_rx_len) - logging.debug("- send header") + logger.debug("- send header") packet = struct.pack(" bytes: - logging.debug("starting transfer: endpoint=%d, max_rx_len=%d", endpoint, max_rx_len) - logging.debug("==============================================") + logger.debug("starting transfer: endpoint=%d, max_rx_len=%d", endpoint, max_rx_len) + logger.debug("==============================================") n = 0 start_time = time.monotonic() exc = PandaSpiException() while (timeout == 0) or (time.monotonic() - start_time) < timeout*1e-3: n += 1 - logging.debug("\ntry #%d", n) + logger.debug("\ntry #%d", n) with self.dev.acquire() as spi: try: return self._transfer_raw(spi, endpoint, data, timeout, max_rx_len, expect_disconnect) except PandaSpiException as e: exc = e - logging.debug("SPI transfer failed, retrying", exc_info=True) + logger.debug("SPI transfer failed, retrying", exc_info=True) raise exc @@ -245,7 +245,7 @@ def get_protocol_version(self) -> bytes: def _get_version(spi) -> bytes: spi.writebytes(vers_str) - logging.debug("- waiting for echo") + logger.debug("- waiting for echo") start = time.monotonic() while True: version_bytes = spi.readbytes(len(vers_str) + 2) @@ -273,7 +273,7 @@ def _get_version(spi) -> bytes: return _get_version(spi) except PandaSpiException as e: exc = e - logging.debug("SPI get protocol version failed, retrying", exc_info=True) + logger.debug("SPI get protocol version failed, retrying", exc_info=True) raise exc # libusb1 functions @@ -378,7 +378,7 @@ def _cmd(self, cmd: int, data: list[bytes] | None = None, read_bytes: int = 0, p return self._cmd_no_retry(cmd, data, read_bytes, predata) except PandaSpiException as e: exc = e - logging.debug("SPI transfer failed, %d retries left", MAX_XFER_RETRY_COUNT - n - 1, exc_info=True) + logger.debug("SPI transfer failed, %d retries left", MAX_XFER_RETRY_COUNT - n - 1, exc_info=True) raise exc def _checksum(self, data: bytes) -> bytes: diff --git a/python/uds.py b/python/uds.py index 32b0de0961..b5439446cd 100644 --- a/python/uds.py +++ b/python/uds.py @@ -301,7 +301,7 @@ def get_dtc_status_names(status): return result class CanClient(): - def __init__(self, can_send: Callable[[int, bytes, int], None], can_recv: Callable[[], list[tuple[int, int, bytes, int]]], + def __init__(self, can_send: Callable[[int, bytes, int], None], can_recv: Callable[[], list[tuple[int, bytes, int]]], tx_addr: int, rx_addr: int, bus: int, sub_addr: int | None = None, debug: bool = False): self.tx = can_send self.rx = can_recv @@ -339,7 +339,7 @@ def _recv_buffer(self, drain: bool = False) -> None: print(f"CAN-RX: drain - {len(msgs)}") self.rx_buff.clear() else: - for rx_addr, _, rx_data, rx_bus in msgs or []: + for rx_addr, rx_data, rx_bus in msgs or []: if self._recv_filter(rx_bus, rx_addr) and len(rx_data) > 0: rx_data = bytes(rx_data) # convert bytearray to bytes diff --git a/python/utils.py b/python/utils.py new file mode 100644 index 0000000000..55181e08b1 --- /dev/null +++ b/python/utils.py @@ -0,0 +1,11 @@ +import os +import logging + +# set up logging +LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper() +logger = logging.getLogger('panda') +logger.setLevel(LOGLEVEL) + +handler = logging.StreamHandler() +handler.setFormatter(logging.Formatter('%(message)s')) +logger.addHandler(handler) diff --git a/python/xcp.py b/python/xcp.py index bb294046ec..066ed9885a 100644 --- a/python/xcp.py +++ b/python/xcp.py @@ -145,7 +145,7 @@ def _recv_dto(self, timeout: float) -> bytes: msgs = self._panda.can_recv() or [] if len(msgs) >= 256: print("CAN RX buffer overflow!!!", file=sys.stderr) - for rx_addr, _, rx_data, rx_bus in msgs: + for rx_addr, rx_data, rx_bus in msgs: if rx_bus == self.can_bus and rx_addr == self.rx_addr: rx_data = bytes(rx_data) # convert bytearray to bytes if self.debug: diff --git a/release/make_release.sh b/release/make_release.sh index 5628c4998d..cfecac3a16 100755 --- a/release/make_release.sh +++ b/release/make_release.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 5ee8636fd5..0000000000 --- a/requirements.txt +++ /dev/null @@ -1,18 +0,0 @@ -ruff -libusb1 -numpy -hexdump -pycryptodome -tqdm>=4.14.0 -pytest -pytest-mock -pytest-xdist -pytest-timeout -pytest-randomly -parameterized -cffi -pre-commit -scons>=4.4.0 -flaky -spidev -termcolor \ No newline at end of file diff --git a/setup.py b/setup.py index 25ee669236..a7729cc6f8 100644 --- a/setup.py +++ b/setup.py @@ -44,12 +44,27 @@ def find_version(*file_paths): platforms='any', license='MIT', install_requires=[ - 'libusb1 == 2.0.1', - 'hexdump >= 3.3', - 'pycryptodome >= 3.9.8', - 'tqdm >= 4.14.0', - 'requests' + 'libusb1', ], + extras_require = { + 'dev': [ + "scons", + "pycryptodome >= 3.9.8", + "cffi", + "flaky", + "pytest", + "pytest-mock", + "pytest-xdist", + "pytest-timeout", + "pytest-randomly", + "parameterized", + "pre-commit", + "numpy", + "ruff", + "spidev", + "setuptools", # for setup.py + ], + }, ext_modules=[], description="Code powering the comma.ai panda", long_description='See https://github.com/commaai/panda', diff --git a/tests/black_white_loopback_test.py b/tests/black_white_loopback_test.py index 8198a30d5f..69b0cfbd1e 100755 --- a/tests/black_white_loopback_test.py +++ b/tests/black_white_loopback_test.py @@ -118,11 +118,11 @@ def test_buses(black_panda, other_panda, direction, test_array, sleep_duration): loop_buses = [] for loop in cans_loop: - if (loop[0] != at) or (loop[2] != st): + if (loop[0] != at) or (loop[1] != st): content_errors += 1 - print(" Loop on bus", str(loop[3])) - loop_buses.append(loop[3]) + print(" Loop on bus", str(loop[2])) + loop_buses.append(loop[2]) if len(cans_loop) == 0: print(" No loop") assert not os.getenv("NOASSERT") diff --git a/tests/black_white_relay_endurance.py b/tests/black_white_relay_endurance.py index 005277c15a..433f12343a 100755 --- a/tests/black_white_relay_endurance.py +++ b/tests/black_white_relay_endurance.py @@ -126,11 +126,11 @@ def test_buses(black_panda, other_panda, direction, test_array, sleep_duration): loop_buses = [] for loop in cans_loop: - if (loop[0] != at) or (loop[2] != st): + if (loop[0] != at) or (loop[1] != st): content_errors += 1 - print(" Loop on bus", str(loop[3])) - loop_buses.append(loop[3]) + print(" Loop on bus", str(loop[2])) + loop_buses.append(loop[2]) if len(cans_loop) == 0: print(" No loop") assert os.getenv("NOASSERT") diff --git a/tests/black_white_relay_test.py b/tests/black_white_relay_test.py index 38db06a1a5..dce44f5675 100755 --- a/tests/black_white_relay_test.py +++ b/tests/black_white_relay_test.py @@ -109,9 +109,9 @@ def test_buses(black_panda, other_panda, test_obj): loop_buses = [] for loop in cans_loop: - if (loop[0] != at) or (loop[2] != st): + if (loop[0] != at) or (loop[1] != st): content_errors += 1 - loop_buses.append(loop[3]) + loop_buses.append(loop[2]) # test loop buses recv_buses.sort() diff --git a/tests/bulk_write_test.py b/tests/bulk_write_test.py index 278766a199..e886efb06d 100755 --- a/tests/bulk_write_test.py +++ b/tests/bulk_write_test.py @@ -16,7 +16,7 @@ def flood_tx(panda): print('Sending!') msg = b"\xaa" * 4 - packet = [[0xaa, None, msg, 0], [0xaa, None, msg, 1], [0xaa, None, msg, 2]] * NUM_MESSAGES_PER_BUS + packet = [[0xaa, msg, 0], [0xaa, msg, 1], [0xaa, msg, 2]] * NUM_MESSAGES_PER_BUS panda.can_send_many(packet, timeout=10000) print(f"Done sending {3*NUM_MESSAGES_PER_BUS} messages!") diff --git a/tests/can_printer.py b/tests/can_printer.py index 15ce89f688..70a18a61bd 100755 --- a/tests/can_printer.py +++ b/tests/can_printer.py @@ -17,10 +17,15 @@ def can_printer(): start = sec_since_boot() lp = sec_since_boot() msgs = defaultdict(list) + canbus = int(os.getenv("CAN", "0")) + if canbus == 3: + canbus = 1 + p.set_obd(True) + while True: can_recv = p.can_recv() - for address, _, dat, src in can_recv: + for address, dat, src in can_recv: if src == canbus: msgs[address].append(dat) diff --git a/tests/canfd/test_canfd.py b/tests/canfd/test_canfd.py index 873bc796ba..500a69aa06 100755 --- a/tests/canfd/test_canfd.py +++ b/tests/canfd/test_canfd.py @@ -86,7 +86,7 @@ def canfd_test(p_send, p_recv): data = bytearray(random.getrandbits(8) for _ in range(DLC_TO_LEN[dlc])) if len(data) >= 2: data[0] = calculate_checksum(data[1:] + bytes(str(address), encoding="utf-8")) - to_send.append([address, 0, data, bus]) + to_send.append([address, data, bus]) sent_msgs[bus].add((address, bytes(data))) p_send.can_send_many(to_send, timeout=0) @@ -95,7 +95,7 @@ def canfd_test(p_send, p_recv): while (time.monotonic() - start_time < 1) and any(len(x) > 0 for x in sent_msgs.values()): incoming = p_recv.can_recv() for msg in incoming: - address, _, data, bus = msg + address, data, bus = msg if len(data) >= 2: assert calculate_checksum(data[1:] + bytes(str(address), encoding="utf-8")) == data[0] k = (address, bytes(data)) diff --git a/tests/ci_shell.sh b/tests/ci_shell.sh index 92c0f96e8a..ab87f36cae 100755 --- a/tests/ci_shell.sh +++ b/tests/ci_shell.sh @@ -1,4 +1,5 @@ -#!/bin/bash -e +#!/usr/bin/env bash +set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" OP_ROOT="$DIR/../../" diff --git a/tests/echo.py b/tests/echo.py index 90bf4a8c76..1c20561b10 100755 --- a/tests/echo.py +++ b/tests/echo.py @@ -11,6 +11,6 @@ while True: incoming = p.can_recv() for message in incoming: - address, notused, data, bus = message + address, data, bus = message if b'test' in data: p.can_send(address, data[::-1], bus) diff --git a/tests/elm_car_simulator.py b/tests/elm_car_simulator.py index 56e825f5dd..90024a2541 100755 --- a/tests/elm_car_simulator.py +++ b/tests/elm_car_simulator.py @@ -77,11 +77,11 @@ def __can_monitor(self): self.panda.can_recv() # Toss whatever was already there while not self.__stop: - for address, ts, data, src in self.panda.can_recv(): + for address, data, src in self.panda.can_recv(): if self.__on and src == 0 and len(data) == 8 and data[0] >= 2: if not self.__silent: print("Processing CAN message", src, hex(address), binascii.hexlify(data)) - self.__can_process_msg(data[1], data[2], address, ts, data, src) + self.__can_process_msg(data[1], data[2], address, data, src) elif not self.__silent: print("Rejecting CAN message", src, hex(address), binascii.hexlify(data)) @@ -120,7 +120,7 @@ def _can_addr_matches(self, addr): return True return False - def __can_process_msg(self, mode, pid, address, ts, data, src): + def __can_process_msg(self, mode, pid, address, data, src): if not self.__silent: print("CAN MSG", binascii.hexlify(data[1:1 + data[0]]), "Addr:", hex(address), "Mode:", hex(mode)[2:].zfill(2), diff --git a/tests/hitl/3_usb_to_can.py b/tests/hitl/3_usb_to_can.py index c0a9035fe4..9920f44a87 100644 --- a/tests/hitl/3_usb_to_can.py +++ b/tests/hitl/3_usb_to_can.py @@ -18,14 +18,14 @@ def test_can_loopback(p): # confirm receive both on loopback and send receipt time.sleep(0.05) r = p.can_recv() - sr = [x for x in r if x[3] == 0x80 | bus] - lb = [x for x in r if x[3] == bus] + sr = [x for x in r if x[2] == 0x80 | bus] + lb = [x for x in r if x[2] == bus] assert len(sr) == 1 assert len(lb) == 1 # confirm data is correct assert 0x1aa == sr[0][0] == lb[0][0] - assert b"message" == sr[0][2] == lb[0][2] + assert b"message" == sr[0][1] == lb[0][1] def test_reliability(p): MSG_COUNT = 100 @@ -35,7 +35,7 @@ def test_reliability(p): p.set_can_speed_kbps(0, 1000) addrs = list(range(100, 100 + MSG_COUNT)) - ts = [(j, 0, b"\xaa" * 8, 0) for j in addrs] + ts = [(j, b"\xaa" * 8, 0) for j in addrs] for _ in range(100): st = time.monotonic() @@ -46,8 +46,8 @@ def test_reliability(p): while len(r) < 200 and (time.monotonic() - st) < 0.5: r.extend(p.can_recv()) - sent_echo = [x for x in r if x[3] == 0x80] - loopback_resp = [x for x in r if x[3] == 0] + sent_echo = [x for x in r if x[2] == 0x80] + loopback_resp = [x for x in r if x[2] == 0] assert sorted([x[0] for x in loopback_resp]) == addrs assert sorted([x[0] for x in sent_echo]) == addrs diff --git a/tests/hitl/4_can_loopback.py b/tests/hitl/4_can_loopback.py index a7e1aea1ee..c482ba8227 100644 --- a/tests/hitl/4_can_loopback.py +++ b/tests/hitl/4_can_loopback.py @@ -118,10 +118,10 @@ def test(p_send, p_recv, address=None): assert len(content) == 1 # Check content - assert content[0][0] == addr and content[0][2] == string + assert content[0][0] == addr and content[0][1] == string # Check bus - assert content[0][3] == bus + assert content[0][2] == bus print("Bus:", bus, "address:", addr, "OBD:", obd, "OK") @@ -148,9 +148,9 @@ def flood_tx(panda): msg = b"\xaa" * 8 packet = [] # start with many messages on a single bus (higher contention for single TX ring buffer) - packet += [[0xaa, None, msg, 0]] * NUM_MESSAGES_PER_BUS + packet += [[0xaa, msg, 0]] * NUM_MESSAGES_PER_BUS # end with many messages on multiple buses - packet += [[0xaa, None, msg, 0], [0xaa, None, msg, 1], [0xaa, None, msg, 2]] * NUM_MESSAGES_PER_BUS + packet += [[0xaa, msg, 0], [0xaa, msg, 1], [0xaa, msg, 2]] * NUM_MESSAGES_PER_BUS # Disable timeout panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) @@ -182,18 +182,18 @@ def test_message_integrity(p): for _ in range(random.randrange(10)): to_send = get_random_can_messages(random.randrange(100)) for m in to_send: - sent_msgs[m[3]].add((m[0], m[2])) + sent_msgs[m[2]].add((m[0], m[1])) p.can_send_many(to_send, timeout=0) start_time = time.monotonic() while time.monotonic() - start_time < 2 and any(len(sent_msgs[bus]) for bus in range(3)): recvd = p.can_recv() for msg in recvd: - if msg[3] >= 128: - k = (msg[0], bytes(msg[2])) - bus = msg[3]-128 + if msg[2] >= 128: + k = (msg[0], bytes(msg[1])) + bus = msg[2]-128 assert k in sent_msgs[bus], f"message {k} was never sent on bus {bus}" - sent_msgs[msg[3]-128].discard(k) + sent_msgs[msg[2]-128].discard(k) # if a set isn't empty, messages got dropped for bus in range(3): diff --git a/tests/hitl/6_safety.py b/tests/hitl/6_safety.py index 2237f53036..67c646166e 100644 --- a/tests/hitl/6_safety.py +++ b/tests/hitl/6_safety.py @@ -14,8 +14,8 @@ def test_safety_nooutput(p): time.sleep(0.05) r = p.can_recv() # bus 192 is messages blocked by TX safety hook on bus 0 - assert len([x for x in r if x[3] != 192]) == 0 - assert len([x for x in r if x[3] == 192]) == 1 + assert len([x for x in r if x[2] != 192]) == 0 + assert len([x for x in r if x[2] == 192]) == 1 def test_canfd_safety_modes(p): diff --git a/tests/hitl/9_harness.py b/tests/hitl/9_harness.py index 5689892b8a..b3544899be 100644 --- a/tests/hitl/9_harness.py +++ b/tests/hitl/9_harness.py @@ -51,7 +51,7 @@ def test_harness_status(p, panda_jungle): time.sleep(0.5) msgs = p.can_recv() - buses = {int(dat): bus for _, _, dat, bus in msgs if bus <= 3} + buses = {int(dat): bus for _, dat, bus in msgs if bus <= 3} print(msgs) # jungle doesn't actually switch buses when switching orientation diff --git a/tests/hitl/helpers.py b/tests/hitl/helpers.py index 4eee437311..d465671309 100644 --- a/tests/hitl/helpers.py +++ b/tests/hitl/helpers.py @@ -8,7 +8,7 @@ def get_random_can_messages(n): bus = random.randrange(3) addr = random.randrange(1 << 29) dat = bytes([random.getrandbits(8) for _ in range(random.randrange(1, 9))]) - m.append([addr, None, dat, bus]) + m.append([addr, dat, bus]) return m @@ -19,7 +19,7 @@ def time_many_sends(p, bus, p_recv=None, msg_count=100, two_pandas=False, msg_le raise ValueError("Cannot have two pandas that are the same panda") msg_id = random.randint(0x100, 0x200) - to_send = [(msg_id, 0, b"\xaa" * msg_len, bus)] * msg_count + to_send = [(msg_id, b"\xaa" * msg_len, bus)] * msg_count start_time = time.monotonic() p.can_send_many(to_send) @@ -35,11 +35,11 @@ def time_many_sends(p, bus, p_recv=None, msg_count=100, two_pandas=False, msg_le while len(r_echo) < r_echo_len_exected and (time.monotonic() - start_time) < 10: r_echo.extend(p.can_recv()) - sent_echo = [x for x in r if x[3] == 0x80 | bus and x[0] == msg_id] - sent_echo.extend([x for x in r_echo if x[3] == 0x80 | bus and x[0] == msg_id]) - resp = [x for x in r if x[3] == bus and x[0] == msg_id] + sent_echo = [x for x in r if x[2] == 0x80 | bus and x[0] == msg_id] + sent_echo.extend([x for x in r_echo if x[2] == 0x80 | bus and x[0] == msg_id]) + resp = [x for x in r if x[2] == bus and x[0] == msg_id] - leftovers = [x for x in r if (x[3] != 0x80 | bus and x[3] != bus) or x[0] != msg_id] + leftovers = [x for x in r if (x[2] != 0x80 | bus and x[2] != bus) or x[0] != msg_id] assert len(leftovers) == 0 assert len(resp) == msg_count diff --git a/tests/hitl/run_parallel_tests.sh b/tests/hitl/run_parallel_tests.sh index b6b79d99f6..f60d838c5b 100755 --- a/tests/hitl/run_parallel_tests.sh +++ b/tests/hitl/run_parallel_tests.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/tests/hitl/run_serial_tests.sh b/tests/hitl/run_serial_tests.sh index 31270f044c..4feae5e30c 100755 --- a/tests/hitl/run_serial_tests.sh +++ b/tests/hitl/run_serial_tests.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/tests/libpanda/safety_helpers.h b/tests/libpanda/safety_helpers.h index 36887c8963..ab4db4757c 100644 --- a/tests/libpanda/safety_helpers.h +++ b/tests/libpanda/safety_helpers.h @@ -47,6 +47,10 @@ bool get_gas_pressed_prev(void){ return gas_pressed_prev; } +void set_gas_pressed_prev(bool c){ + gas_pressed_prev = c; +} + bool get_brake_pressed_prev(void){ return brake_pressed_prev; } diff --git a/tests/libpanda/safety_helpers.py b/tests/libpanda/safety_helpers.py index ea41264ae0..6b510da6a8 100644 --- a/tests/libpanda/safety_helpers.py +++ b/tests/libpanda/safety_helpers.py @@ -11,6 +11,7 @@ def setup_safety_helpers(ffi): void set_relay_malfunction(bool c); bool get_relay_malfunction(void); bool get_gas_pressed_prev(void); + void set_gas_pressed_prev(bool); bool get_brake_pressed_prev(void); bool get_regen_braking_prev(void); bool get_acc_main_on(void); @@ -61,6 +62,7 @@ def get_alternative_experience(self) -> int: ... def set_relay_malfunction(self, c: bool) -> None: ... def get_relay_malfunction(self) -> bool: ... def get_gas_pressed_prev(self) -> bool: ... + def set_gas_pressed_prev(self, c: bool) -> None: ... def get_brake_pressed_prev(self) -> bool: ... def get_regen_braking_prev(self) -> bool: ... def get_acc_main_on(self) -> bool: ... diff --git a/tests/loopback_test.py b/tests/loopback_test.py index a95c2ea228..2b6eb53085 100755 --- a/tests/loopback_test.py +++ b/tests/loopback_test.py @@ -69,13 +69,13 @@ def run_test_w_pandas(pandas, sleep_duration): assert cans_echo[0][0] == at assert cans_loop[0][0] == at - assert cans_echo[0][2] == st - assert cans_loop[0][2] == st + assert cans_echo[0][1] == st + assert cans_loop[0][1] == st - assert cans_echo[0][3] == 0x80 | bus - if cans_loop[0][3] != bus: - print("EXPECTED %d GOT %d" % (bus, cans_loop[0][3])) - assert cans_loop[0][3] == bus + assert cans_echo[0][2] == 0x80 | bus + if cans_loop[0][2] != bus: + print("EXPECTED %d GOT %d" % (bus, cans_loop[0][2])) + assert cans_loop[0][2] == bus print("CAN pass", bus, ho) time.sleep(sleep_duration) diff --git a/tests/message_drop_test.py b/tests/message_drop_test.py index bf485e4545..a131a9c914 100755 --- a/tests/message_drop_test.py +++ b/tests/message_drop_test.py @@ -16,7 +16,7 @@ # Generate unique messages NUM_MESSAGES_PER_BUS = 10000 messages = [bytes(struct.pack("Q", i)) for i in range(NUM_MESSAGES_PER_BUS)] -tx_messages = list(itertools.chain.from_iterable([[0xaa, None, msg, 0], [0xaa, None, msg, 1], [0xaa, None, msg, 2]] for msg in messages)) +tx_messages = list(itertools.chain.from_iterable([[0xaa, msg, 0], [0xaa, msg, 1], [0xaa, msg, 2]] for msg in messages)) def flood_tx(panda): print('Sending!') @@ -65,6 +65,6 @@ def flood_tx(panda): # Check if we received everything for bus in range(3): - received_msgs = {bytes(m[2]) for m in filter(lambda m, b=bus: m[3] == b, rx)} # type: ignore + received_msgs = {bytes(m[1]) for m in filter(lambda m, b=bus: m[2] == b, rx)} # type: ignore dropped_msgs = set(messages).difference(received_msgs) print(f"Bus {bus} dropped msgs: {len(list(dropped_msgs))} / {len(messages)}") diff --git a/tests/misra/checkers.txt b/tests/misra/checkers.txt index 714bde0210..16489ca720 100644 --- a/tests/misra/checkers.txt +++ b/tests/misra/checkers.txt @@ -146,6 +146,7 @@ Yes CheckOther::clarifyCalculation Yes CheckOther::clarifyStatement Yes CheckOther::invalidPointerCast Yes CheckOther::redundantBitwiseOperationInSwitch +Yes CheckOther::suspiciousFloatingPointCast No CheckOther::warningOldStylePointerCast require:style,c++ No CheckPostfixOperator::postfixOperator require:performance Yes CheckSizeof::checkSizeofForArrayParameter @@ -193,7 +194,10 @@ Yes CheckType::checkSignConversion Yes CheckType::checkTooBigBitwiseShift Yes CheckUninitVar::check Yes CheckUninitVar::valueFlowUninit +<<<<<<< HEAD Yes CheckUnusedFunctions::check +======= +No CheckUnusedFunctions::check require:unusedFunction Yes CheckUnusedVar::checkFunctionVariableUsage Yes CheckUnusedVar::checkStructMemberUsage Yes CheckVaarg::va_list_usage @@ -222,11 +226,32 @@ Not available, Cppcheck Premium is not used Misra C 2012 ------------ +No Misra C 2012: Dir 1.1 +No Misra C 2012: Dir 2.1 +No Misra C 2012: Dir 3.1 +No Misra C 2012: Dir 4.1 +No Misra C 2012: Dir 4.2 +No Misra C 2012: Dir 4.3 +No Misra C 2012: Dir 4.4 +No Misra C 2012: Dir 4.5 +No Misra C 2012: Dir 4.6 amendment:3 +No Misra C 2012: Dir 4.7 +No Misra C 2012: Dir 4.8 +No Misra C 2012: Dir 4.9 amendment:3 +No Misra C 2012: Dir 4.10 +No Misra C 2012: Dir 4.11 amendment:3 +No Misra C 2012: Dir 4.12 +No Misra C 2012: Dir 4.13 +No Misra C 2012: Dir 4.14 amendment:2 +No Misra C 2012: Dir 4.15 amendment:3 +No Misra C 2012: Dir 5.1 amendment:4 +No Misra C 2012: Dir 5.2 amendment:4 +No Misra C 2012: Dir 5.3 amendment:4 Yes Misra C 2012: 1.1 Yes Misra C 2012: 1.2 Yes Misra C 2012: 1.3 -Yes Misra C 2012: 1.4 amendment:2 -No Misra C 2012: 1.5 amendment:3 require:premium +Yes Misra C 2012: 1.4 amendment:2 +No Misra C 2012: 1.5 amendment:3 require:premium Yes Misra C 2012: 2.1 Yes Misra C 2012: 2.2 Yes Misra C 2012: 2.3 @@ -303,8 +328,8 @@ Yes Misra C 2012: 12.1 Yes Misra C 2012: 12.2 Yes Misra C 2012: 12.3 Yes Misra C 2012: 12.4 -Yes Misra C 2012: 12.5 amendment:1 -No Misra C 2012: 12.6 amendment:4 require:premium +Yes Misra C 2012: 12.5 amendment:1 +No Misra C 2012: 12.6 amendment:4 require:premium Yes Misra C 2012: 13.1 No Misra C 2012: 13.2 Yes Misra C 2012: 13.3 @@ -380,48 +405,504 @@ Yes Misra C 2012: 21.9 Yes Misra C 2012: 21.10 Yes Misra C 2012: 21.11 Yes Misra C 2012: 21.12 -Yes Misra C 2012: 21.13 amendment:1 -Yes Misra C 2012: 21.14 amendment:1 -Yes Misra C 2012: 21.15 amendment:1 -Yes Misra C 2012: 21.16 amendment:1 -Yes Misra C 2012: 21.17 amendment:1 -Yes Misra C 2012: 21.18 amendment:1 -Yes Misra C 2012: 21.19 amendment:1 -Yes Misra C 2012: 21.20 amendment:1 -Yes Misra C 2012: 21.21 amendment:3 -No Misra C 2012: 21.22 amendment:3 require:premium -No Misra C 2012: 21.23 amendment:3 require:premium -No Misra C 2012: 21.24 amendment:3 require:premium -No Misra C 2012: 21.25 amendment:4 require:premium -No Misra C 2012: 21.26 amendment:4 require:premium +Yes Misra C 2012: 21.13 amendment:1 +Yes Misra C 2012: 21.14 amendment:1 +Yes Misra C 2012: 21.15 amendment:1 +Yes Misra C 2012: 21.16 amendment:1 +Yes Misra C 2012: 21.17 amendment:1 +Yes Misra C 2012: 21.18 amendment:1 +Yes Misra C 2012: 21.19 amendment:1 +Yes Misra C 2012: 21.20 amendment:1 +Yes Misra C 2012: 21.21 amendment:3 +No Misra C 2012: 21.22 amendment:3 require:premium +No Misra C 2012: 21.23 amendment:3 require:premium +No Misra C 2012: 21.24 amendment:3 require:premium +No Misra C 2012: 21.25 amendment:4 require:premium +No Misra C 2012: 21.26 amendment:4 require:premium Yes Misra C 2012: 22.1 Yes Misra C 2012: 22.2 Yes Misra C 2012: 22.3 Yes Misra C 2012: 22.4 Yes Misra C 2012: 22.5 Yes Misra C 2012: 22.6 -Yes Misra C 2012: 22.7 amendment:1 -Yes Misra C 2012: 22.8 amendment:1 -Yes Misra C 2012: 22.9 amendment:1 -Yes Misra C 2012: 22.10 amendment:1 -No Misra C 2012: 22.11 amendment:4 require:premium -No Misra C 2012: 22.12 amendment:4 require:premium -No Misra C 2012: 22.13 amendment:4 require:premium -No Misra C 2012: 22.14 amendment:4 require:premium -No Misra C 2012: 22.15 amendment:4 require:premium -No Misra C 2012: 22.16 amendment:4 require:premium -No Misra C 2012: 22.17 amendment:4 require:premium -No Misra C 2012: 22.18 amendment:4 require:premium -No Misra C 2012: 22.19 amendment:4 require:premium -No Misra C 2012: 22.20 amendment:4 require:premium -No Misra C 2012: 23.1 amendment:3 require:premium -No Misra C 2012: 23.2 amendment:3 require:premium -No Misra C 2012: 23.3 amendment:3 require:premium -No Misra C 2012: 23.4 amendment:3 require:premium -No Misra C 2012: 23.5 amendment:3 require:premium -No Misra C 2012: 23.6 amendment:3 require:premium -No Misra C 2012: 23.7 amendment:3 require:premium -No Misra C 2012: 23.8 amendment:3 require:premium +Yes Misra C 2012: 22.7 amendment:1 +Yes Misra C 2012: 22.8 amendment:1 +Yes Misra C 2012: 22.9 amendment:1 +Yes Misra C 2012: 22.10 amendment:1 +No Misra C 2012: 22.11 amendment:4 require:premium +No Misra C 2012: 22.12 amendment:4 require:premium +No Misra C 2012: 22.13 amendment:4 require:premium +No Misra C 2012: 22.14 amendment:4 require:premium +No Misra C 2012: 22.15 amendment:4 require:premium +No Misra C 2012: 22.16 amendment:4 require:premium +No Misra C 2012: 22.17 amendment:4 require:premium +No Misra C 2012: 22.18 amendment:4 require:premium +No Misra C 2012: 22.19 amendment:4 require:premium +No Misra C 2012: 22.20 amendment:4 require:premium +No Misra C 2012: 23.1 amendment:3 require:premium +No Misra C 2012: 23.2 amendment:3 require:premium +No Misra C 2012: 23.3 amendment:3 require:premium +No Misra C 2012: 23.4 amendment:3 require:premium +No Misra C 2012: 23.5 amendment:3 require:premium +No Misra C 2012: 23.6 amendment:3 require:premium +No Misra C 2012: 23.7 amendment:3 require:premium +No Misra C 2012: 23.8 amendment:3 require:premium + + +Misra C++ 2008 +-------------- +Not available, Cppcheck Premium is not used + + +Misra C++ 2023 +-------------- +Not available, Cppcheck Premium is not used + + + + + +TEST variant options: +--enable=all --disable=unusedFunction -DPANDA --addon=misra -DSTM32H7 -DSTM32H725xx /board/main.c + + +Critical errors +--------------- +No critical errors, all files were checked. +Important: Analysis is still not guaranteed to be 'complete' it is possible there are false negatives. + + +Open source checkers +-------------------- +Yes Check64BitPortability::pointerassignment +Yes CheckAssert::assertWithSideEffects +Yes CheckAutoVariables::assignFunctionArg +Yes CheckAutoVariables::autoVariables +Yes CheckAutoVariables::checkVarLifetime +No CheckBool::checkAssignBoolToFloat require:style,c++ +Yes CheckBool::checkAssignBoolToPointer +No CheckBool::checkBitwiseOnBoolean require:style,inconclusive +Yes CheckBool::checkComparisonOfBoolExpressionWithInt +No CheckBool::checkComparisonOfBoolWithBool require:style,c++ +No CheckBool::checkComparisonOfBoolWithInt require:warning,c++ +No CheckBool::checkComparisonOfFuncReturningBool require:style,c++ +Yes CheckBool::checkIncrementBoolean +Yes CheckBool::pointerArithBool +Yes CheckBool::returnValueOfFunctionReturningBool +No CheckBoost::checkBoostForeachModification +Yes CheckBufferOverrun::analyseWholeProgram +Yes CheckBufferOverrun::argumentSize +Yes CheckBufferOverrun::arrayIndex +Yes CheckBufferOverrun::arrayIndexThenCheck +Yes CheckBufferOverrun::bufferOverflow +Yes CheckBufferOverrun::negativeArraySize +Yes CheckBufferOverrun::objectIndex +Yes CheckBufferOverrun::pointerArithmetic +No CheckBufferOverrun::stringNotZeroTerminated require:warning,inconclusive +Yes CheckClass::analyseWholeProgram +No CheckClass::checkConst require:style,inconclusive +No CheckClass::checkConstructors require:style,warning +No CheckClass::checkCopyConstructors require:warning +No CheckClass::checkDuplInheritedMembers require:warning +No CheckClass::checkExplicitConstructors require:style +No CheckClass::checkMemset +No CheckClass::checkMissingOverride require:style,c++03 +No CheckClass::checkReturnByReference require:performance +No CheckClass::checkSelfInitialization +No CheckClass::checkThisUseAfterFree require:warning +No CheckClass::checkUnsafeClassRefMember require:warning,safeChecks +No CheckClass::checkUselessOverride require:style +No CheckClass::checkVirtualFunctionCallInConstructor require:warning +No CheckClass::initializationListUsage require:performance +No CheckClass::initializerListOrder require:style,inconclusive +No CheckClass::operatorEqRetRefThis require:style +No CheckClass::operatorEqToSelf require:warning +No CheckClass::privateFunctions require:style +No CheckClass::thisSubtraction require:warning +No CheckClass::virtualDestructor +Yes CheckCondition::alwaysTrueFalse +Yes CheckCondition::assignIf +Yes CheckCondition::checkAssignmentInCondition +Yes CheckCondition::checkBadBitmaskCheck +Yes CheckCondition::checkCompareValueOutOfTypeRange +Yes CheckCondition::checkDuplicateConditionalAssign +Yes CheckCondition::checkIncorrectLogicOperator +Yes CheckCondition::checkInvalidTestForOverflow +Yes CheckCondition::checkModuloAlwaysTrueFalse +Yes CheckCondition::checkPointerAdditionResultNotNull +Yes CheckCondition::clarifyCondition +Yes CheckCondition::comparison +Yes CheckCondition::duplicateCondition +Yes CheckCondition::multiCondition +Yes CheckCondition::multiCondition2 +No CheckExceptionSafety::checkCatchExceptionByValue require:style +No CheckExceptionSafety::checkRethrowCopy require:style +No CheckExceptionSafety::deallocThrow require:warning +No CheckExceptionSafety::destructors require:warning +No CheckExceptionSafety::nothrowThrows +No CheckExceptionSafety::rethrowNoCurrentException +No CheckExceptionSafety::unhandledExceptionSpecification require:style,inconclusive +Yes CheckFunctions::checkIgnoredReturnValue +Yes CheckFunctions::checkMathFunctions +Yes CheckFunctions::checkMissingReturn +Yes CheckFunctions::checkProhibitedFunctions +Yes CheckFunctions::invalidFunctionUsage +Yes CheckFunctions::memsetInvalid2ndParam +Yes CheckFunctions::memsetZeroBytes +No CheckFunctions::returnLocalStdMove require:performance,c++11 +Yes CheckFunctions::useStandardLibrary +No CheckIO::checkCoutCerrMisusage require:c +Yes CheckIO::checkFileUsage +Yes CheckIO::checkWrongPrintfScanfArguments +Yes CheckIO::invalidScanf +Yes CheckLeakAutoVar::check +No CheckMemoryLeakInClass::check +Yes CheckMemoryLeakInFunction::checkReallocUsage +Yes CheckMemoryLeakNoVar::check +No CheckMemoryLeakNoVar::checkForUnsafeArgAlloc +Yes CheckMemoryLeakStructMember::check +Yes CheckNullPointer::analyseWholeProgram +Yes CheckNullPointer::arithmetic +Yes CheckNullPointer::nullConstantDereference +Yes CheckNullPointer::nullPointer +No CheckOther::checkAccessOfMovedVariable require:c++11,warning +Yes CheckOther::checkCastIntToCharAndBack +Yes CheckOther::checkCharVariable +Yes CheckOther::checkComparePointers +Yes CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalse +Yes CheckOther::checkConstPointer +No CheckOther::checkConstVariable require:style,c++ +No CheckOther::checkDuplicateBranch require:style,inconclusive +Yes CheckOther::checkDuplicateExpression +Yes CheckOther::checkEvaluationOrder +Yes CheckOther::checkFuncArgNamesDifferent +No CheckOther::checkIncompleteArrayFill require:warning,portability,inconclusive +Yes CheckOther::checkIncompleteStatement +No CheckOther::checkInterlockedDecrement require:windows-platform +Yes CheckOther::checkInvalidFree +Yes CheckOther::checkKnownArgument +Yes CheckOther::checkKnownPointerToBool +No CheckOther::checkMisusedScopedObject require:style,c++ +Yes CheckOther::checkModuloOfOne +Yes CheckOther::checkNanInArithmeticExpression +Yes CheckOther::checkNegativeBitwiseShift +Yes CheckOther::checkOverlappingWrite +No CheckOther::checkPassByReference require:performance,c++ +Yes CheckOther::checkRedundantAssignment +No CheckOther::checkRedundantCopy require:c++,performance,inconclusive +Yes CheckOther::checkRedundantPointerOp +Yes CheckOther::checkShadowVariables +Yes CheckOther::checkSignOfUnsignedVariable +No CheckOther::checkSuspiciousCaseInSwitch require:warning,inconclusive +No CheckOther::checkSuspiciousSemicolon require:warning,inconclusive +Yes CheckOther::checkUnreachableCode +Yes CheckOther::checkUnusedLabel +Yes CheckOther::checkVarFuncNullUB +Yes CheckOther::checkVariableScope +Yes CheckOther::checkZeroDivision +Yes CheckOther::clarifyCalculation +Yes CheckOther::clarifyStatement +Yes CheckOther::invalidPointerCast +Yes CheckOther::redundantBitwiseOperationInSwitch +Yes CheckOther::suspiciousFloatingPointCast +No CheckOther::warningOldStylePointerCast require:style,c++ +No CheckPostfixOperator::postfixOperator require:performance +Yes CheckSizeof::checkSizeofForArrayParameter +Yes CheckSizeof::checkSizeofForNumericParameter +Yes CheckSizeof::checkSizeofForPointerSize +Yes CheckSizeof::sizeofCalculation +Yes CheckSizeof::sizeofFunction +Yes CheckSizeof::sizeofVoid +Yes CheckSizeof::sizeofsizeof +No CheckSizeof::suspiciousSizeofCalculation require:warning,inconclusive +No CheckStl::checkDereferenceInvalidIterator require:warning +No CheckStl::checkDereferenceInvalidIterator2 +No CheckStl::checkFindInsert require:performance +No CheckStl::checkMutexes require:warning +No CheckStl::erase +No CheckStl::eraseIteratorOutOfBounds +No CheckStl::if_find require:warning,performance +No CheckStl::invalidContainer +No CheckStl::iterators +No CheckStl::knownEmptyContainer require:style +No CheckStl::misMatchingContainerIterator +No CheckStl::misMatchingContainers +No CheckStl::missingComparison require:warning +No CheckStl::negativeIndex +No CheckStl::outOfBounds +No CheckStl::outOfBoundsIndexExpression +No CheckStl::redundantCondition require:style +No CheckStl::size require:performance,c++03 +No CheckStl::stlBoundaries +No CheckStl::stlOutOfBounds +No CheckStl::string_c_str +No CheckStl::useStlAlgorithm require:style +No CheckStl::uselessCalls require:performance,warning +Yes CheckString::checkAlwaysTrueOrFalseStringCompare +Yes CheckString::checkIncorrectStringCompare +Yes CheckString::checkSuspiciousStringCompare +Yes CheckString::overlappingStrcmp +Yes CheckString::sprintfOverlappingData +Yes CheckString::strPlusChar +Yes CheckString::stringLiteralWrite +Yes CheckType::checkFloatToIntegerOverflow +Yes CheckType::checkIntegerOverflow +Yes CheckType::checkLongCast +Yes CheckType::checkSignConversion +Yes CheckType::checkTooBigBitwiseShift +Yes CheckUninitVar::check +Yes CheckUninitVar::valueFlowUninit +No CheckUnusedFunctions::check require:unusedFunction +>>>>>>> 8545c68e4d51eab55803c9c28cdf8bb7bfaa261e +Yes CheckUnusedVar::checkFunctionVariableUsage +Yes CheckUnusedVar::checkStructMemberUsage +Yes CheckVaarg::va_list_usage +Yes CheckVaarg::va_start_argument + + +Premium checkers +---------------- +Not available, Cppcheck Premium is not used + + +Autosar +------- +Not available, Cppcheck Premium is not used + + +Cert C +------ +Not available, Cppcheck Premium is not used + + +Cert C++ +-------- +Not available, Cppcheck Premium is not used + + +Misra C 2012 +------------ +No Misra C 2012: Dir 1.1 +No Misra C 2012: Dir 2.1 +No Misra C 2012: Dir 3.1 +No Misra C 2012: Dir 4.1 +No Misra C 2012: Dir 4.2 +No Misra C 2012: Dir 4.3 +No Misra C 2012: Dir 4.4 +No Misra C 2012: Dir 4.5 +No Misra C 2012: Dir 4.6 amendment:3 +No Misra C 2012: Dir 4.7 +No Misra C 2012: Dir 4.8 +No Misra C 2012: Dir 4.9 amendment:3 +No Misra C 2012: Dir 4.10 +No Misra C 2012: Dir 4.11 amendment:3 +No Misra C 2012: Dir 4.12 +No Misra C 2012: Dir 4.13 +No Misra C 2012: Dir 4.14 amendment:2 +No Misra C 2012: Dir 4.15 amendment:3 +No Misra C 2012: Dir 5.1 amendment:4 +No Misra C 2012: Dir 5.2 amendment:4 +No Misra C 2012: Dir 5.3 amendment:4 +Yes Misra C 2012: 1.1 +Yes Misra C 2012: 1.2 +Yes Misra C 2012: 1.3 +Yes Misra C 2012: 1.4 amendment:2 +No Misra C 2012: 1.5 amendment:3 require:premium +Yes Misra C 2012: 2.1 +Yes Misra C 2012: 2.2 +Yes Misra C 2012: 2.3 +Yes Misra C 2012: 2.4 +Yes Misra C 2012: 2.5 +Yes Misra C 2012: 2.6 +Yes Misra C 2012: 2.7 +Yes Misra C 2012: 2.8 +Yes Misra C 2012: 3.1 +Yes Misra C 2012: 3.2 +Yes Misra C 2012: 4.1 +Yes Misra C 2012: 4.2 +Yes Misra C 2012: 5.1 +Yes Misra C 2012: 5.2 +Yes Misra C 2012: 5.3 +Yes Misra C 2012: 5.4 +Yes Misra C 2012: 5.5 +Yes Misra C 2012: 5.6 +Yes Misra C 2012: 5.7 +Yes Misra C 2012: 5.8 +Yes Misra C 2012: 5.9 +Yes Misra C 2012: 6.1 +Yes Misra C 2012: 6.2 +No Misra C 2012: 6.3 +Yes Misra C 2012: 7.1 +Yes Misra C 2012: 7.2 +Yes Misra C 2012: 7.3 +Yes Misra C 2012: 7.4 +No Misra C 2012: 7.5 +No Misra C 2012: 7.6 +Yes Misra C 2012: 8.1 +Yes Misra C 2012: 8.2 +No Misra C 2012: 8.3 +Yes Misra C 2012: 8.4 +Yes Misra C 2012: 8.5 +Yes Misra C 2012: 8.6 +Yes Misra C 2012: 8.7 +Yes Misra C 2012: 8.8 +Yes Misra C 2012: 8.9 +Yes Misra C 2012: 8.10 +Yes Misra C 2012: 8.11 +Yes Misra C 2012: 8.12 +Yes Misra C 2012: 8.13 +Yes Misra C 2012: 8.14 +No Misra C 2012: 8.15 +No Misra C 2012: 8.16 +No Misra C 2012: 8.17 +Yes Misra C 2012: 9.1 +Yes Misra C 2012: 9.2 +Yes Misra C 2012: 9.3 +Yes Misra C 2012: 9.4 +Yes Misra C 2012: 9.5 +No Misra C 2012: 9.6 +No Misra C 2012: 9.7 +Yes Misra C 2012: 10.1 +Yes Misra C 2012: 10.2 +Yes Misra C 2012: 10.3 +Yes Misra C 2012: 10.4 +Yes Misra C 2012: 10.5 +Yes Misra C 2012: 10.6 +Yes Misra C 2012: 10.7 +Yes Misra C 2012: 10.8 +Yes Misra C 2012: 11.1 +Yes Misra C 2012: 11.2 +Yes Misra C 2012: 11.3 +Yes Misra C 2012: 11.4 +Yes Misra C 2012: 11.5 +Yes Misra C 2012: 11.6 +Yes Misra C 2012: 11.7 +Yes Misra C 2012: 11.8 +Yes Misra C 2012: 11.9 +No Misra C 2012: 11.10 +Yes Misra C 2012: 12.1 +Yes Misra C 2012: 12.2 +Yes Misra C 2012: 12.3 +Yes Misra C 2012: 12.4 +Yes Misra C 2012: 12.5 amendment:1 +No Misra C 2012: 12.6 amendment:4 require:premium +Yes Misra C 2012: 13.1 +No Misra C 2012: 13.2 +Yes Misra C 2012: 13.3 +Yes Misra C 2012: 13.4 +Yes Misra C 2012: 13.5 +Yes Misra C 2012: 13.6 +Yes Misra C 2012: 14.1 +Yes Misra C 2012: 14.2 +Yes Misra C 2012: 14.3 +Yes Misra C 2012: 14.4 +Yes Misra C 2012: 15.1 +Yes Misra C 2012: 15.2 +Yes Misra C 2012: 15.3 +Yes Misra C 2012: 15.4 +Yes Misra C 2012: 15.5 +Yes Misra C 2012: 15.6 +Yes Misra C 2012: 15.7 +Yes Misra C 2012: 16.1 +Yes Misra C 2012: 16.2 +Yes Misra C 2012: 16.3 +Yes Misra C 2012: 16.4 +Yes Misra C 2012: 16.5 +Yes Misra C 2012: 16.6 +Yes Misra C 2012: 16.7 +Yes Misra C 2012: 17.1 +Yes Misra C 2012: 17.2 +Yes Misra C 2012: 17.3 +No Misra C 2012: 17.4 +Yes Misra C 2012: 17.5 +Yes Misra C 2012: 17.6 +Yes Misra C 2012: 17.7 +Yes Misra C 2012: 17.8 +No Misra C 2012: 17.9 +No Misra C 2012: 17.10 +No Misra C 2012: 17.11 +No Misra C 2012: 17.12 +No Misra C 2012: 17.13 +Yes Misra C 2012: 18.1 +Yes Misra C 2012: 18.2 +Yes Misra C 2012: 18.3 +Yes Misra C 2012: 18.4 +Yes Misra C 2012: 18.5 +Yes Misra C 2012: 18.6 +Yes Misra C 2012: 18.7 +Yes Misra C 2012: 18.8 +No Misra C 2012: 18.9 +No Misra C 2012: 18.10 +Yes Misra C 2012: 19.1 +Yes Misra C 2012: 19.2 +Yes Misra C 2012: 20.1 +Yes Misra C 2012: 20.2 +Yes Misra C 2012: 20.3 +Yes Misra C 2012: 20.4 +Yes Misra C 2012: 20.5 +Yes Misra C 2012: 20.6 +Yes Misra C 2012: 20.7 +Yes Misra C 2012: 20.8 +Yes Misra C 2012: 20.9 +Yes Misra C 2012: 20.10 +Yes Misra C 2012: 20.11 +Yes Misra C 2012: 20.12 +Yes Misra C 2012: 20.13 +Yes Misra C 2012: 20.14 +Yes Misra C 2012: 21.1 +Yes Misra C 2012: 21.2 +Yes Misra C 2012: 21.3 +Yes Misra C 2012: 21.4 +Yes Misra C 2012: 21.5 +Yes Misra C 2012: 21.6 +Yes Misra C 2012: 21.7 +Yes Misra C 2012: 21.8 +Yes Misra C 2012: 21.9 +Yes Misra C 2012: 21.10 +Yes Misra C 2012: 21.11 +Yes Misra C 2012: 21.12 +Yes Misra C 2012: 21.13 amendment:1 +Yes Misra C 2012: 21.14 amendment:1 +Yes Misra C 2012: 21.15 amendment:1 +Yes Misra C 2012: 21.16 amendment:1 +Yes Misra C 2012: 21.17 amendment:1 +Yes Misra C 2012: 21.18 amendment:1 +Yes Misra C 2012: 21.19 amendment:1 +Yes Misra C 2012: 21.20 amendment:1 +Yes Misra C 2012: 21.21 amendment:3 +No Misra C 2012: 21.22 amendment:3 require:premium +No Misra C 2012: 21.23 amendment:3 require:premium +No Misra C 2012: 21.24 amendment:3 require:premium +No Misra C 2012: 21.25 amendment:4 require:premium +No Misra C 2012: 21.26 amendment:4 require:premium +Yes Misra C 2012: 22.1 +Yes Misra C 2012: 22.2 +Yes Misra C 2012: 22.3 +Yes Misra C 2012: 22.4 +Yes Misra C 2012: 22.5 +Yes Misra C 2012: 22.6 +Yes Misra C 2012: 22.7 amendment:1 +Yes Misra C 2012: 22.8 amendment:1 +Yes Misra C 2012: 22.9 amendment:1 +Yes Misra C 2012: 22.10 amendment:1 +No Misra C 2012: 22.11 amendment:4 require:premium +No Misra C 2012: 22.12 amendment:4 require:premium +No Misra C 2012: 22.13 amendment:4 require:premium +No Misra C 2012: 22.14 amendment:4 require:premium +No Misra C 2012: 22.15 amendment:4 require:premium +No Misra C 2012: 22.16 amendment:4 require:premium +No Misra C 2012: 22.17 amendment:4 require:premium +No Misra C 2012: 22.18 amendment:4 require:premium +No Misra C 2012: 22.19 amendment:4 require:premium +No Misra C 2012: 22.20 amendment:4 require:premium +No Misra C 2012: 23.1 amendment:3 require:premium +No Misra C 2012: 23.2 amendment:3 require:premium +No Misra C 2012: 23.3 amendment:3 require:premium +No Misra C 2012: 23.4 amendment:3 require:premium +No Misra C 2012: 23.5 amendment:3 require:premium +No Misra C 2012: 23.6 amendment:3 require:premium +No Misra C 2012: 23.7 amendment:3 require:premium +No Misra C 2012: 23.8 amendment:3 require:premium Misra C++ 2008 diff --git a/tests/misra/install.sh b/tests/misra/install.sh index e0a743b72e..c1fdbe8383 100755 --- a/tests/misra/install.sh +++ b/tests/misra/install.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" @@ -10,7 +10,7 @@ fi cd $CPPCHECK_DIR -VERS="2.14.1" +VERS="2.15.0" git fetch --all --tags --force git checkout $VERS diff --git a/tests/misra/test_misra.sh b/tests/misra/test_misra.sh index e930fa41aa..5f713bfa6f 100755 --- a/tests/misra/test_misra.sh +++ b/tests/misra/test_misra.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" @@ -19,7 +19,7 @@ fi # ensure checked in coverage table is up to date cd $DIR if [ -z "$SKIP_TABLES_DIFF" ]; then - python $CPPCHECK_DIR/addons/misra.py -generate-table > coverage_table + python3 $CPPCHECK_DIR/addons/misra.py -generate-table > coverage_table if ! git diff --quiet coverage_table; then echo -e "${YELLOW}MISRA coverage table doesn't match. Update and commit:${NC}" exit 3 @@ -47,10 +47,10 @@ cppcheck() { $CPPCHECK_DIR/cppcheck --inline-suppr -I $PANDA_DIR/board/ \ --library=gnu.cfg --suppress=missingIncludeSystem \ --suppressions-list=$DIR/suppressions.txt --suppress=*:*inc/* \ - --error-exitcode=2 --check-level=exhaustive \ + --error-exitcode=2 --check-level=exhaustive --safety \ --platform=arm32-wchar_t4 $COMMON_DEFINES --checkers-report=$CHECKLIST.tmp \ --std=c11 "$@" |& tee $OUTPUT - + cat $CHECKLIST.tmp >> $CHECKLIST rm $CHECKLIST.tmp # cppcheck bug: some MISRA errors won't result in the error exit code, diff --git a/tests/read_st_flash.sh b/tests/read_st_flash.sh index ffcfd7bbfe..65b0709f6c 100755 --- a/tests/read_st_flash.sh +++ b/tests/read_st_flash.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash rm -f /tmp/dump_bootstub rm -f /tmp/dump_main dfu-util -a 0 -s 0x08000000 -U /tmp/dump_bootstub diff --git a/tests/safety/common.py b/tests/safety/common.py index e111ff7eff..884f21a360 100644 --- a/tests/safety/common.py +++ b/tests/safety/common.py @@ -30,7 +30,7 @@ def make_can_msg_panda(self, name_or_addr, bus, values, fix_checksum=None): msg = self.make_can_msg(name_or_addr, bus, values) if fix_checksum is not None: msg = fix_checksum(msg) - addr, _, dat, bus = msg + addr, dat, bus = msg return libpanda_py.make_CANPacket(addr, bus, dat) diff --git a/tests/safety/test_ford.py b/tests/safety/test_ford.py index 1be3a273cc..710462ae95 100755 --- a/tests/safety/test_ford.py +++ b/tests/safety/test_ford.py @@ -24,7 +24,7 @@ def checksum(msg): - addr, t, dat, bus = msg + addr, dat, bus = msg ret = bytearray(dat) if addr == MSG_Yaw_Data_FD1: @@ -50,7 +50,7 @@ def checksum(msg): chksum = 0xff - (chksum & 0xff) ret[1] = chksum - return addr, t, ret, bus + return addr, ret, bus class Buttons: diff --git a/tests/safety/test_hyundai.py b/tests/safety/test_hyundai.py index fbe7d1032f..1bff99fa75 100755 --- a/tests/safety/test_hyundai.py +++ b/tests/safety/test_hyundai.py @@ -11,7 +11,7 @@ # 4 bit checkusm used in some hyundai messages # lives outside the can packer because we never send this msg def checksum(msg): - addr, t, dat, bus = msg + addr, dat, bus = msg chksum = 0 if addr == 0x386: @@ -40,7 +40,7 @@ def checksum(msg): ret = bytearray(dat) ret[6 if addr == 0x394 else 7] |= chksum << (4 if addr == 0x421 else 0) - return addr, t, ret, bus + return addr, ret, bus class TestHyundaiSafety(HyundaiButtonBase, common.PandaCarSafetyTest, common.DriverTorqueSteeringSafetyTest, common.SteerRequestCutSafetyTest): diff --git a/tests/setup_device_ci.sh b/tests/setup_device_ci.sh index b45c6b466b..a74ce7a2c9 100755 --- a/tests/setup_device_ci.sh +++ b/tests/setup_device_ci.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash set -e @@ -19,7 +19,7 @@ fi CONTINUE_PATH="/data/continue.sh" tee $CONTINUE_PATH << EOF -#!/usr/bin/bash +#!/usr/bin/env bash sudo abctl --set_success diff --git a/tests/som_debug.sh b/tests/som_debug.sh index 9bb4219713..6f0a86537c 100755 --- a/tests/som_debug.sh +++ b/tests/som_debug.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/tests/usbprotocol/test.sh b/tests/usbprotocol/test.sh index 8e3886da7d..b4c32166b9 100755 --- a/tests/usbprotocol/test.sh +++ b/tests/usbprotocol/test.sh @@ -4,5 +4,5 @@ set -e # Loops over all HW_TYPEs, see board/boards/board_declarations.h for hw_type in {0..7}; do echo "Testing HW_TYPE: $hw_type" - HW_TYPE=$hw_type python -m unittest discover . + HW_TYPE=$hw_type python3 -m unittest discover . done diff --git a/tests/usbprotocol/test_comms.py b/tests/usbprotocol/test_comms.py index 8efefef7ca..e649bdaeab 100755 --- a/tests/usbprotocol/test_comms.py +++ b/tests/usbprotocol/test_comms.py @@ -14,7 +14,7 @@ def unpackage_can_msg(pkt): dat_len = DLC_TO_LEN[pkt[0].data_len_code] dat = bytes(pkt[0].data[0:dat_len]) - return pkt[0].addr, 0, dat, pkt[0].bus + return pkt[0].addr, dat, pkt[0].bus def random_can_messages(n, bus=None): @@ -24,7 +24,7 @@ def random_can_messages(n, bus=None): bus = random.randint(0, 3) address = random.randint(1, (1 << 29) - 1) data = bytes([random.getrandbits(8) for _ in range(DLC_TO_LEN[random.randrange(0, len(DLC_TO_LEN))])]) - msgs.append((address, 0, data, bus)) + msgs.append((address, data, bus)) return msgs @@ -34,9 +34,9 @@ def setUp(self): def test_tx_queues(self): for bus in range(len(TX_QUEUES)): - message = (0x100, 0, b"test", bus) + message = (0x100, b"test", bus) - can_pkt_tx = libpanda_py.make_CANPacket(message[0], message[3], message[2]) + can_pkt_tx = libpanda_py.make_CANPacket(message[0], message[2], message[1]) can_pkt_rx = libpanda_py.ffi.new('CANPacket_t *') assert lpp.can_push(TX_QUEUES[bus], can_pkt_tx), "CAN push failed" @@ -46,9 +46,9 @@ def test_tx_queues(self): def test_comms_reset_rx(self): # store some test messages in the queue - test_msg = (0x100, 0, b"test", 0) + test_msg = (0x100, b"test", 0) for _ in range(100): - can_pkt_tx = libpanda_py.make_CANPacket(test_msg[0], test_msg[3], test_msg[2]) + can_pkt_tx = libpanda_py.make_CANPacket(test_msg[0], test_msg[2], test_msg[1]) lpp.can_push(lpp.rx_q, can_pkt_tx) # read a small chunk such that we have some overflow @@ -76,7 +76,7 @@ def test_comms_reset_rx(self): def test_comms_reset_tx(self): # store some test messages in the queue - test_msg = (0x100, 0, b"test", 0) + test_msg = (0x100, b"test", 0) packed = pack_can_buffer([test_msg for _ in range(100)]) # write a small chunk such that we have some overflow @@ -126,7 +126,7 @@ def test_can_send_usb(self): def test_can_receive_usb(self): msgs = random_can_messages(50000) - packets = [libpanda_py.make_CANPacket(m[0], m[3], m[2]) for m in msgs] + packets = [libpanda_py.make_CANPacket(m[0], m[2], m[1]) for m in msgs] rx_msgs = [] overflow_buf = b"" diff --git a/tests/usbprotocol/test_pandalib.py b/tests/usbprotocol/test_pandalib.py index c03f246f31..ef725948c7 100755 --- a/tests/usbprotocol/test_pandalib.py +++ b/tests/usbprotocol/test_pandalib.py @@ -12,7 +12,7 @@ def test_panda_lib_pack_unpack(self): for _ in range(10000): address = random.randint(1, (1 << 29) - 1) data = bytes([random.getrandbits(8) for _ in range(DLC_TO_LEN[random.randrange(0, len(DLC_TO_LEN))])]) - to_pack.append((address, 0, data, 0)) + to_pack.append((address, data, 0)) packed = pack_can_buffer(to_pack) unpacked = [] From da75bfaf6b0fb24630a5518498a01d80d33930ce Mon Sep 17 00:00:00 2001 From: dzid26 Date: Sun, 22 Sep 2024 15:58:14 -0700 Subject: [PATCH 12/13] constParameterPointer --- board/safety.h | 2 +- board/safety_declarations.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/board/safety.h b/board/safety.h index 048d7cca48..b0a09a7dcb 100644 --- a/board/safety.h +++ b/board/safety.h @@ -428,7 +428,7 @@ bool max_limit_check(int val, const int MAX_VAL, const int MIN_VAL) { } // check that commanded torque value isn't too far from measured -bool dist_to_meas_check(int val, int val_last, struct sample_t *val_meas, +bool dist_to_meas_check(int val, int val_last, const struct sample_t *val_meas, const int MAX_RATE_UP, const int MAX_RATE_DOWN, const int MAX_ERROR) { // *** val rate limit check *** diff --git a/board/safety_declarations.h b/board/safety_declarations.h index 428107d6bb..f84788ea99 100644 --- a/board/safety_declarations.h +++ b/board/safety_declarations.h @@ -32,7 +32,7 @@ const uint8_t MAX_MISSED_MSGS = 10U; // sample struct that keeps 6 samples in memory -struct sample_t { +const struct sample_t { int values[MAX_SAMPLE_VALS]; int min; int max; @@ -176,7 +176,7 @@ void reset_sample(struct sample_t *sample); bool max_limit_check(int val, const int MAX, const int MIN); bool angle_dist_to_meas_check(int val, struct sample_t *val_meas, const int MAX_ERROR, const int MAX_VAL); -bool dist_to_meas_check(int val, int val_last, struct sample_t *val_meas, +bool dist_to_meas_check(int val, int val_last, const struct sample_t *val_meas, const int MAX_RATE_UP, const int MAX_RATE_DOWN, const int MAX_ERROR); bool driver_limit_check(int val, int val_last, const struct sample_t *val_driver, const int MAX, const int MAX_RATE_UP, const int MAX_RATE_DOWN, From 0c67cebff83a06c7388264736942bf9a5aa1ec3b Mon Sep 17 00:00:00 2001 From: dzid26 Date: Sun, 22 Sep 2024 19:43:13 -0700 Subject: [PATCH 13/13] cppcheck with --project CI: test misra with RELEASE=1 Generates compile db without ALLOW_DEBUG --- .github/workflows/test.yaml | 5 +- .gitignore | 1 + SConscript | 4 +- SConstruct | 6 + tests/misra/checkers.txt | 461 +------------------------------ tests/misra/panda_macro_config.h | 5 +- tests/misra/suppressions.txt | 2 +- tests/misra/test_misra.sh | 24 +- tests/misra/test_mutation.py | 2 +- 9 files changed, 40 insertions(+), 470 deletions(-) mode change 100755 => 100644 tests/misra/test_mutation.py diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d1d9f7605a..9dfae7ce86 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -96,9 +96,12 @@ jobs: run: eval "$BUILD" - name: Build FW run: ${{ env.RUN }} "scons -j$(nproc)" - - name: Run MISRA C:2012 analysis + - name: Run MISRA C:2012 analysis - ALLOW_DEBUG timeout-minutes: 1 run: ${{ env.RUN }} "cd tests/misra && ./test_misra.sh" + - name: Run MISRA C:2012 analysis - RELEASE + timeout-minutes: 2 + run: ${{ env.RUN }} "cd tests/misra && CERT=./certs/debug RELEASE=1 ./test_misra.sh" - name: MISRA mutation tests timeout-minutes: 7 run: ${{ env.RUN }} "cd tests/misra && pytest -n8 test_mutation.py" diff --git a/.gitignore b/.gitignore index 640f25f8e0..173a0b41eb 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ examples/output.csv nosetests.xml .mypy_cache/ .sconsign.dblite +compile_commands*.json # CTU info files generated by Cppcheck *.*.ctu-info diff --git a/SConscript b/SConscript index 4c86d0cfab..9054f32b59 100644 --- a/SConscript +++ b/SConscript @@ -107,8 +107,8 @@ def build_project(project_name, project, extra_flags): # Bootstub crypto_obj = [ - env.Object(f"rsa-{project_name}", f"{panda_root}/crypto/rsa.c"), - env.Object(f"sha-{project_name}", f"{panda_root}/crypto/sha.c") + env.Object(f"bootstub-rsa-{project_name}", f"{panda_root}/crypto/rsa.c"), + env.Object(f"bootstub-sha-{project_name}", f"{panda_root}/crypto/sha.c") ] bootstub_obj = env.Object(f"bootstub-{project_name}", File(project.get("BOOTSTUB", f"{panda_root}/board/bootstub.c"))) bootstub_elf = env.Program(f"obj/bootstub.{project_name}.elf", diff --git a/SConstruct b/SConstruct index aa13f59229..9ff8c36733 100644 --- a/SConstruct +++ b/SConstruct @@ -22,7 +22,13 @@ env = Environment( ) if GetOption('compile_db'): + # whole project compilation database env.CompilationDatabase("compile_commands.json") + # Panda compilation database + env_p = env.Clone() + env_p["COMPILATIONDB_PATH_FILTER"] = '*board/[!jungle/][!bootstub]*' + env_p.CompilationDatabase("compile_commands_panda.json") + # panda fw & test files SConscript('SConscript') diff --git a/tests/misra/checkers.txt b/tests/misra/checkers.txt index 16489ca720..8fb3ab35d8 100644 --- a/tests/misra/checkers.txt +++ b/tests/misra/checkers.txt @@ -5,7 +5,7 @@ Cppcheck checkers list from test_misra.sh: TEST variant options: -/board/main.c -I/board/ -DPANDA -DALLOW_DEBUG -UPANDA_JUNGLE -UFINAL_PROVISIONING -UBOOTSTUB -UDEBUG -UDEBUG_COMMS -UDEBUG_FAULTS -UDEBUG_FAN -UDEBUG_SPI -UDEBUG_UART -UDEBUG_USB --config-exclude=/board/stm32f4/inc --config-exclude=/board/stm32h7/inc --include=/tests/misra/panda_macro_config.h -i/tests/misra --enable=all --addon=misra --force --suppress=unknownMacro +--project=/compile_commands.json --enable=all --addon=misra -i/board/bootstub.c -i/board/jungle/ -i/crypto/ Critical errors @@ -194,466 +194,7 @@ Yes CheckType::checkSignConversion Yes CheckType::checkTooBigBitwiseShift Yes CheckUninitVar::check Yes CheckUninitVar::valueFlowUninit -<<<<<<< HEAD Yes CheckUnusedFunctions::check -======= -No CheckUnusedFunctions::check require:unusedFunction -Yes CheckUnusedVar::checkFunctionVariableUsage -Yes CheckUnusedVar::checkStructMemberUsage -Yes CheckVaarg::va_list_usage -Yes CheckVaarg::va_start_argument - - -Premium checkers ----------------- -Not available, Cppcheck Premium is not used - - -Autosar -------- -Not available, Cppcheck Premium is not used - - -Cert C ------- -Not available, Cppcheck Premium is not used - - -Cert C++ --------- -Not available, Cppcheck Premium is not used - - -Misra C 2012 ------------- -No Misra C 2012: Dir 1.1 -No Misra C 2012: Dir 2.1 -No Misra C 2012: Dir 3.1 -No Misra C 2012: Dir 4.1 -No Misra C 2012: Dir 4.2 -No Misra C 2012: Dir 4.3 -No Misra C 2012: Dir 4.4 -No Misra C 2012: Dir 4.5 -No Misra C 2012: Dir 4.6 amendment:3 -No Misra C 2012: Dir 4.7 -No Misra C 2012: Dir 4.8 -No Misra C 2012: Dir 4.9 amendment:3 -No Misra C 2012: Dir 4.10 -No Misra C 2012: Dir 4.11 amendment:3 -No Misra C 2012: Dir 4.12 -No Misra C 2012: Dir 4.13 -No Misra C 2012: Dir 4.14 amendment:2 -No Misra C 2012: Dir 4.15 amendment:3 -No Misra C 2012: Dir 5.1 amendment:4 -No Misra C 2012: Dir 5.2 amendment:4 -No Misra C 2012: Dir 5.3 amendment:4 -Yes Misra C 2012: 1.1 -Yes Misra C 2012: 1.2 -Yes Misra C 2012: 1.3 -Yes Misra C 2012: 1.4 amendment:2 -No Misra C 2012: 1.5 amendment:3 require:premium -Yes Misra C 2012: 2.1 -Yes Misra C 2012: 2.2 -Yes Misra C 2012: 2.3 -Yes Misra C 2012: 2.4 -Yes Misra C 2012: 2.5 -Yes Misra C 2012: 2.6 -Yes Misra C 2012: 2.7 -Yes Misra C 2012: 2.8 -Yes Misra C 2012: 3.1 -Yes Misra C 2012: 3.2 -Yes Misra C 2012: 4.1 -Yes Misra C 2012: 4.2 -Yes Misra C 2012: 5.1 -Yes Misra C 2012: 5.2 -Yes Misra C 2012: 5.3 -Yes Misra C 2012: 5.4 -Yes Misra C 2012: 5.5 -Yes Misra C 2012: 5.6 -Yes Misra C 2012: 5.7 -Yes Misra C 2012: 5.8 -Yes Misra C 2012: 5.9 -Yes Misra C 2012: 6.1 -Yes Misra C 2012: 6.2 -No Misra C 2012: 6.3 -Yes Misra C 2012: 7.1 -Yes Misra C 2012: 7.2 -Yes Misra C 2012: 7.3 -Yes Misra C 2012: 7.4 -No Misra C 2012: 7.5 -No Misra C 2012: 7.6 -Yes Misra C 2012: 8.1 -Yes Misra C 2012: 8.2 -No Misra C 2012: 8.3 -Yes Misra C 2012: 8.4 -Yes Misra C 2012: 8.5 -Yes Misra C 2012: 8.6 -Yes Misra C 2012: 8.7 -Yes Misra C 2012: 8.8 -Yes Misra C 2012: 8.9 -Yes Misra C 2012: 8.10 -Yes Misra C 2012: 8.11 -Yes Misra C 2012: 8.12 -Yes Misra C 2012: 8.13 -Yes Misra C 2012: 8.14 -No Misra C 2012: 8.15 -No Misra C 2012: 8.16 -No Misra C 2012: 8.17 -Yes Misra C 2012: 9.1 -Yes Misra C 2012: 9.2 -Yes Misra C 2012: 9.3 -Yes Misra C 2012: 9.4 -Yes Misra C 2012: 9.5 -No Misra C 2012: 9.6 -No Misra C 2012: 9.7 -Yes Misra C 2012: 10.1 -Yes Misra C 2012: 10.2 -Yes Misra C 2012: 10.3 -Yes Misra C 2012: 10.4 -Yes Misra C 2012: 10.5 -Yes Misra C 2012: 10.6 -Yes Misra C 2012: 10.7 -Yes Misra C 2012: 10.8 -Yes Misra C 2012: 11.1 -Yes Misra C 2012: 11.2 -Yes Misra C 2012: 11.3 -Yes Misra C 2012: 11.4 -Yes Misra C 2012: 11.5 -Yes Misra C 2012: 11.6 -Yes Misra C 2012: 11.7 -Yes Misra C 2012: 11.8 -Yes Misra C 2012: 11.9 -No Misra C 2012: 11.10 -Yes Misra C 2012: 12.1 -Yes Misra C 2012: 12.2 -Yes Misra C 2012: 12.3 -Yes Misra C 2012: 12.4 -Yes Misra C 2012: 12.5 amendment:1 -No Misra C 2012: 12.6 amendment:4 require:premium -Yes Misra C 2012: 13.1 -No Misra C 2012: 13.2 -Yes Misra C 2012: 13.3 -Yes Misra C 2012: 13.4 -Yes Misra C 2012: 13.5 -Yes Misra C 2012: 13.6 -Yes Misra C 2012: 14.1 -Yes Misra C 2012: 14.2 -Yes Misra C 2012: 14.3 -Yes Misra C 2012: 14.4 -Yes Misra C 2012: 15.1 -Yes Misra C 2012: 15.2 -Yes Misra C 2012: 15.3 -Yes Misra C 2012: 15.4 -Yes Misra C 2012: 15.5 -Yes Misra C 2012: 15.6 -Yes Misra C 2012: 15.7 -Yes Misra C 2012: 16.1 -Yes Misra C 2012: 16.2 -Yes Misra C 2012: 16.3 -Yes Misra C 2012: 16.4 -Yes Misra C 2012: 16.5 -Yes Misra C 2012: 16.6 -Yes Misra C 2012: 16.7 -Yes Misra C 2012: 17.1 -Yes Misra C 2012: 17.2 -Yes Misra C 2012: 17.3 -No Misra C 2012: 17.4 -Yes Misra C 2012: 17.5 -Yes Misra C 2012: 17.6 -Yes Misra C 2012: 17.7 -Yes Misra C 2012: 17.8 -No Misra C 2012: 17.9 -No Misra C 2012: 17.10 -No Misra C 2012: 17.11 -No Misra C 2012: 17.12 -No Misra C 2012: 17.13 -Yes Misra C 2012: 18.1 -Yes Misra C 2012: 18.2 -Yes Misra C 2012: 18.3 -Yes Misra C 2012: 18.4 -Yes Misra C 2012: 18.5 -Yes Misra C 2012: 18.6 -Yes Misra C 2012: 18.7 -Yes Misra C 2012: 18.8 -No Misra C 2012: 18.9 -No Misra C 2012: 18.10 -Yes Misra C 2012: 19.1 -Yes Misra C 2012: 19.2 -Yes Misra C 2012: 20.1 -Yes Misra C 2012: 20.2 -Yes Misra C 2012: 20.3 -Yes Misra C 2012: 20.4 -Yes Misra C 2012: 20.5 -Yes Misra C 2012: 20.6 -Yes Misra C 2012: 20.7 -Yes Misra C 2012: 20.8 -Yes Misra C 2012: 20.9 -Yes Misra C 2012: 20.10 -Yes Misra C 2012: 20.11 -Yes Misra C 2012: 20.12 -Yes Misra C 2012: 20.13 -Yes Misra C 2012: 20.14 -Yes Misra C 2012: 21.1 -Yes Misra C 2012: 21.2 -Yes Misra C 2012: 21.3 -Yes Misra C 2012: 21.4 -Yes Misra C 2012: 21.5 -Yes Misra C 2012: 21.6 -Yes Misra C 2012: 21.7 -Yes Misra C 2012: 21.8 -Yes Misra C 2012: 21.9 -Yes Misra C 2012: 21.10 -Yes Misra C 2012: 21.11 -Yes Misra C 2012: 21.12 -Yes Misra C 2012: 21.13 amendment:1 -Yes Misra C 2012: 21.14 amendment:1 -Yes Misra C 2012: 21.15 amendment:1 -Yes Misra C 2012: 21.16 amendment:1 -Yes Misra C 2012: 21.17 amendment:1 -Yes Misra C 2012: 21.18 amendment:1 -Yes Misra C 2012: 21.19 amendment:1 -Yes Misra C 2012: 21.20 amendment:1 -Yes Misra C 2012: 21.21 amendment:3 -No Misra C 2012: 21.22 amendment:3 require:premium -No Misra C 2012: 21.23 amendment:3 require:premium -No Misra C 2012: 21.24 amendment:3 require:premium -No Misra C 2012: 21.25 amendment:4 require:premium -No Misra C 2012: 21.26 amendment:4 require:premium -Yes Misra C 2012: 22.1 -Yes Misra C 2012: 22.2 -Yes Misra C 2012: 22.3 -Yes Misra C 2012: 22.4 -Yes Misra C 2012: 22.5 -Yes Misra C 2012: 22.6 -Yes Misra C 2012: 22.7 amendment:1 -Yes Misra C 2012: 22.8 amendment:1 -Yes Misra C 2012: 22.9 amendment:1 -Yes Misra C 2012: 22.10 amendment:1 -No Misra C 2012: 22.11 amendment:4 require:premium -No Misra C 2012: 22.12 amendment:4 require:premium -No Misra C 2012: 22.13 amendment:4 require:premium -No Misra C 2012: 22.14 amendment:4 require:premium -No Misra C 2012: 22.15 amendment:4 require:premium -No Misra C 2012: 22.16 amendment:4 require:premium -No Misra C 2012: 22.17 amendment:4 require:premium -No Misra C 2012: 22.18 amendment:4 require:premium -No Misra C 2012: 22.19 amendment:4 require:premium -No Misra C 2012: 22.20 amendment:4 require:premium -No Misra C 2012: 23.1 amendment:3 require:premium -No Misra C 2012: 23.2 amendment:3 require:premium -No Misra C 2012: 23.3 amendment:3 require:premium -No Misra C 2012: 23.4 amendment:3 require:premium -No Misra C 2012: 23.5 amendment:3 require:premium -No Misra C 2012: 23.6 amendment:3 require:premium -No Misra C 2012: 23.7 amendment:3 require:premium -No Misra C 2012: 23.8 amendment:3 require:premium - - -Misra C++ 2008 --------------- -Not available, Cppcheck Premium is not used - - -Misra C++ 2023 --------------- -Not available, Cppcheck Premium is not used - - - - - -TEST variant options: ---enable=all --disable=unusedFunction -DPANDA --addon=misra -DSTM32H7 -DSTM32H725xx /board/main.c - - -Critical errors ---------------- -No critical errors, all files were checked. -Important: Analysis is still not guaranteed to be 'complete' it is possible there are false negatives. - - -Open source checkers --------------------- -Yes Check64BitPortability::pointerassignment -Yes CheckAssert::assertWithSideEffects -Yes CheckAutoVariables::assignFunctionArg -Yes CheckAutoVariables::autoVariables -Yes CheckAutoVariables::checkVarLifetime -No CheckBool::checkAssignBoolToFloat require:style,c++ -Yes CheckBool::checkAssignBoolToPointer -No CheckBool::checkBitwiseOnBoolean require:style,inconclusive -Yes CheckBool::checkComparisonOfBoolExpressionWithInt -No CheckBool::checkComparisonOfBoolWithBool require:style,c++ -No CheckBool::checkComparisonOfBoolWithInt require:warning,c++ -No CheckBool::checkComparisonOfFuncReturningBool require:style,c++ -Yes CheckBool::checkIncrementBoolean -Yes CheckBool::pointerArithBool -Yes CheckBool::returnValueOfFunctionReturningBool -No CheckBoost::checkBoostForeachModification -Yes CheckBufferOverrun::analyseWholeProgram -Yes CheckBufferOverrun::argumentSize -Yes CheckBufferOverrun::arrayIndex -Yes CheckBufferOverrun::arrayIndexThenCheck -Yes CheckBufferOverrun::bufferOverflow -Yes CheckBufferOverrun::negativeArraySize -Yes CheckBufferOverrun::objectIndex -Yes CheckBufferOverrun::pointerArithmetic -No CheckBufferOverrun::stringNotZeroTerminated require:warning,inconclusive -Yes CheckClass::analyseWholeProgram -No CheckClass::checkConst require:style,inconclusive -No CheckClass::checkConstructors require:style,warning -No CheckClass::checkCopyConstructors require:warning -No CheckClass::checkDuplInheritedMembers require:warning -No CheckClass::checkExplicitConstructors require:style -No CheckClass::checkMemset -No CheckClass::checkMissingOverride require:style,c++03 -No CheckClass::checkReturnByReference require:performance -No CheckClass::checkSelfInitialization -No CheckClass::checkThisUseAfterFree require:warning -No CheckClass::checkUnsafeClassRefMember require:warning,safeChecks -No CheckClass::checkUselessOverride require:style -No CheckClass::checkVirtualFunctionCallInConstructor require:warning -No CheckClass::initializationListUsage require:performance -No CheckClass::initializerListOrder require:style,inconclusive -No CheckClass::operatorEqRetRefThis require:style -No CheckClass::operatorEqToSelf require:warning -No CheckClass::privateFunctions require:style -No CheckClass::thisSubtraction require:warning -No CheckClass::virtualDestructor -Yes CheckCondition::alwaysTrueFalse -Yes CheckCondition::assignIf -Yes CheckCondition::checkAssignmentInCondition -Yes CheckCondition::checkBadBitmaskCheck -Yes CheckCondition::checkCompareValueOutOfTypeRange -Yes CheckCondition::checkDuplicateConditionalAssign -Yes CheckCondition::checkIncorrectLogicOperator -Yes CheckCondition::checkInvalidTestForOverflow -Yes CheckCondition::checkModuloAlwaysTrueFalse -Yes CheckCondition::checkPointerAdditionResultNotNull -Yes CheckCondition::clarifyCondition -Yes CheckCondition::comparison -Yes CheckCondition::duplicateCondition -Yes CheckCondition::multiCondition -Yes CheckCondition::multiCondition2 -No CheckExceptionSafety::checkCatchExceptionByValue require:style -No CheckExceptionSafety::checkRethrowCopy require:style -No CheckExceptionSafety::deallocThrow require:warning -No CheckExceptionSafety::destructors require:warning -No CheckExceptionSafety::nothrowThrows -No CheckExceptionSafety::rethrowNoCurrentException -No CheckExceptionSafety::unhandledExceptionSpecification require:style,inconclusive -Yes CheckFunctions::checkIgnoredReturnValue -Yes CheckFunctions::checkMathFunctions -Yes CheckFunctions::checkMissingReturn -Yes CheckFunctions::checkProhibitedFunctions -Yes CheckFunctions::invalidFunctionUsage -Yes CheckFunctions::memsetInvalid2ndParam -Yes CheckFunctions::memsetZeroBytes -No CheckFunctions::returnLocalStdMove require:performance,c++11 -Yes CheckFunctions::useStandardLibrary -No CheckIO::checkCoutCerrMisusage require:c -Yes CheckIO::checkFileUsage -Yes CheckIO::checkWrongPrintfScanfArguments -Yes CheckIO::invalidScanf -Yes CheckLeakAutoVar::check -No CheckMemoryLeakInClass::check -Yes CheckMemoryLeakInFunction::checkReallocUsage -Yes CheckMemoryLeakNoVar::check -No CheckMemoryLeakNoVar::checkForUnsafeArgAlloc -Yes CheckMemoryLeakStructMember::check -Yes CheckNullPointer::analyseWholeProgram -Yes CheckNullPointer::arithmetic -Yes CheckNullPointer::nullConstantDereference -Yes CheckNullPointer::nullPointer -No CheckOther::checkAccessOfMovedVariable require:c++11,warning -Yes CheckOther::checkCastIntToCharAndBack -Yes CheckOther::checkCharVariable -Yes CheckOther::checkComparePointers -Yes CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalse -Yes CheckOther::checkConstPointer -No CheckOther::checkConstVariable require:style,c++ -No CheckOther::checkDuplicateBranch require:style,inconclusive -Yes CheckOther::checkDuplicateExpression -Yes CheckOther::checkEvaluationOrder -Yes CheckOther::checkFuncArgNamesDifferent -No CheckOther::checkIncompleteArrayFill require:warning,portability,inconclusive -Yes CheckOther::checkIncompleteStatement -No CheckOther::checkInterlockedDecrement require:windows-platform -Yes CheckOther::checkInvalidFree -Yes CheckOther::checkKnownArgument -Yes CheckOther::checkKnownPointerToBool -No CheckOther::checkMisusedScopedObject require:style,c++ -Yes CheckOther::checkModuloOfOne -Yes CheckOther::checkNanInArithmeticExpression -Yes CheckOther::checkNegativeBitwiseShift -Yes CheckOther::checkOverlappingWrite -No CheckOther::checkPassByReference require:performance,c++ -Yes CheckOther::checkRedundantAssignment -No CheckOther::checkRedundantCopy require:c++,performance,inconclusive -Yes CheckOther::checkRedundantPointerOp -Yes CheckOther::checkShadowVariables -Yes CheckOther::checkSignOfUnsignedVariable -No CheckOther::checkSuspiciousCaseInSwitch require:warning,inconclusive -No CheckOther::checkSuspiciousSemicolon require:warning,inconclusive -Yes CheckOther::checkUnreachableCode -Yes CheckOther::checkUnusedLabel -Yes CheckOther::checkVarFuncNullUB -Yes CheckOther::checkVariableScope -Yes CheckOther::checkZeroDivision -Yes CheckOther::clarifyCalculation -Yes CheckOther::clarifyStatement -Yes CheckOther::invalidPointerCast -Yes CheckOther::redundantBitwiseOperationInSwitch -Yes CheckOther::suspiciousFloatingPointCast -No CheckOther::warningOldStylePointerCast require:style,c++ -No CheckPostfixOperator::postfixOperator require:performance -Yes CheckSizeof::checkSizeofForArrayParameter -Yes CheckSizeof::checkSizeofForNumericParameter -Yes CheckSizeof::checkSizeofForPointerSize -Yes CheckSizeof::sizeofCalculation -Yes CheckSizeof::sizeofFunction -Yes CheckSizeof::sizeofVoid -Yes CheckSizeof::sizeofsizeof -No CheckSizeof::suspiciousSizeofCalculation require:warning,inconclusive -No CheckStl::checkDereferenceInvalidIterator require:warning -No CheckStl::checkDereferenceInvalidIterator2 -No CheckStl::checkFindInsert require:performance -No CheckStl::checkMutexes require:warning -No CheckStl::erase -No CheckStl::eraseIteratorOutOfBounds -No CheckStl::if_find require:warning,performance -No CheckStl::invalidContainer -No CheckStl::iterators -No CheckStl::knownEmptyContainer require:style -No CheckStl::misMatchingContainerIterator -No CheckStl::misMatchingContainers -No CheckStl::missingComparison require:warning -No CheckStl::negativeIndex -No CheckStl::outOfBounds -No CheckStl::outOfBoundsIndexExpression -No CheckStl::redundantCondition require:style -No CheckStl::size require:performance,c++03 -No CheckStl::stlBoundaries -No CheckStl::stlOutOfBounds -No CheckStl::string_c_str -No CheckStl::useStlAlgorithm require:style -No CheckStl::uselessCalls require:performance,warning -Yes CheckString::checkAlwaysTrueOrFalseStringCompare -Yes CheckString::checkIncorrectStringCompare -Yes CheckString::checkSuspiciousStringCompare -Yes CheckString::overlappingStrcmp -Yes CheckString::sprintfOverlappingData -Yes CheckString::strPlusChar -Yes CheckString::stringLiteralWrite -Yes CheckType::checkFloatToIntegerOverflow -Yes CheckType::checkIntegerOverflow -Yes CheckType::checkLongCast -Yes CheckType::checkSignConversion -Yes CheckType::checkTooBigBitwiseShift -Yes CheckUninitVar::check -Yes CheckUninitVar::valueFlowUninit -No CheckUnusedFunctions::check require:unusedFunction ->>>>>>> 8545c68e4d51eab55803c9c28cdf8bb7bfaa261e Yes CheckUnusedVar::checkFunctionVariableUsage Yes CheckUnusedVar::checkStructMemberUsage Yes CheckVaarg::va_list_usage diff --git a/tests/misra/panda_macro_config.h b/tests/misra/panda_macro_config.h index 30ba1cfc8f..766517c311 100644 --- a/tests/misra/panda_macro_config.h +++ b/tests/misra/panda_macro_config.h @@ -1,5 +1,5 @@ -// This is a dummy structure to allow cppcheck to test certain macro combinations -// together and in one seesion (needed for things like unused macros) +// This is a dummy structure to allow cppcheck to test certain macro combinations +// together and in one seesion (needed for things like unused macros) // The structure should represents macro configurations used in scons #ifdef STM32H7 @@ -12,5 +12,4 @@ #ifdef ENABLE_SPI #endif #endif -#else #endif diff --git a/tests/misra/suppressions.txt b/tests/misra/suppressions.txt index 4b79e109f5..04fc81158f 100644 --- a/tests/misra/suppressions.txt +++ b/tests/misra/suppressions.txt @@ -18,7 +18,7 @@ unusedFunction:*/interrupt_handlers.h # all of the below suppressions are from new checks introduced after updating # cppcheck from 2.5 -> 2.13. they are listed here to separate the update from # fixing the violations and all are intended to be removed soon after -misra-c2012-2.5 # unused macros. a few legit, rest aren't common between F4/H7 builds. should we do this in the unusedFunction pass? +misra-c2012-5.9 # false positives ? misra-c2012-8.7 misra-c2012-8.4 misra-c2012-21.15 diff --git a/tests/misra/test_misra.sh b/tests/misra/test_misra.sh index 5f713bfa6f..392efd23a2 100755 --- a/tests/misra/test_misra.sh +++ b/tests/misra/test_misra.sh @@ -28,7 +28,7 @@ fi cd $PANDA_DIR if [ -z "${SKIP_BUILD}" ]; then - scons -j8 + scons -j8 --compile_db fi CHECKLIST=$DIR/checkers.txt @@ -61,6 +61,25 @@ cppcheck() { fi } +if [ -z "$PANDA_SYSTEM_LEVEL_ONLY" ]; then +# Test whole Panda project for unused functions / constants +printf "\n${GREEN}** Panda project - tests: Cppcheck whole program + MISRA per translation unit **${NC}\n" +cppcheck --project=$PANDA_DIR/compile_commands.json \ + --enable=all --addon=misra \ + -i$PANDA_DIR/board/bootstub.c \ + -i$PANDA_DIR/board/jungle/ \ + -i$PANDA_DIR/crypto/ +# TODO enable bootstub and jungle for the whole build +# Note: MISRA system level tests (e.g. rule 2.5) not supported by cppcheck 2.15 with --project argument + + +# Test standalone Panda program. (Unused functions / constants will be more strict than whole project check) + printf "\n${GREEN}** Panda standalone - tests: Cppcheck whole program **${NC}\n" + cppcheck --project=$PANDA_DIR/compile_commands_panda.json \ + --enable=all --addon=misra +fi + +# *** Legacy cppcheck test type by providing c files list *** # --force checks different macro combinations to avoid reporting macros and functions used by only one panda configuration # panda_macro_config.h lets cppcheck know macro combinations used for the build printf "\n${GREEN}** Panda tests: cppcheck whole program anlysis + Misra addon system level analysis **${NC}\n" @@ -71,7 +90,8 @@ cppcheck $PANDA_DIR/board/main.c -I$PANDA_DIR/board/ \ --config-exclude=$PANDA_DIR/board/stm32f4/inc --config-exclude=$PANDA_DIR/board/stm32h7/inc \ --include=$DIR/panda_macro_config.h -i$DIR \ --enable=all --addon=misra \ - --force --suppress=unknownMacro + --force +# TODO remove this test when cppcheck fully supports system level misra reporting with --project printf "\n${GREEN}Success!${NC} took $SECONDS seconds\n" diff --git a/tests/misra/test_mutation.py b/tests/misra/test_mutation.py old mode 100755 new mode 100644 index da6aa85bde..85047a4173 --- a/tests/misra/test_mutation.py +++ b/tests/misra/test_mutation.py @@ -81,6 +81,6 @@ def test_misra_mutation(fn, patch, should_fail, tmp_path): assert r == 0 # run test - r = subprocess.run("SKIP_TABLES_DIFF=1 tests/misra/test_misra.sh", cwd=tmp_path, shell=True) + r = subprocess.run("SKIP_TABLES_DIFF=1 PANDA_SYSTEM_LEVEL_ONLY=1 tests/misra/test_misra.sh", cwd=tmp_path, shell=True) failed = r.returncode != 0 assert failed == should_fail