Since the tool identifies memory access violations statically (e.g., without running the code), memory access rights can be specified with a much higher granularity without adding any impact to run-time performance. Higher granularity memory access rights allow for detection of more safety violations, (e.g., safety violations between software components that are within the same safety class but should be shielded from each other regardless).
The TASKING Safety Checker can be easily integrated into your preferred development environment or continuous integration framework. This will allow you to minimize the cost of coding mistakes in the day-to-day work of your developers by providing instant feedback before such errors propagate through your code base and cause expensive knock on effects.
An example workflow in the tasking safety checker
In this section, an example application of the TASKING Safety Checker is presented.
1. Defining Safety Classes
First, the MPU memory access rights must be defined using the TASKING Safety Checker input format (e.g. within the file “partitioning.saf”), which is given as a command line option when the tool is executed. By providing these settings in an extra file, no source code changes are required to use the TASKING Safety Checker.
If the memory access rights information is already available in a structured format (e.g., from the architectural documentation), the input file required by the TASKING Safety Checker can be easily generated from the existing information using common, free tools like grep, sed and friends. Otherwise, the input format is a great way to document safety requirements in a formal manner that can be verified.
The TASKING Safety Checker input format supports the C-preprocessor to increase readability. Hence, easy-to-read macros are used to define the different safety classes as shown below:
//short cuts for access rights read, write, execute and none
#define R (__SAFETY_CLASS_ACCESS_RIGHTS_READ__) //read
#define W (__SAFETY_CLASS_ACCESS_RIGHTS_WRITE__) //write
#define X (__SAFETY_CLASS_ACCESS_RIGHTS_CALL__) //execute
#define N (0U) //none
//define different safety classes, e.g. ASIL levels
#define QM (0U)
#define ASIL_A (1U)
#define ASIL_B (2U)
#define ASIL_C (3U)
#define ASIL_D (4U)
In the next step, we define the access rights between the different safety classes.