← Back to the learning library
Before you begin: Read TFA-104 on defensive programming and TFA-108 on static analysis. Familiarity with C integer types, pointers and basic resource ownership is useful.
Reading time and practice time are estimates. Examples use fictional products and illustrative engineering values, not approved product limits.
Publication basis: Use the project’s explicitly selected MISRA C or MISRA C++ edition and applicable compliance guidance. The linked SEI CERT C publication is the 2016 edition; online guidance can evolve. Rule identifiers and obligations must be checked against the authorised editions.
Learning objectives
By the end of this module, you should be able to:
- Define the language, code and configuration boundaries of a coding policy.
- Distinguish coding guidance from product or lifecycle assurance.
- Resolve findings using evidence rather than blanket suppression.
- Review a deviation and the limits of a compliance claim.
Lesson 1
1. Choose a policy with a clear purpose
MISRA guidance addresses disciplined use of C or C++ in critical software. CERT coding guidance explains common vulnerability causes and safer programming practices. They can complement a project’s engineering controls, but neither turns a clean analysis report into proof that a firmware product is safe or secure.
In a fictional valve controller, the policy should address actual sources of failure: integer conversion, buffer boundaries, state transitions, peripheral access and concurrent ownership. Choose a rule baseline that fits the language version, toolchain and project obligations. Record why the policy is selected and what claims the team intends to make. Avoid combining arbitrary fragments of several publications and then describing the result as complete compliance with each.
Lesson 2
2. Define the assessed code and build configurations
Identify application code, boot code, generated code, supplier libraries and low-level hardware wrappers. Each category needs an assessment strategy. Excluding a supplier component from one analysis run does not remove its effect on the product. State the boundary and provide an alternative acceptance approach where needed.
Record compiler options, language dialect, target integer widths, preprocessor definitions and supported build variants. A desktop analysis using a different data model can miss target-specific conversion behaviour. Review the generated configuration used by the analyser, not just the command displayed in the pipeline. When compile-time options remove code paths, ensure that the assessed configurations represent the combinations the project actually releases.
Lesson 3
3. Translate rules into reviewable engineering decisions
Use findings to investigate behaviour. If a narrowing conversion appears, determine the possible source range, the destination range and the required response when the value cannot be represented. Adding a cast may silence a diagnostic while preserving the defect. Similarly, marking a pointer volatile does not establish ownership, atomicity or safe inter-task communication.
For a command containing a payload length, validate the untrusted length before indexing or copying. Where total size is bounded by a buffer capacity, a check such as length <= capacity - header_size is meaningful only after proving header_size <= capacity. This example illustrates a review question; it is not presented as a verbatim MISRA or CERT rule. The chosen implementation still needs appropriate types and a defined error response.
Lesson 4
4. Combine automatic and manual assessment
An analyser evaluates code using its model and configuration. Some findings require context that the tool cannot establish, while some design errors fall outside the selected checks. Supplement automated analysis with focused review of concurrency, interface contracts, hardware behaviour and assumptions about callers.
| Assessment area | Automation can support | Additional reasoning |
|---|---|---|
| Integer and pointer use | Suspicious conversions and paths | Real ranges, lifetimes and error policy |
| Interrupt-shared state | Some access and race patterns | Target atomicity and synchronisation design |
| Memory-mapped registers | Type and expression checks | Register semantics, barriers and device errata |
| Generated code | Repeated pattern analysis | Generator configuration and integration assumptions |
Keep the analysis version and configuration with the results. A changed tool can alter findings without any source change, so investigate differences before accepting a new baseline.
Lesson 5
5. Resolve findings without losing the argument
Classify each reviewed result according to the project procedure: a real defect to correct, a justified false positive, an allowed deviation or an unresolved issue that blocks a defined gate. These outcomes need different evidence. A false-positive rationale explains why the reported condition cannot occur; a deviation acknowledges a departure and justifies its controlled use.
Review suppressions at the narrowest practical scope. Record the affected source, rule or diagnostic, tool configuration, reasoning, approval and conditions for re-review. A file-level suppression added to accommodate one register access can conceal unrelated defects introduced later. Separate the team’s progress metrics from its acceptance criteria: a decreasing warning count does not establish that the remaining warnings are acceptable.
Lesson 6
6. Control deviations at hardware boundaries
Firmware may need operations that conflict with a general language-use policy, such as a constrained conversion used to address a peripheral register. The first response should be to examine safer alternatives and isolate the operation behind a narrow interface. A deviation must follow the selected edition’s rules; some requirements cannot simply be waived.
For the valve controller, a peripheral wrapper can document address alignment, access width, allowed register offsets and the permitted execution context. Its review should consider unintended read or write side effects. The same wrapper can include target tests and restrict application access. Hardware necessity is a starting point for an argument, not a universal exemption for every low-level file.
Lesson 7
7. Make the release claim precise
A useful release statement identifies the coding baseline, assessed code, configurations, tools, manual checks, exclusions, deviations and unresolved results. Keep the evidence reproducible. If a vendor says a library is compliant, establish the edition, scope and build assumptions behind that statement before using it in the product record.
Reassess the policy when language versions, compilers, generators or target families change. Avoid silently treating a newer MISRA edition as equivalent to the contractually selected one. Plan the transition and review changed expectations. Coding guidance should remain connected to design and verification: the most carefully controlled source code can still implement the wrong requirement or fail to meet a physical deadline.
Decision guide
What should happen to this analysis finding?
| Situation | Appropriate response | Evidence |
|---|---|---|
| The path can cause incorrect behaviour | Correct the implementation | Review and regression results |
| The reported condition is impossible under a proven invariant | Document a false-positive rationale | Invariant, call paths and tool assumptions |
| A permitted departure is necessary | Use controlled deviation handling | Alternatives, bounded scope and approval |
| The risk or applicability is unresolved | Retain as an open issue | Owner, investigation and gate decision |
Worked example
Worked example — a cast that hides a length defect
A service packet carries a wide integer length. The parser casts it to an 8-bit value before comparing it with a 128-byte buffer. Large values wrap into small ones and the code no longer checks what the sender actually requested.
The reviewer follows the value from the packet boundary to every use. The implementation validates the original value against the available payload, buffer capacity and protocol limit before conversion. Invalid packets receive a defined error without altering controller state. Tests include exact boundaries, large encoded values, truncated packets and repeated invalid commands.
The finding is resolved by controlling the input range and behaviour. A cast remains only where its safety can be explained from validated bounds; the analysis report is retained as supporting evidence rather than the sole justification.
Engineering evidence
What should the work produce?
Coding-policy baseline
Identifies language, editions, assessed code and permitted configurations.
Analysis configuration and results
Retains reproducible settings, tool versions and reviewed outcomes.
Manual assessment record
Covers relevant properties outside automatic analysis.
Deviation register
Contains bounded scope, technical rationale, approval and re-review triggers.
Common failure patterns
What goes wrong?
- Treating explicit casts as automatic repairs.
- Suppressing a whole directory to reach zero warnings.
- Claiming that volatile provides thread safety.
- Equating supplier coding claims with product acceptance.
Applied exercise · approximately 25 minutes
Review a proposed peripheral-access deviation
A developer requests a project-wide exception for pointer conversions because one driver maps hardware registers. The proposed justification is “standard practice in embedded C”.
- Identify why the proposed scope and rationale are inadequate.
- Define a narrower implementation and assessment boundary.
- List evidence and change triggers for reviewing the deviation.
Review a suggested approach
Project-wide scope could conceal unrelated pointer defects and does not identify the actual hardware requirement. Consider one reviewed register-access wrapper with a fixed address range, documented alignment and access widths, and a restricted API. Determine whether the chosen rule and compliance process permit the proposed deviation before approving it.
The record should explain alternatives, compiler assumptions, register side effects, target verification and independent review appropriate to the project. Re-review it when the processor, compiler, optimisation settings or register map changes. This is an exercise in building a justified record, not a declaration that a particular pointer conversion is valid on every platform.
Completion criteria
- The departure is necessary and limited to an identifiable use.
- Target-specific assumptions and remaining risks are examined.
- Approval follows the selected guidance rather than a blanket exemption.
This is a self-directed engineering exercise, not an accredited examination. Compare the rationale as well as the final answer.
Practical check
Questions for your next design review
- Does the analyser use the intended target data model and build options?
- Are real defects, false positives and deviations distinguished?
- Can a reviewer understand every suppression without asking its author?
- Does the release statement accurately describe its scope and limitations?
Coding guidance is effective when every claimed result is tied to a controlled scope and a defensible engineering argument.
References and further reading
- MISRA — coding-guidance publisher
- SEI CERT C Coding Standard — 2016 publication and scope
- TFA-108 — Coding Standards & Static Analysis
- TFA-104 — Defensive Programming
- TFA-201 — Firmware & Embedded Software Engineers
Educational guidance only. Apply the authorised standards editions, regulations and approved procedures relevant to your product and market. Linked publications support further study; the fictional exercises do not demonstrate compliance.
