1.1: Legacy System ASPICE Retrofit

Overview

Legacy embedded systems—codebases developed before ASPICE adoption, often spanning 10-20+ years—represent a critical challenge for organizations seeking safety certification (ISO 26262, IEC 61508, DO-178C) or customer mandates (OEM ASPICE compliance). Retrofitting ASPICE compliance to existing systems requires a systematic, risk-based approach that balances regulatory requirements with business constraints.

This chapter provides a comprehensive retrofit framework covering:

  • Assessment: Evaluate legacy system maturity and ASPICE gaps
  • Strategy: Risk-based phased approach vs. full reengineering
  • Traceability: Establish requirements-to-code linkage for existing systems
  • Requirements Extraction: Reverse-engineer requirements from code and documentation
  • Architecture Modernization: Refactor legacy designs for ASPICE compliance
  • Testing Strategy: Build regression test suites for retrofit validation
  • Multi-Standard Context: Align ASPICE retrofit with ISO 26262, IEC 61508, DO-178C
  • Case Study: Real-world 15-year-old automotive ECU retrofit to ISO 26262 ASIL-C
  • Cost Estimation: ROI analysis and budget planning
  • Team Training: Upskilling legacy development teams

ASPICE Processes Addressed:

  • SYS.2/SWE.1: Requirements elicitation for undocumented legacy systems
  • SYS.3/SWE.2: Architecture recovery and documentation
  • SWE.3: Code refactoring for modularity and testability
  • SWE.4/SWE.5: Comprehensive test suite development
  • SUP.8: Configuration management establishment
  • SUP.9: Problem resolution (defect tracking for legacy bugs)
  • MAN.3: Project management (retrofit planning, risk management)

Assessment Process for Legacy Codebases

Step 1: System Characterization

Objective: Understand the scope, complexity, and current state of the legacy system.

Characteristic Data Collection Method Key Metrics
Age Version control history, oldest file timestamps Years since first release, major version count
Size Static analysis tools (SLOCCount, cloc) Lines of code (LoC), file count, module count
Complexity Cyclomatic complexity (Lizard, SonarQube) McCabe complexity (avg, max), nesting depth
Language File extensions, compiler toolchain C/C++/Assembly mix, language standard (C89 vs. C11)
Platform Target hardware documentation Microcontroller family, RTOS, toolchain version
Documentation File system search, knowledge transfer interviews Requirements specs, design docs, test plans (% available)
Standards Exposure Code review, design patterns analysis Coding standards adherence (MISRA, CERT C), safety mechanisms
Test Coverage Coverage tools (gcov, VectorCAST) Statement coverage %, branch coverage %, test count

Example: Legacy ECU Assessment Report

The following diagram presents a sample legacy ECU assessment report, summarizing the gap analysis findings across documentation, traceability, test coverage, and coding standards compliance.

Legacy System Assessment: BCM ECU

Step 2: ASPICE Capability Level Baseline

Objective: Assess current ASPICE maturity using PAM (Process Assessment Model).

Assessment Approach:

  1. Self-Assessment: Development team completes ASPICE questionnaire
  2. Document Review: Auditors examine work products (code, specs, test reports)
  3. Interviews: Engineers, managers, QA personnel interviewed
  4. Tool Analysis: Automated checks for traceability, coverage, coding standards

Capability Levels (ASPICE 4.0):

  • Level 0 (Incomplete): Process not implemented or fails to achieve purpose
  • Level 1 (Performed): Process achieves its purpose (ad-hoc)
  • Level 2 (Managed): Process is planned, monitored, documented
  • Level 3 (Established): Process follows defined standards across organization
  • Level 4 (Predictable): Process operates within quantitative limits
  • Level 5 (Optimizing): Continuous process improvement

Example: BCM ECU Baseline Assessment

Process Current Level Evidence Target Level (Post-Retrofit)
SYS.2 (System Requirements Analysis) 0 (Incomplete) No system requirements document 2 (Managed)
SWE.1 (Software Requirements Analysis) 1 (Performed) Partial requirements in Word docs, outdated 2 (Managed)
SWE.2 (Software Architectural Design) 1 (Performed) High-level block diagrams, no interface specs 2 (Managed)
SWE.3 (Software Detailed Design) 1 (Performed) Code comments as design, inconsistent 2 (Managed)
SWE.4 (Software Unit Verification) 0 (Incomplete) No unit tests, manual desk checks 2 (Managed)
SWE.5 (Software Integration Test) 1 (Performed) Manual integration testing, no automation 2 (Managed)
SWE.6 (Software Qualification Test) 1 (Performed) Manual test checklists, 40% documented 2 (Managed)
SUP.8 (Configuration Management) 1 (Performed) Git since 2019, no baselines or branching strategy 2 (Managed)
SUP.9 (Problem Resolution) 1 (Performed) Bug tracking in Jira, no root cause analysis 2 (Managed)
SUP.10 (Change Request Management) 0 (Incomplete) Email-based change requests, no formal process 2 (Managed)

Overall Maturity: Capability Level 0-1 (ad-hoc, inconsistent processes) Target: Capability Level 2 (managed, documented, traceable)


Risk-Based Retrofit Strategy

Strategy Options

Option 1: Phased Retrofit (Recommended for Most Projects)

Approach: Incrementally improve ASPICE compliance while maintaining product functionality.

Phases:

  1. Phase 1 (Months 1-3): Establish foundational processes

    • Configuration management (Git branching, release tagging)
    • Requirements database setup (DOORS, Jama, Polarion)
    • Coding standards enforcement (MISRA C checker integration)
    • Problem tracking formalization (Jira workflows)
  2. Phase 2 (Months 4-6): Requirements and architecture recovery

    • Extract requirements from code and legacy docs (see Section 4)
    • Document software architecture (UML, SysML diagrams)
    • Establish bidirectional traceability (requirements ↔ code)
  3. Phase 3 (Months 7-12): Testing and verification

    • Develop unit test suite (target 80% coverage)
    • Automate integration tests (HIL/SiL)
    • Build regression test harness
  4. Phase 4 (Months 13-15): Safety and qualification

    • Hazard analysis and ASIL classification (ISO 26262)
    • Safety mechanism implementation (e.g., memory protection, diagnostic monitors)
    • Qualification test execution

Advantages:

  • Lower upfront cost (spread over 15 months)
  • Reduced technical risk (incremental changes)
  • Continuous product delivery (no "big bang" rewrite)

Disadvantages:

  • Longer calendar time
  • Requires disciplined change management
  • May accumulate technical debt if shortcuts taken

Option 2: Full Reengineering

Approach: Complete system redesign with modern architecture, followed by reimplementation.

Process:

  1. Months 1-2: Requirements elicitation from stakeholders (ignore legacy code)
  2. Months 3-4: Clean-sheet architecture design (layered, AUTOSAR-compliant)
  3. Months 5-10: Reimplementation with ASPICE from day one
  4. Months 11-12: Migration and validation

Advantages:

  • Highest quality result (no legacy cruft)
  • Opportunity to adopt modern practices (AUTOSAR, model-based development)
  • Clean ASPICE evidence (no retrofit artifacts)

Disadvantages:

  • Very high cost (2-3× phased retrofit)
  • High technical risk (reimplementation bugs)
  • Long schedule (12+ months with no intermediate releases)
  • Requires complete team retraining

When to Choose:

  • Legacy code is unmaintainable (> 50% cyclomatic complexity violations)
  • Architecture is fundamentally incompatible with safety requirements
  • Business case supports greenfield investment

Option 3: Hybrid Approach (Retrofit + Selective Rewrite)

Approach: Retrofit most modules, rewrite safety-critical components.

Example Strategy:

  • Retrofit (70% of codebase): Non-safety features (diagnostics, calibration, communication stacks)
  • Rewrite (30% of codebase): Safety-critical functions (e.g., motor control, brake actuation)

Advantages:

  • Balances risk and cost
  • Allows higher ASIL ratings for rewritten modules
  • Shorter timeline than full reengineering

Disadvantages:

  • Complex integration between legacy and new code
  • Requires clear module boundaries

Risk-Based Decision Matrix

Legacy System Characteristic Phased Retrofit Full Reengineering Hybrid
Age < 5 years [OK] Best fit Overkill Consider if safety-critical
Age 5-15 years [OK] Best fit If budget allows [OK] Good option
Age > 15 years High effort [OK] Best fit [OK] Good option
Complexity low (< 10 avg) [OK] Best fit Overkill Overkill
Complexity high (> 20 avg) Risky [OK] Best fit [OK] Best fit
Test coverage > 50% [OK] Best fit Overkill Consider
Test coverage < 20% Very risky [OK] Best fit [OK] Best fit
Documentation > 70% [OK] Best fit Not needed Consider
Documentation < 30% High effort [OK] Consider [OK] Best fit
Budget < $500K [OK] Only option Not feasible Consider
Budget $500K-$2M [OK] Best fit Consider [OK] Best fit
Budget > $2M Conservative [OK] Consider [OK] Best fit
Schedule < 6 months Aggressive Not feasible Not feasible
Schedule 6-18 months [OK] Best fit Tight [OK] Best fit
Schedule > 18 months [OK] Best fit [OK] Feasible [OK] Best fit

Recommendation for BCM ECU Case Study: Hybrid Approach (retrofit 70%, rewrite door lock safety functions as ASIL-C)


Traceability Establishment for Existing Code

Challenge: No Existing Requirements-to-Code Links

Legacy systems typically lack formal traceability:

  • Code written before requirements documented
  • Requirements in Word docs, code comments, or tribal knowledge
  • Manual desk checks instead of formal verification

Traceability Framework

ASPICE Requirements (SWE.1-BP7, SWE.2-BP7, SWE.3-BP7):

  • Bidirectional trace: Requirements → Design → Code → Tests
  • Consistency: Changes propagate through trace (requirement change → update code + tests)
  • Completeness: Every requirement has implementing code, every code module has requirement

Tool Selection:

Tool Strengths Cost Integration
IBM DOORS Next Industry standard, strong traceability, ISO 26262 workflows $5K-$15K/user/year Git, Jira, Jenkins
Jama Connect Modern UI, REST API, automotive templates $3K-$10K/user/year Git, Azure DevOps
Polarion ALM All-in-one (requirements + ALM), MathWorks integration $4K-$12K/user/year Simulink, Git
Codebeamer Agile-friendly, low-cost, ASPICE compliance $2K-$6K/user/year Git, Jenkins, MATLAB
Atlassian Jira (with plugins) Flexible, widely adopted, requires customization $10-$30/user/month Git, Confluence, Bamboo

Recommended for Legacy Retrofit: Codebeamer or Jama Connect (balance of cost, features, ease of adoption)

Traceability Establishment Process

Step 1: Import Legacy Requirements

# Python script to import legacy Word documents into Jama Connect
import docx
from jama import JamaClient

client = JamaClient(url="https://company.jamacloud.com", credentials=("user", "pass"))
project_id = 12345  # BCM ECU Project

# Parse legacy Word document
doc = docx.Document("Legacy_Requirements_BCM_v3.docx")
requirements = []

for para in doc.paragraphs:
    # Detect requirement pattern: "REQ-BCM-XXX: ..."
    if para.text.startswith("REQ-BCM-"):
        req_id = para.text.split(":")[0].strip()
        req_text = para.text.split(":", 1)[1].strip()
        requirements.append({"id": req_id, "text": req_text})

# Create requirements in Jama
for req in requirements:
    item = client.create_item(
        project=project_id,
        item_type="Software Requirement",
        fields={
            "name": req["id"],
            "description": req["text"],
            "status": "Approved (Legacy)",
            "source": "Migrated from Word doc (2011)"
        }
    )
    print(f"Created {req['id']} → Jama Item #{item['id']}")

Step 2: Annotate Code with Requirement IDs

// Legacy code BEFORE traceability annotation
void door_lock_control(void) {
    if (vehicle_speed > 5) {  // Lock doors above 5 km/h
        set_door_lock_state(LOCKED);
    }
}

// AFTER traceability annotation
/**
 * @brief Control automatic door locking based on vehicle speed
 * @requirement REQ-BCM-123: Doors shall lock when vehicle speed exceeds 5 km/h
 * @requirement REQ-BCM-124: Doors shall remain locked until driver unlocks or speed < 5 km/h
 * @asil ASIL-C (ISO 26262: inadvertent door opening hazard)
 */
void door_lock_control(void) {
    // REQ-BCM-123: Speed threshold check
    if (vehicle_speed > 5) {
        set_door_lock_state(LOCKED);
    }
    // REQ-BCM-124: Manual unlock override handled in set_door_lock_state()
}

Step 3: Automated Trace Extraction

# Extract requirement traces from annotated source code
import re
from pathlib import Path

def extract_traces_from_code(source_dir):
    """Parse C code for @requirement annotations"""
    traces = []  # List of (file, line, requirement_id)

    for c_file in Path(source_dir).rglob("*.c"):
        with open(c_file, 'r') as f:
            for line_num, line in enumerate(f, start=1):
                # Match: @requirement REQ-XXX-YYY: description
                match = re.search(r'@requirement\s+(REQ-[A-Z]+-\d+)', line)
                if match:
                    req_id = match.group(1)
                    traces.append({
                        "file": str(c_file),
                        "line": line_num,
                        "requirement": req_id
                    })

    return traces

# Generate traceability matrix
traces = extract_traces_from_code("/path/to/bcm_src")
for trace in traces:
    print(f"{trace['requirement']}{trace['file']}:{trace['line']}")

# Upload to Jama (create requirement-to-code relationships)
for trace in traces:
    req_item = client.get_item_by_name(trace['requirement'])
    client.create_relationship(
        from_item=req_item['id'],
        to_item=f"Code:{trace['file']}:{trace['line']}",
        relationship_type="implemented_by"
    )

Step 4: Validate Completeness

-- SQL query to find orphaned requirements (no code implementation)
SELECT r.id, r.name, r.description
FROM requirements r
LEFT JOIN relationships rel ON r.id = rel.from_item_id AND rel.type = 'implemented_by'
WHERE rel.to_item_id IS NULL
ORDER BY r.id;

-- SQL query to find orphaned code (no requirement justification)
-- (Requires static analysis tool integration, e.g., SonarQube + Jama plugin)

Requirements Extraction from Legacy Code

Reverse Engineering Requirements

Challenge: For systems with < 30% requirements documentation, must extract implicit requirements from:

  • Source code logic
  • Code comments
  • Legacy test cases
  • Domain expert interviews
  • Regulatory standards (inferred from safety mechanisms)

Extraction Techniques

Technique 1: Static Code Analysis

Tools:

  • Understand (SciTools): Code navigation, dependency graphs, call trees
  • Lattix: Architecture extraction, module dependencies
  • Doxygen: Generate documentation from code comments

Example: Extract Control Logic Requirements

// Legacy code fragment (no explicit requirement)
void temperature_sensor_monitor(void) {
    int16_t temp_degC = read_adc_temperature();

    if (temp_degC > 125) {
        set_error_code(ERR_TEMP_OVERTEMP);
        shutdown_power_stage();
    }

    if (temp_degC < -40) {
        set_error_code(ERR_TEMP_UNDERTEMP);
        enable_heater();
    }
}

// Extracted requirements (reverse-engineered):
// REQ-BCM-TEMP-001: System shall monitor junction temperature every 100ms
// REQ-BCM-TEMP-002: If temperature > 125°C, system shall enter safe state (power-off)
// REQ-BCM-TEMP-003: If temperature < -40°C, system shall activate heating element
// REQ-BCM-TEMP-004: Temperature faults shall be logged with error code (ERR_TEMP_*)

AI-Assisted Extraction (Large Language Models):

# Use GPT-4 / Claude to extract requirements from legacy code
import anthropic

client = anthropic.Anthropic(api_key="sk-ant-...")

code_snippet = """
void brake_control_loop(void) {
    uint16_t pressure_bar = read_brake_pressure_sensor();
    if (pressure_bar > MAX_PRESSURE) {
        release_brake_actuator();
        log_fault(FAULT_OVERPRESSURE);
    }
}
"""

prompt = f"""
You are a safety engineer analyzing legacy automotive code.
Extract functional safety requirements from this code snippet:

{code_snippet}

Format each requirement as:
REQ-ID: [Requirement text]
ASIL: [A/B/C/D or QM]
Rationale: [Why this requirement exists]
"""

message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=2048,
    messages=[{"role": "user", "content": prompt}]
)

print(message.content[0].text)

# Example AI output:
# REQ-BCM-BRK-001: Brake control loop shall monitor hydraulic pressure continuously
# ASIL: ASIL-D (braking is safety-critical)
# Rationale: Overpressure can cause brake failure or ABS malfunction
#
# REQ-BCM-BRK-002: If pressure > MAX_PRESSURE, system shall release actuator
# ASIL: ASIL-D
# Rationale: Prevent hydraulic line rupture (hazard analysis item H-BRK-03)
#
# REQ-BCM-BRK-003: Overpressure events shall be logged with fault code
# ASIL: ASIL-B (diagnostic requirement)
# Rationale: Required for ISO 26262 Part 4 (fault detection and handling)

Technique 2: Test Case Analysis

Approach: Reverse-engineer requirements from existing test cases.

Example: Manual Test Checklist → Requirements

Legacy Test Case (from Excel spreadsheet):
┌────────────────────────────────────────────────────────────┐
│ Test ID: TC-BCM-045                                         │
│ Description: Door lock on speed                             │
│ Preconditions: Vehicle stationary, doors unlocked           │
│ Steps:                                                      │
│   1. Start engine                                           │
│   2. Accelerate to 10 km/h                                  │
│   3. Verify doors locked                                    │
│ Expected Result: All doors lock within 2 seconds           │
│ Status: PASS (last tested: 2019-03-12)                     │
└────────────────────────────────────────────────────────────┘

Extracted Requirements:
REQ-BCM-LOCK-001: Doors shall automatically lock when vehicle speed exceeds 5 km/h
REQ-BCM-LOCK-002: Door locking shall occur within 2 seconds of speed threshold breach
REQ-BCM-LOCK-003: Door lock function shall apply to all 4 doors simultaneously

Technique 3: Domain Expert Interviews

Structured Interview Template:

REQUIREMENT ELICITATION INTERVIEW
System: BCM ECU Door Lock Module
Interviewee: [Original developer / System engineer]
Date: 2026-01-10

Q1: What are the main functions of the door lock module?
A: Automatic locking above speed, central locking via key fob, child safety lock

Q2: What safety hazards does this module address?
A: Inadvertent door opening during driving (ASIL-C), child ejection (ASIL-D)

Q3: What are the failure modes and safe states?
A: If sensors fail, doors remain in last known state (fail-safe: locked if moving)

Q4: What regulatory requirements apply?
A: FMVSS 206 (door locks and retention), ECE R11 (door latches)

Q5: What environmental conditions must the system handle?
A: -40°C to +85°C, EMC (ISO 11452), voltage transients (ISO 7637)

Extracted Requirements:
REQ-BCM-LOCK-SAFETY-001: Door lock module shall achieve ASIL-C (inadvertent opening hazard)
REQ-BCM-LOCK-SAFETY-002: In case of sensor failure, doors shall remain locked if vehicle speed > 0
REQ-BCM-LOCK-REG-001: Door lock mechanism shall comply with FMVSS 206 retention force (>4500 N)
REQ-BCM-LOCK-ENV-001: Module shall operate across temperature range -40°C to +85°C

Architecture Modernization Path

Assessing Legacy Architecture

Common Legacy Architecture Patterns (pre-ASPICE era):

  1. Big Ball of Mud: No clear module boundaries, global variables, spaghetti dependencies
  2. God Object: Single mega-module (e.g., main.c with 10,000+ lines)
  3. Layering Violations: Application code directly accessing hardware registers
  4. Tight Coupling: Modules with circular dependencies

Example: Legacy BCM Architecture (Problematic)

┌────────────────────────────────────────────────────────────────┐
│                         main.c (8,500 lines)                    │
│  - CAN message handling                                        │
│  - Door lock logic                                             │
│  - Window control                                              │
│  - Diagnostics                                                 │
│  - Hardware abstraction (GPIO, ADC, PWM)                       │
│  - Global variables: 127 declared                              │
└────────────────────────────────────────────────────────────────┘
          │                    │                    │
          ▼                    ▼                    ▼
  ┌─────────────┐      ┌─────────────┐      ┌─────────────┐
  │ CAN Driver  │      │ EEPROM Lib  │      │  OSEK-OS    │
  │ (vendor lib)│      │ (custom)    │      │ (3rd party) │
  └─────────────┘      └─────────────┘      └─────────────┘

Problems:
- No module interfaces (everything calls everything)
- Cannot unit test (all code in main.c)
- Hardware-dependent (impossible to simulate)
- High coupling (change in door lock breaks window control)

Target Architecture: Layered ASPICE-Compliant Design

Recommended Architecture (AUTOSAR-inspired layering):

┌─────────────────────────────────────────────────────────────────┐
│                    Application Layer (ASIL-C)                    │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ Door Lock    │  │ Window Ctrl  │  │ Diagnostics  │          │
│  │ Manager      │  │ Manager      │  │ Manager      │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
└─────────────────────────────────────────────────────────────────┘
                            │ (Function calls via API)
┌─────────────────────────────────────────────────────────────────┐
│                   Service Layer (ASIL-A/QM)                      │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ COM Manager  │  │ NVM Manager  │  │ Diagnostic   │          │
│  │ (CAN stack)  │  │ (EEPROM)     │  │ Event Mgr    │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
└─────────────────────────────────────────────────────────────────┘
                            │ (Standardized interfaces)
┌─────────────────────────────────────────────────────────────────┐
│                Hardware Abstraction Layer (HAL)                  │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ GPIO Driver  │  │ CAN Driver   │  │ ADC Driver   │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
└─────────────────────────────────────────────────────────────────┘
                            │ (Memory-mapped I/O)
┌─────────────────────────────────────────────────────────────────┐
│                  Microcontroller Abstraction Layer (MCAL)        │
│                  (Vendor drivers: Infineon iLLD)                 │
└─────────────────────────────────────────────────────────────────┘

Benefits:
[OK] Clear module boundaries (testable in isolation)
[OK] Hardware independence (HAL enables simulation)
[OK] ASIL decomposition (safety-critical in App layer only)
[OK] Reusability (Service layer portable across projects)

Refactoring Strategy

Incremental Refactoring Steps (Phased Retrofit):

  1. Phase 1: Extract Hardware Abstraction Layer (HAL)

    • Wrap all hardware register access in HAL functions
    • Replace direct register writes with HAL_GPIO_WritePin(PORT_A, PIN_3, HIGH)
    • Goal: Enable unit testing on host PC (mock HAL in tests)
  2. Phase 2: Modularize Application Layer

    • Split main.c into functional modules (door lock, window, diagnostics)
    • Define clear APIs between modules (.h interface files)
    • Eliminate global variables (replace with getter/setter functions or context structs)
  3. Phase 3: Introduce Service Layer

    • Abstract CAN communication (COM Manager with signal-level API)
    • Abstract EEPROM access (NVM Manager with block read/write)
    • Centralize error handling (Diagnostic Event Manager)
  4. Phase 4: AUTOSAR Alignment (Optional)

    • If migrating to AUTOSAR, map modules to Software Components (SWCs)
    • Use AUTOSAR RTE (Runtime Environment) for inter-SWC communication

Example: Refactoring Door Lock Module

Before (Legacy Monolith):

// main.c (fragment)
uint8_t door_lock_state = 0;  // Global variable
uint16_t vehicle_speed = 0;   // Global variable

void main_loop(void) {
    // Read CAN message (direct hardware access)
    if (CAN1_RX_FIFO & 0x01) {
        uint32_t can_data = CAN1_DATA_REG;
        vehicle_speed = (can_data >> 8) & 0xFFFF;
    }

    // Door lock logic (mixed with other code)
    if (vehicle_speed > 5) {
        PORTB |= (1 << PB3);  // Direct GPIO write (lock solenoid)
        door_lock_state = 1;
    }
}

After (Modular ASPICE-Compliant):

// door_lock_manager.h (API definition)
#ifndef DOOR_LOCK_MANAGER_H
#define DOOR_LOCK_MANAGER_H

#include <stdint.h>

/**
 * @brief Initialize door lock module
 * @requirement REQ-BCM-LOCK-INIT-001
 */
void DoorLock_Init(void);

/**
 * @brief Periodic task for door lock control (call every 100ms)
 * @requirement REQ-BCM-LOCK-CTRL-001
 */
void DoorLock_MainFunction(void);

/**
 * @brief Get current door lock state
 * @return 0 = unlocked, 1 = locked
 */
uint8_t DoorLock_GetState(void);

#endif

// door_lock_manager.c (implementation)
#include "door_lock_manager.h"
#include "com_manager.h"       // For CAN signal access
#include "hal_gpio.h"          // Hardware abstraction

typedef struct {
    uint8_t lock_state;        // Private state (encapsulated)
    uint16_t speed_threshold;  // Configuration parameter
} DoorLockContext_t;

static DoorLockContext_t ctx = {
    .lock_state = 0,
    .speed_threshold = 5  // km/h (from requirement REQ-BCM-LOCK-001)
};

void DoorLock_Init(void) {
    HAL_GPIO_Init(GPIO_PORT_B, GPIO_PIN_3, GPIO_MODE_OUTPUT);
    ctx.lock_state = 0;
}

void DoorLock_MainFunction(void) {
    // Get vehicle speed from COM Manager (abstracted CAN access)
    uint16_t speed_kmh = COM_GetSignal(SIGNAL_ID_VEHICLE_SPEED);

    // REQ-BCM-LOCK-001: Lock doors when speed > threshold
    if (speed_kmh > ctx.speed_threshold && ctx.lock_state == 0) {
        HAL_GPIO_WritePin(GPIO_PORT_B, GPIO_PIN_3, GPIO_HIGH);
        ctx.lock_state = 1;
    }

    // REQ-BCM-LOCK-002: Unlock when speed < threshold and driver requests
    if (speed_kmh < ctx.speed_threshold && COM_GetSignal(SIGNAL_ID_UNLOCK_REQ)) {
        HAL_GPIO_WritePin(GPIO_PORT_B, GPIO_PIN_3, GPIO_LOW);
        ctx.lock_state = 0;
    }
}

uint8_t DoorLock_GetState(void) {
    return ctx.lock_state;
}

Benefits:

  • Unit testable (mock COM_GetSignal() and HAL_GPIO_WritePin())
  • Clear requirements traceability (comments reference REQ-BCM-LOCK-*)
  • No global variables (encapsulated in DoorLockContext_t)
  • Hardware-independent (HAL abstraction enables PC-based testing)

Testing Strategy for Retrofit

Challenge: Building Test Coverage for Untested Code

Legacy systems often have 0-30% automated test coverage. Retrofit requires:

  1. Regression test suite: Prevent new bugs during refactoring
  2. Unit tests: Achieve 80-100% coverage for ASPICE SWE.4
  3. Integration tests: Validate module interactions
  4. HiL tests: System-level validation on target hardware

Recommended Testing Pyramid

                    ┌────────────────┐
                    │  HiL Tests     │  10% of tests, 100% system coverage
                    │  (10 tests)    │  Example: Full vehicle simulation
                    └────────────────┘
                          │
                ┌────────────────────────┐
                │ Integration Tests      │  30% of tests, API coverage
                │ (50 tests)             │  Example: Door lock + CAN stack
                └────────────────────────┘
                          │
          ┌────────────────────────────────────┐
          │       Unit Tests                   │  60% of tests, code coverage
          │       (200 tests)                  │  Example: Individual functions
          └────────────────────────────────────┘

Test Development Strategy

Step 1: Characterization Tests (Prevent Regressions)

Objective: Lock in existing behavior before refactoring.

// Characterization test: Capture current behavior (even if buggy)
void test_door_lock_legacy_behavior(void) {
    /**
     * Purpose: Document existing behavior before refactoring
     * Note: This test captures a BUG (lock should trigger at 5 km/h, not 6)
     *       Once refactored, update test to match REQ-BCM-LOCK-001
     */

    // Setup: Vehicle stationary
    COM_SetSignal(SIGNAL_ID_VEHICLE_SPEED, 0);
    DoorLock_Init();

    // Act: Accelerate to 6 km/h (legacy threshold, incorrect per requirement)
    COM_SetSignal(SIGNAL_ID_VEHICLE_SPEED, 6);
    DoorLock_MainFunction();

    // Assert: Doors lock (capturing legacy behavior)
    assert(DoorLock_GetState() == 1);  // Will FAIL after fix → update test
}

Step 2: Requirements-Based Unit Tests

// Unit test: Verify requirement REQ-BCM-LOCK-001
void test_door_lock_activates_at_5kmh(void) {
    /**
     * @requirement REQ-BCM-LOCK-001: Doors shall lock when speed > 5 km/h
     * @test_type Unit Test
     * @aspice SWE.4-BP2 (Unit verification)
     */

    // Arrange: Initialize module, set speed = 5 km/h (below threshold)
    DoorLock_Init();
    COM_SetSignal(SIGNAL_ID_VEHICLE_SPEED, 5);
    DoorLock_MainFunction();
    assert(DoorLock_GetState() == 0);  // Still unlocked

    // Act: Increase speed to 6 km/h (above threshold)
    COM_SetSignal(SIGNAL_ID_VEHICLE_SPEED, 6);
    DoorLock_MainFunction();

    // Assert: Doors locked
    assert(DoorLock_GetState() == 1);
}

// Unit test: Edge case (exactly at threshold)
void test_door_lock_threshold_boundary(void) {
    /**
     * @requirement REQ-BCM-LOCK-001 (boundary condition)
     * @test_type Boundary Value Analysis
     */

    DoorLock_Init();

    // Exactly 5 km/h: Should NOT lock (threshold is > 5, not ≥ 5)
    COM_SetSignal(SIGNAL_ID_VEHICLE_SPEED, 5);
    DoorLock_MainFunction();
    assert(DoorLock_GetState() == 0);

    // 5.1 km/h: Should lock
    COM_SetSignal(SIGNAL_ID_VEHICLE_SPEED, 5.1);  // Assuming 0.1 km/h resolution
    DoorLock_MainFunction();
    assert(DoorLock_GetState() == 1);
}

// Unit test: Fault injection (sensor failure)
void test_door_lock_sensor_fault_handling(void) {
    /**
     * @requirement REQ-BCM-LOCK-SAFETY-002: If sensor fails, doors remain in last state
     * @test_type Fault Injection
     * @asil ASIL-C
     */

    // Setup: Doors locked, vehicle moving
    DoorLock_Init();
    COM_SetSignal(SIGNAL_ID_VEHICLE_SPEED, 50);
    DoorLock_MainFunction();
    assert(DoorLock_GetState() == 1);

    // Inject fault: Speed sensor returns invalid value (0xFFFF)
    COM_SetSignal(SIGNAL_ID_VEHICLE_SPEED, 0xFFFF);  // Fault condition
    DoorLock_MainFunction();

    // Assert: Doors remain locked (safe state)
    assert(DoorLock_GetState() == 1);
    assert(COM_GetSignal(SIGNAL_ID_FAULT_SPEED_SENSOR) == 1);  // Fault flagged
}

Step 3: Coverage-Guided Testing

Tools:

  • gcov/lcov: Open-source coverage for GCC
  • VectorCAST: Commercial tool with MC/DC coverage (ISO 26262 ASIL-D)
  • Tessy: Embedded unit testing with automatic test generation

Process:

  1. Run existing tests → measure coverage
  2. Identify uncovered branches
  3. Write tests for uncovered code
  4. Repeat until target coverage achieved (80% for ASIL-C)

Example: Coverage Report Analysis

Coverage Report: door_lock_manager.c
├─ Statement Coverage: 85% (43/50 statements)
├─ Branch Coverage: 78% (14/18 branches)
├─ MC/DC Coverage: 72% (requires additional tests for ASIL-C)

Uncovered Code:
Line 87: if (ctx.speed_threshold > MAX_SPEED_THRESHOLD) { ... }
  → Missing test: Invalid configuration parameter
  → Add test: test_door_lock_invalid_config()

Line 102: if (eeprom_read_error) { ... }
  → Missing test: EEPROM read failure
  → Add test: test_door_lock_eeprom_fault()

Multi-Standard Context: ASPICE + ISO 26262

Aligning Retrofit with Functional Safety

Key Integration Points:

ASPICE Process ISO 26262 Equivalent Retrofit Activity
SYS.2 (System Requirements) Part 3: Item definition, Part 4: System requirements Hazard analysis, ASIL classification, safety goals
SWE.1 (Software Requirements) Part 6: Software safety requirements Derive software safety requirements from hazard analysis
SWE.2 (Software Architecture) Part 6: Architectural design (Clause 7) ASIL decomposition, freedom from interference
SWE.3 (Detailed Design) Part 6: Unit design and implementation (Clause 8) Coding standards (MISRA C), static analysis
SWE.4 (Unit Verification) Part 6: Unit testing (Clause 9) Unit test coverage (statement, branch, MC/DC)
SWE.5 (Integration Test) Part 6: Software integration and testing (Clause 10) Interface testing, fault injection
SWE.6 (Qualification Test) Part 4: System testing (Clause 8) HiL testing, safety mechanism validation
SUP.1 (Quality Assurance) Part 8: Functional safety audits Independent safety assessment

Case Study: BCM ECU Retrofit to ISO 26262 ASIL-C

System: Body Control Module (BCM) with automatic door locking feature Legacy State: No ASIL classification, informal development process Target: ASIL-C compliance (inadvertent door opening hazard) Timeline: 18 months Budget: $1.2M

Retrofit Phases

Phase 1: Hazard Analysis and Risk Assessment (Months 1-2)

Activities:

  1. Item Definition (ISO 26262-3 Clause 5): Define BCM ECU scope, interfaces, dependencies
  2. Hazard Analysis (HARA, ISO 26262-3 Clause 6): Identify door lock hazards
  3. ASIL Determination: Classify hazards using Severity-Exposure-Controllability

Results:

┌─────────────────────────────────────────────────────────────────────────────┐
│ Hazard Analysis: BCM Door Lock System                                       │
├─────────────────────────────────────────────────────────────────────────────┤
│ Hazard ID: H-BCM-001                                                         │
│ Description: Inadvertent door opening during vehicle motion                 │
│ Severity: S3 (Severe injuries, survival probable)                           │
│ Exposure: E4 (High probability, occurs frequently)                          │
│ Controllability: C2 (Normally controllable by driver)                       │
│ ASIL: C (S3 × E4 × C2 → ASIL-C per ISO 26262-3 Table 4)                     │
├─────────────────────────────────────────────────────────────────────────────┤
│ Safety Goal: SG-BCM-001                                                      │
│ "Doors shall remain closed during vehicle motion to prevent occupant        │
│  ejection (ASIL-C)"                                                         │
├─────────────────────────────────────────────────────────────────────────────┤
│ Functional Safety Requirements:                                             │
│ FSR-BCM-001: Door lock actuators shall remain engaged when speed > 5 km/h   │
│              (ASIL-C)                                                       │
│ FSR-BCM-002: Door lock module shall detect actuator faults within 100ms     │
│              (ASIL-C)                                                       │
│ FSR-BCM-003: In case of fault, doors shall remain in locked state (safe     │
│              state) (ASIL-C)                                                │
└─────────────────────────────────────────────────────────────────────────────┘

Phase 2: Requirements and Architecture (Months 3-6)

Activities:

  1. Extract legacy requirements (see Section 4)
  2. Derive software safety requirements from FSRs
  3. Refactor architecture to enable ASIL decomposition

Architecture Decision: ASIL Decomposition

Original Architecture (All ASIL-C):
┌──────────────────────────────────────────┐
│  Door Lock Module (ASIL-C)               │
│  - Speed monitoring                       │
│  - Lock control logic                     │
│  - Actuator driver                        │
│  - Self-diagnostics                       │
└──────────────────────────────────────────┘
Problem: Entire module requires ASIL-C rigor (expensive testing, certified tools)

Decomposed Architecture (ASIL-C + ASIL-A):
┌──────────────────────────────────────────┐
│  Safety Monitor (ASIL-C)                 │  ← Lightweight, high-integrity
│  - Independent speed plausibility check   │
│  - Lock state verification                │
│  - Fault detection                        │
└──────────────────────────────────────────┘
              ↓ (Monitors)
┌──────────────────────────────────────────┐
│  Lock Control (ASIL-A)                   │  ← Main logic, lower rigor
│  - Speed-based lock decision              │
│  - Actuator command                       │
└──────────────────────────────────────────┘

Benefits:
- Safety Monitor is small, simple (easier to achieve ASIL-C)
- Lock Control can use standard tools (ASIL-A allows GCC without qualification)
- Satisfies ISO 26262-9 Clause 5 (ASIL decomposition with independence)

Phase 3: Implementation and Verification (Months 7-15)

Activities:

  1. Refactor code to match new architecture (see Section 5)
  2. Implement safety mechanisms (watchdog, CRC, plausibility checks)
  3. Develop unit tests (100% MC/DC for ASIL-C modules)
  4. Conduct integration testing (fault injection, timing analysis)

Test Metrics (ISO 26262-6 Table 13):

┌─────────────────────────────────────────────────────────────────┐
│ Test Coverage Summary (BCM Door Lock Retrofit)                  │
├─────────────────────────────────────────────────────────────────┤
│ Module: Safety Monitor (ASIL-C)                                │
│ ├─ Statement Coverage: 100% (45/45 statements)                  │
│ ├─ Branch Coverage: 100% (12/12 branches)                       │
│ ├─ MC/DC Coverage: 100% (12/12 conditions)                      │
│ └─ Fault Injection: 100% (8/8 faults detected within 100ms)     │
├─────────────────────────────────────────────────────────────────┤
│ Module: Lock Control (ASIL-A, decomposed from ASIL-C)          │
│ ├─ Statement Coverage: 98% (87/89 statements)                   │
│ ├─ Branch Coverage: 100% (24/24 branches)                       │
│ └─ Integration Tests: 42 test cases (all PASS)                  │
├─────────────────────────────────────────────────────────────────┤
│ System-Level (HiL Testing)                                      │
│ ├─ Functional Tests: 23/23 PASS                                 │
│ ├─ Safety Mechanism Tests: 8/8 PASS                             │
│ ├─ Environmental Tests: 12/12 PASS (-40°C to +85°C, EMC)        │
│ └─ Endurance Tests: 1,000,000 lock/unlock cycles (no failures)  │
└─────────────────────────────────────────────────────────────────┘

Phase 4: Qualification and Certification (Months 16-18)

Activities:

  1. Generate safety case (argumentation that ASIL-C achieved)
  2. Independent safety assessment (ISO 26262-2 Clause 6)
  3. Functional safety audit (SUP.1, ISO 26262-8 Clause 14)
  4. Release for production

Deliverables:

  • Safety plan (work product 02-06 per ASPICE)
  • Hazard analysis report (HARA)
  • Safety requirements specification (SRS)
  • Safety architecture design
  • Unit test reports with MC/DC coverage
  • Integration test reports
  • HiL test reports
  • Safety validation report
  • Functional safety assessment report (from independent assessor)
  • Safety case documentation

Cost Estimation and ROI Analysis

Cost Model: BCM ECU Retrofit (15-Year-Old System)

Cost Category Phased Retrofit (18 months) Full Reengineering (24 months)
Labor
- Requirements engineering (2 FTE) $240K $360K
- Software development (4 FTE) $480K $960K
- Testing/QA (2 FTE) $240K $480K
- Safety engineering (1 FTE) $180K $240K
- Project management (0.5 FTE) $90K $120K
Tools & Licenses
- Requirements management (Jama) $30K $30K
- Static analysis (LDRA, Polyspace) $60K $60K
- Test automation (VectorCAST) $40K $40K
- HiL platform (dSpace) $150K $150K
External Services
- Independent safety assessor $80K $120K
- ASPICE audit $40K $60K
- Training (team upskilling) $30K $50K
Contingency (20%) $230K $534K
Total $1.85M $3.20M

Break-even Analysis:

Scenario: OEM requires ASPICE CL2 + ISO 26262 ASIL-C for new vehicle platform contract.

Without Retrofit:

  • Lose contract (opportunity cost: $50M revenue over 5 years)
  • OR: Develop new ECU from scratch ($4M, 24 months) → Late to market penalty

With Phased Retrofit:

  • Investment: $1.85M
  • Time to market: 18 months (vs. 24 for greenfield)
  • Revenue: $50M contract secured
  • ROI: ($50M - $1.85M) / $1.85M = 2600% over 5 years

Payback Period: < 1 year after first vehicle delivery


Team Training and Change Management

Skills Gap Analysis

Legacy Team Skills (Typical pre-ASPICE era):

  • C programming (strong)
  • Hardware debugging (strong)
  • Domain knowledge (automotive, strong)
  • Requirements engineering (weak)
  • Formal testing (weak)
  • Safety standards (none)

Required Skills for ASPICE Retrofit:

  • Requirements management tools (DOORS, Jama)
  • Architecture modeling (UML, SysML)
  • Unit testing frameworks (Tessy, VectorCAST)
  • Static analysis interpretation (MISRA violations, code smells)
  • ISO 26262 fundamentals

Training Plan

Training Module Duration Audience Delivery Method
ASPICE Fundamentals 2 days All engineers, PM Instructor-led workshop
ISO 26262 Awareness 1 day All engineers Online course + exam
Requirements Engineering 3 days SW architects, leads Hands-on with Jama
Software Testing (Unit, Integration) 5 days All SW engineers Instructor-led + lab
MISRA C Coding Standards 1 day All SW engineers Online + code review practice
Safety Mechanisms Design 2 days Safety-critical module owners Instructor-led
Tool Training (VectorCAST, LDRA) 2 days QA engineers Vendor-provided

Total Training Investment: $30K (phased retrofit), 16 days per engineer (spread over 6 months)

Change Management Strategy

Challenges:

  • Resistance to "bureaucratic" ASPICE processes
  • Fear of blame for legacy code defects
  • Learning curve for new tools

Mitigation:

  1. Executive Sponsorship: VP of Engineering champions retrofit, explains business case
  2. Incremental Adoption: Start with one module (door lock), demonstrate success
  3. Celebrate Wins: Recognize team when milestones achieved (e.g., first 80% coverage module)
  4. Blame-Free Culture: Legacy defects are "archeological discoveries," not engineer failures
  5. Tool Support: Provide dedicated tool experts (license champions)

Lessons Learned and Best Practices

What Works

  1. Start with high-value modules: Retrofit safety-critical functions first (door lock, airbag) → immediate ASIL compliance
  2. Invest in traceability early: Requirements database pays off throughout retrofit (test generation, impact analysis)
  3. Automate relentlessly: Manual testing is bottleneck → invest in test automation infrastructure
  4. Leverage AI for requirements extraction: LLMs (GPT-4, Claude) accelerate reverse engineering
  5. Phased approach beats "big bang": Incremental delivery maintains business continuity

Common Pitfalls

  1. Underestimating effort: Legacy code is often 2-3× more complex than expected → pad estimates by 50%
  2. Skipping characterization tests: Refactoring without regression tests introduces new bugs
  3. Ignoring toolchain qualification: Using unqualified tools for ASIL-C/D → certification failure
  4. Poor change management: Team burnout from excessive process overhead → involve engineers in process design
  5. Inadequate documentation: "We'll document later" never happens → enforce documentation as part of done

Conclusion and Recommendations

Decision Framework: Retrofit vs. Rewrite

Choose Phased Retrofit if:

  • Age < 20 years
  • Test coverage > 20%
  • Documentation > 30%
  • Budget < $2M
  • Schedule < 18 months
  • Business requires incremental delivery

Choose Full Reengineering if:

  • Age > 20 years OR complexity unmanageable (avg cyclomatic > 25)
  • Test coverage < 10%
  • Documentation < 10%
  • Budget > $3M available
  • Schedule allows 24+ months
  • Business case supports greenfield investment (platform reuse across product line)

Choose Hybrid Approach if:

  • Mixed maturity (some modules testable, others "black boxes")
  • Safety-critical modules need ASIL-D (rewrite), QM modules can be retrofitted
  • Team has capacity for parallel workstreams

Key Success Factors

  1. Executive commitment: Retrofit requires sustained investment (18+ months)
  2. Phased delivery: Demonstrate value early (first module retrofit in 3 months)
  3. Tool infrastructure: Requirements DB, test automation, static analysis
  4. Training investment: Upskill team on ASPICE, safety, testing
  5. External expertise: Hire experienced safety consultants for ISO 26262 guidance

Next Steps

After completing ASPICE retrofit:

  1. Expand to full ASPICE CL3: Establish organization-wide processes (MAN.3, MAN.5, MAN.6)
  2. Automate compliance evidence: Generate ASPICE work products from CI/CD pipeline
  3. Continuous improvement: Measure defect density, test coverage trends → optimize processes

Next Chapter: Chapter 16.2 Model-Based Development with MATLAB - Leverage Simulink for next-generation ASPICE-compliant embedded systems.


References

  • VDA: Automotive SPICE PAM 4.0 (2023)
  • ISO 26262:2018: Road Vehicles - Functional Safety (Parts 1-12)
  • IEC 61508:2010: Functional Safety of Electrical/Electronic/Programmable Electronic Safety-Related Systems
  • DO-178C: Software Considerations in Airborne Systems and Equipment Certification (2011)
  • Feathers, Michael: "Working Effectively with Legacy Code" (Prentice Hall, 2004)
  • Seacord, Robert: "The CERT C Coding Standard" (Addison-Wesley, 2014)
  • Martin, Robert C.: "Clean Architecture" (Prentice Hall, 2017)
  • Lyu, Michael R.: "Handbook of Software Reliability Engineering" (IEEE Computer Society, 1996)