Robust Development Methodologies (II)
Introduction
Thus far, you have created, run and debugged your own application developed with ARM Keil. However, you have little to no knowledge whether this application could be used - from a qualitative standpoint - in a safety environment. This codelab aims at adding this dimension to your project so as to have sound foundations for future work.
What you’ll build
In this codelab, you will understand the required tools and guidelines for building qualitatively good SW - attitude that should be used while creating any type of SW. You will also understand how to interpret the results delivered by the tools used in order to improve your work.
What you’ll learn
- How to set up the tools for ensuring sufficiently good SW quality.
- Continue ensuring quality throughout the development lifecycle.
- Understand the different elements composing quality and to interpret the results provided by the different analysis tools.
What you’ll need
- You need to have completed the getting started with keil codelab.
- You need to have finished the Digging into RTX codelab.
- You need to have finished Scheduling of periodic tasks
Install the SW Quality checkers - cloc, lizard, clang-formatand cpplint
You need python3 installed
You likely have it already - but in case you did not, follow the following instructions
During this course, we will use cloc, lizard, clang-format, cpplint (and 
pre-commit later) for ensuring our code conforms to expected quality. 
In order to install the checker tools:
- head to clang-format- LLVM Download Page, download and install the appropriate package ( here a direct link ). Important: make sure to ignore the warning during installation and install the tool in the PATH for all users. This tool will be used for formatting the C/C++ code.
- enter pip3 install cpplintto install a linter for our code. This will be used for ensuring compliancy to Google styleguide . Remember, it is important to have 1 styleguide. Whether this is the best is up to debate (as we should tailor it to C anyhow for instance).
- head to 
  cloc- releases to download and install the appropriate package ( here a direct link ). Save it on your harddisk and add it to the $PATH.
 IMPORTANT: do not yet use version 2.xx (or at your own risk).
- issue pip3 install lizardto installlizard.
Note
In case you had a different operating system, you can also issue:
- clang-format:- MacOS: brew install clang-format
- Linux: sudo apt install clang-format
 
- MacOS: 
- cloc- MacOS: brew install cloc
- Linux: pip3 install cloc
 
- MacOS: 
- cpplint- MacOS: brew install cpplint
- Linux: pip3 install cpplint
 
- MacOS: 
Obviously, these tools may be available as plugin in various IDEs ( VsCode, CLion, …) you may use regularly.
Test your tools from the command line before continuing
Ensure that your tools are working by issuing the following commands:
- clang-format --version
- cpplint --version
- cloc --version
Not finding the tool from the command line?
In case Windows did not find the tool, check that it is indeed present 
in your $PATH.
Configure the tools
Now that you have installed the tools, it is time to make use of them. You first start by checking they do work and then move on to test what your code looks like.
Run a first analysis
To test lizard functionality (and be surprised by the complexity of a 
function), go to where your simple car project is located and issue:
lizard  RTE/Device/STM32L475VGTx/STCubeGenerated/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c
You should be able to see that HAL_SPI_TransmitReceive has a whopping cyclomatic 
complexity of 62. Open the file and see it yourself what that 62 means as far 
understanding a foreign piece of SW.
In order to analyze your own project, head to the root of your simple car 
project, run the lizard tool and inspect the results. You can run the tool 
by entering:
// use lizard (note: "Application" is the folder in which you put your own application)
lizard Application RTE/Device/STM32L475VGTx/STCubeGenerated/Core/src/main.c
Question 1
- With lizard, what does the option-Cmean?
- What Cvalue would you set according to the theory?
Solution
- Threshold for cyclomatic complexity number warning
- Ideally 10 (12 topmost value)
Subsequently, run the cloc tool and inspect the results. You can run the 
tool by entering:
// use cloc (note: "Application" is the folder in which you put your own application)
cloc Application RTE/Device/STM32L475VGTx/STCubeGenerated/Core/src/main.c
Afterwards, check out what clang-format does. For doing so, first create a 
.clang-format at the root of your project with the following content:
---
  BasedOnStyle: Google
  IndentWidth: 4
---
  Language: Cpp
  ColumnLimit: 100
  AlignConsecutiveAssignments: true
  DerivePointerAlignment: false
  PointerAlignment: Left
  BinPackArguments: false
  BinPackParameters: false
clang-format -i RTE/Device/STM32L475VGTx/STCubeGenerated/Core/src/main.c.
Question 2
Respond to the following questions:
- has the file been modified?
- how can you check that? (write down the command)
- what is the meaning of option -i?
- what does ColumnLimitin.clang-formatmean?
Solution
- Yes, it has
- git diff RTE/Device/STM32L475VGTx/STCubeGenerated/Core/src/main.c
- Inplace edit files, if specified
- the maximum length of a line
Lastly, have a look at what cpplint. Issue:
  cpplint Application/* RTE/Device/STM32L475VGTx/STCubeGenerated/Core/src/main.c
Fixing the issues
You have tested most tools and inspected results. However, the goal is to ensure qualitatively good code. As a result:
- create a dedicated git branchfor fixing the eventual issues
- use lizard -C 10 Application RTE/Device/STM32L475VGTx/STCubeGenerated/Core/src/main.c.
 Fix all the functions - if any - crossing the 10 maximal value for the cyclomatic complexity.
- commit your changes (git add *andgit commit -m "Fixed cyclomatic complecity issues")
- apply clang-format -i Application/* RTE/Device/STM32L475VGTx/STCubeGenerated/Core/src/main.c
- commit your changes (git add *andgit commit -m "Fixed formatting issues with clang-format")
- run cpplint Application/* RTE/Device/STM32L475VGTx/STCubeGenerated/Core/src/main.c
- commit your changes (git add *andgit commit -m "Fixed Google Styleguides issues")
REMEMBER: make small commits!
As we learned, small commits are instrumental to a proper way of developing. Make sure to respect it when you are fixing the issues. That is, you will commit only one step at a time - not all changes at once.
Use spaces, not tabs
Make sure your editor (including ARM Keil) makes use of spaces instead of 
tabs. 
Here the link to ARM Keil’s user manual
to change the behaviour accordingly (and act according to the 
chosen styleguide).
Note
There may be issues flagged by cpplint that may not seem trivial. However:
- check Google’s Styleguide concerning the rationale of the rule
- control the Styleguide Script as it may help the understanding
- be aware of compiler’s behaviours. For instance const static aVariableis accepted by the compiler but it is not standard compliant (static const aVariableis)
- although one could disable a rule with -filter, it is strongly suggested not to - and if so, only with a written justification
Warning
Be sure you have created a CPPLINT.cfg file at the root of your project 
containing, at least, the line length aligned with .clang-format.
Moreover, prevent cpplint from expecting include files in the same
directory.
# Stop searching for additional config files.
set noparent
# Limit line length.
linelength=100
# Header files are not always placed in the same directory
filter=-build/include
cpplint manual (aka
ccplint.py 😉).
Copyrighting your work
No matter what SW one writes, a copyright shall always be specified - no matter 
whether open source or proprietary in its nature. With cpplint, in case one 
forgot, the following error will be shown ” 
No copyright message found.  You should have a line: Copyright [year] <Copyright Owner>
“. An example of such copyright can be found below:
  /**
  ******************************************************************************
  * @file        : monnalisa.h
  * @brief       : pensive woman module
  * @author      : Leonardo Da Vinci <leo@davinci.net>
  * @date        : 19. March 1503
  ******************************************************************************
  * @copyright   : Copyright (c) 1503 
  *                Haute école de peinture de Florence
  * @attention   : SPDX-License-Identifier: MIT OR Apache-2.0
  ******************************************************************************
  * @details
  * Pensive woman module for impressing mankind
  ******************************************************************************
  */
Putting all together: pre-commit
Now that you are capable of checking the code, a question arises: how to ensure 
to always remember to execute this? One way would be to check it centrally on a 
CI/CD pipeline, but that would be late (and consume energy for nothing). 
Do not worry! 
We got you covered: pre-commit does exactly what its name 
implies. It will run a serie of checks prior to committing. In order to install 
it, head to https://pre-commit.com/ and follow the 
instructions. 
So, once installed, we put all the tools seen so far by following the following instructions:
- create a .pre-commit-config.yamlat the root of yourgitproject with the following content:
files: ^(Application)|^(RTE\/Device\/STM32L475VGTx\/STCubeGenerated\/Core\/Src\/main\.c)
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v4.3.0
  hooks:
  -   id: check-yaml
      args: [--allow-multiple-documents]
  -   id: end-of-file-fixer
  -   id: trailing-whitespace
- repo: https://github.com/pre-commit/mirrors-clang-format
  rev: 'v14.0.6'
  hooks:
  -   id: clang-format
- repo: https://github.com/cpplint/cpplint
  rev: '1.6.1'
  hooks:
  -   id: cpplint
- repo: local
  hooks:
  -   id: lizard
      name: lizard
      entry: lizard
      language: system
      args: [-C 12]
- add .pre-commit-config.yamlto yourgitrepository
- install the hooks with pre-commit install
- run the command manually by issuing pre-commit run --all-files
- if you did a good job in Fixing the issues, all will be green
- That’s it!. From now on, all code changes will undergo the specified checks
Question 3
Respond to the following questions:
- what does 
   ^(Application)|^(RTE\/Device\/STM32L475VGTx\/STCubeGenerated\/Core\/Src\/main\.c)underfilesmean? (hint: check https://regex101.com/)
- what does [-C 12]mean?
- what are the implications  of language: system?
- is there a way to ensure that MISRA C:2012 checks are run automatically?
Solution
- It is a regex specifying on what the hooks will be applied
- It specifies the maximum cyclomatic complexity accepted
- One needs to a) ensure the presence of the tool on the machine, b)
   handle the updates manually and c) manage the accessibility of the 
   tool (e.g. tool present in the $PATH)
- Yes, there is. One can run pre-commit run cppcheck --all-filesonce .pre-commit-config.yaml is configured as follows (or similar):Obviously, it would be best not to rely on- repo: local hooks: - id: cppcheck name: cppcheck entry: cppcheck language: system args: [--addon=misra.json --force --inline-suppr --suppress=*:RTE/Device/STM32L475VGTx/STCubeGenerated/Inc/* -IRTE/Device/STM32L475VGTx/STCubeGenerated/Inc -IApplication]language: system;-)
Note
For those who would like to know more about git hooks and pre-commit, 
here a few interesting links:
Run the analysis on your code
On a dedicated branch, run the analysis on your code to find 
eventual issues in your application (including MISRA). Go about fixing 
them one at a time and commit the fixes on a dedicated branch (named 
going_professional). 
Important: only run the analysis on main.c contained in 
YOUR_PROJECT_LOCATION\RTE\Device\STM32L475VGTx\STCubeGenerated\src and
Application (or whatever folder you put your own implementation), not those coming from 3rd party.
pre-commit will be part of the git repository and will throw no errors.
Metrics - Going beyond
Although we will use the above tools throughout the course, there is a 
multitude of other metrics that will help you assess the code quality. 
Scitool Understand, for which
you have now received a license, will offer you a plethora of options under 
the “Metrics->Metrics Browser”. You have access to the metrics definitions by 
clicking on the following icon:
