Functional Safety

Complete Guide to Table H.2 Fault Control Measures

IEC 60730-1 Table H.2 defines 7 core measures for software fault control. This article provides detailed analysis of requirements, implementation methods, and verification points for each measure.

19 min read
Complete Guide to Table H.2 Fault Control Measures

Complete Guide to Table H.2 Fault Control Measures

1. Table H.2 Overview and Purpose

1.1 Positioning of Table H.2 in the Standard

IEC 60730-1 Annex H addresses functional safety requirements for electronic controls using software, and Table H.2 represents the core content of this appendix, defining acceptable fault/error control techniques for different component failures.

Table H.2 is based on a fundamental assumption: all hardware and software components can fail. The standard requires appropriate detection and control measures to ensure the system can achieve or maintain a safe state when faults occur.

1.2 Core Structure of Table H.2

Table H.2 is organized by component type, covering the following 7 main categories:

No.Component CategoryFailure ModeClass B Minimum Requirement
1.1CPU RegistersStuck-at/DC faultsPeriodic self-test or functional test
1.2InterruptsNo interrupt or too frequentTime-slot monitoring
1.3Program CounterStuck-at faultsLogical monitoring or time-slot monitoring
3ClockIncorrect frequencyFrequency monitoring or time-slot monitoring
4.1Non-volatile Memory (Flash/ROM)Single bit faultCRC or modified checksum
4.2Variable Memory (RAM)DC faultsStatic memory test or redundancy protection
5Data Path/External CommunicationHamming distance 3/4CRC or transfer redundancy
6Input/Output UnitsFault conditionsPlausibility check or output verification

1.3 Legend

Symbols used in Table H.2:

  • rq: required - The measure is mandatory
  • rec: recommended - The measure is recommended

2. Detailed Explanation of Fault Control Measures

2.1 CPU Register Testing

2.1.1 Failure Mode Analysis

Failure Types:

  • Stuck-at faults: Register bits fixed at 0 or 1
  • DC faults: Decoupling faults, adjacent cells affecting each other
  • Address decoding faults: Accessing wrong registers

2.1.2 Class B Acceptable Measures

According to Table H.2, for CPU register faults, Class B accepts the following measures:

  1. Functional test
  2. Periodic self-test:
    • Static memory test
    • Word protection with single bit redundancy

2.1.3 Implementation: Static Memory Test

// CPU register static test example
typedef struct {
    uint32_t r0;
    uint32_t r1;
    uint32_t r2;
    // ... other registers
} CPU_Registers_t;

#define TEST_PATTERN_1  0xAAAAAAAA
#define TEST_PATTERN_2  0x55555555
#define TEST_PATTERN_3  0xFFFFFFFF
#define TEST_PATTERN_4  0x00000000

bool TestCPURegisters(void) {
    volatile CPU_Registers_t regs;
    uint32_t backup;

    // Backup original value
    backup = regs.r0;

    // Test pattern 1: Alternating bit pattern
    regs.r0 = TEST_PATTERN_1;
    if(regs.r0 != TEST_PATTERN_1) return false;

    // Test pattern 2: Reverse alternating bits
    regs.r0 = TEST_PATTERN_2;
    if(regs.r0 != TEST_PATTERN_2) return false;

    // Test pattern 3: All 1s
    regs.r0 = TEST_PATTERN_3;
    if(regs.r0 != TEST_PATTERN_3) return false;

    // Test pattern 4: All 0s
    regs.r0 = TEST_PATTERN_4;
    if(regs.r0 != TEST_PATTERN_4) return false;

    // Restore original value
    regs.r0 = backup;

    return true;
}

2.1.4 Single Bit Redundancy Word Protection

// Single bit parity check example
uint8_t CalculateParity(uint32_t data) {
    uint8_t parity = 0;
    while(data) {
        parity ^= (data & 1);
        data >>= 1;
    }
    return parity;
}

bool CheckRegisterWithParity(uint32_t reg) {
    uint8_t stored_parity = GetStoredParity(reg);
    uint8_t calculated_parity = CalculateParity(reg);
    return (stored_parity == calculated_parity);
}

2.1.5 Test Frequency Requirements

  • At startup: Full test must be executed
  • During operation: Periodic execution based on fault detection time requirements (typically once every 24 hours)

2.2 Program Flow Monitoring

2.2.1 Failure Mode Analysis

Failure Types:

  • Program Counter Stuck-at: PC fixed at a specific address
  • Program run-away: Execution jumps to wrong code area
  • Infinite loop: Program enters an endless loop

2.2.2 Class B Acceptable Measures

According to Table H.2, for program counter faults, Class B accepts:

  1. Functional test
  2. Periodic self-test
  3. Time-slot monitoring
  4. Logical monitoring

2.2.3 Implementation: Logical Monitoring

Logical monitoring detects anomalies by verifying the logical sequence of program execution:

// Using state flags for logical monitoring
typedef enum {
    PHASE_INIT = 0,
    PHASE_INPUT_READ,
    PHASE_CONTROL_CALC,
    PHASE_OUTPUT_WRITE,
    PHASE_DIAGNOSTIC,
    PHASE_MAX
} Phase_t;

static Phase_t current_phase = PHASE_INIT;
static Phase_t expected_next_phase = PHASE_INPUT_READ;

void CheckProgramFlow(void) {
    if(current_phase != expected_next_phase) {
        // Program flow anomaly
        EnterSafeState();
    }

    // Set next expected phase
    switch(current_phase) {
        case PHASE_INIT:
            expected_next_phase = PHASE_INPUT_READ;
            break;
        case PHASE_INPUT_READ:
            expected_next_phase = PHASE_CONTROL_CALC;
            break;
        case PHASE_CONTROL_CALC:
            expected_next_phase = PHASE_OUTPUT_WRITE;
            break;
        case PHASE_OUTPUT_WRITE:
            expected_next_phase = PHASE_DIAGNOSTIC;
            break;
        case PHASE_DIAGNOSTIC:
            expected_next_phase = PHASE_INPUT_READ;  // Loop
            break;
    }
}

// Call at each phase
void InputReadPhase(void) {
    current_phase = PHASE_INPUT_READ;
    CheckProgramFlow();

    // Execute input reading
    // ...
}

2.2.4 Program Signature Monitoring

// Program signature: Update signature value at key points
#define FLOW_SIGNATURE_INIT      0xA5A5A5A5
#define FLOW_SIGNATURE_INPUT     0x5A5A5A5A
#define FLOW_SIGNATURE_CONTROL   0xAA55AA55
#define FLOW_SIGNATURE_OUTPUT    0x55AA55AA

static uint32_t flow_signature = FLOW_SIGNATURE_INIT;

void CheckFlowSignature(uint32_t expected) {
    if(flow_signature != expected) {
        EnterSafeState();
    }
}

void MainControlLoop(void) {
    // Initialize
    flow_signature = FLOW_SIGNATURE_INIT;

    // Input phase
    flow_signature = FLOW_SIGNATURE_INPUT;
    ReadInputs();

    // Control phase
    CheckFlowSignature(FLOW_SIGNATURE_INPUT);
    flow_signature = FLOW_SIGNATURE_CONTROL;
    CalculateControl();

    // Output phase
    CheckFlowSignature(FLOW_SIGNATURE_CONTROL);
    flow_signature = FLOW_SIGNATURE_OUTPUT;
    WriteOutputs();
}

2.3 Clock Monitoring

2.3.1 Failure Mode Analysis

Failure Types:

  • Clock frequency drift: Frequency higher or lower than expected
  • Clock source failure: Crystal damage or oscillator failure
  • Clock switching failure: Multi-clock source system switching failure

2.3.2 Class B Acceptable Measures

According to Table H.2, for clock faults, Class B accepts:

  1. Frequency monitoring
  2. Time-slot monitoring

2.3.3 Implementation: Frequency Monitoring

// Using independent clock source for frequency monitoring
#define EXPECTED_FREQ_COUNT_50HZ  1000  // Assuming internal clock 20MHz
#define TOLERANCE_PERCENT         5

bool MonitorClockFrequency(void) {
    static uint32_t last_count = 0;
    uint32_t current_count = GetTimerCounter();
    uint32_t delta = current_count - last_count;
    last_count = current_count;

    // Calculate percentage deviation
    int32_t error = (int32_t)delta - (int32_t)EXPECTED_FREQ_COUNT_50HZ;
    int32_t error_percent = (error * 100) / EXPECTED_FREQ_COUNT_50HZ;

    if(abs(error_percent) > TOLERANCE_PERCENT) {
        return false;  // Clock frequency anomaly
    }

    return true;
}

2.3.4 Time-slot Monitoring: Window Watchdog

// Window watchdog configuration
#define WDT_MIN_FEED_TIME_MS  9
#define WDT_MAX_FEED_TIME_MS  11

void InitWindowWatchdog(void) {
    // Configure window watchdog
    // Early feeding (<9ms) or late feeding (>11ms) triggers reset
    WDT->WINDOW = WDT_MAX_FEED_TIME_MS;
    WDT->COMP = WDT_MIN_FEED_TIME_MS;
    WDT->CTRL |= WDT_CTRL_ENABLE;
}

void FeedWindowWatchdog(void) {
    // Must feed watchdog within time window
    WDT->FEED = 0xAA;
    WDT->FEED = 0x55;
}

Advantages of Window Watchdog:

  • Detects slow program execution (timeout)
  • Detects fast program execution (early feeding)
  • Meets H.13.2.1.1 requirement for upper and lower limit sensitivity

2.4 I/O Monitoring

2.4.1 Failure Mode Analysis

Input Unit Failures:

  • Sensor open/short circuit
  • ADC sampling error
  • Data range anomaly

Output Unit Failures:

  • Output stuck at high/low level
  • Relay weld/contact stuck
  • Output state inconsistent with command

2.4.2 Class B Acceptable Measures

According to Table H.2, for I/O faults, Class B accepts:

  1. Plausibility check
  2. Input comparison
  3. Output verification

2.4.3 Implementation: Plausibility Check

// Variable range check
#define ADC_MIN_VALUE  0
#define ADC_MAX_VALUE  4095
#define TEMP_MIN_VALUE -40
#define TEMP_MAX_VALUE 120

bool CheckVariableRange(int16_t value, int16_t min, int16_t max) {
    return (value >= min && value <= max);
}

void SafeReadTemperature(int16_t* temp) {
    int16_t raw_adc = ReadADCTemperature();

    if(!CheckVariableRange(raw_adc, ADC_MIN_VALUE, ADC_MAX_VALUE)) {
        EnterSafeState();
        return;
    }

    *temp = ConvertADCToTemperature(raw_adc);

    if(!CheckVariableRange(*temp, TEMP_MIN_VALUE, TEMP_MAX_VALUE)) {
        EnterSafeState();
    }
}

2.4.4 Rate of Change Check

// Data plausibility check: rate of change
typedef struct {
    int16_t current;
    int16_t previous;
    int16_t max_delta;
} PlausibilityCheck_t;

bool CheckPlausibility(PlausibilityCheck_t* check, int16_t new_value) {
    int16_t delta = abs(new_value - check->previous);

    if(delta > check->max_delta) {
        return false;  // Unreasonable change
    }

    check->previous = check->current;
    check->current = new_value;
    return true;
}

// Temperature rate of change check (assuming max 10°C/second)
PlausibilityCheck_t temp_check = {
    .current = 25,
    .previous = 25,
    .max_delta = 10  // Assuming check once per second
};

void ReadTemperatureWithPlausibility(int16_t* temp) {
    int16_t new_temp = ReadTemperatureSensor();

    if(!CheckPlausibility(&temp_check, new_temp)) {
        // Unreasonable temperature change
        EnterSafeState();
        return;
    }

    *temp = new_temp;
}

2.4.5 Output Verification

// Output readback verification
void SetSafetyRelay(bool state) {
    // 1. Set output
    GPIO_Write(RELAY_PIN, state);

    // 2. Readback verification
    bool actual_state = GPIO_Read(RELAY_FEEDBACK_PIN);

    // 3. Verify output state
    if(actual_state != state) {
        // Output fault, enter safe state
        EnterSafeState();
        RecordError(ERROR_OUTPUT_MISMATCH);
    }
}

2.5 External Memory Monitoring

2.5.1 Failure Mode Analysis

Program Memory (Flash/ROM) Failures:

  • Single bit flip
  • Multi-bit faults
  • Address decoding errors

Data Memory (RAM) Failures:

  • Stuck-at faults
  • Coupling faults (adjacent cells affecting each other)
  • Address faults

2.5.2 Class B Acceptable Measures

Non-volatile Memory (4.1):

  1. Modified checksum
  2. Multiple checksum
  3. Word protection with single bit redundancy

Variable Memory (4.2):

  1. Periodic static memory test
  2. Word protection with single bit redundancy

2.5.3 Program Memory Test: CRC Check

// CRC-16-CCITT implementation
uint16_t CRC16_CCITT(const uint8_t* data, uint32_t length) {
    uint16_t crc = 0xFFFF;
    const uint16_t poly = 0x1021;

    for(uint32_t i = 0; i < length; i++) {
        crc ^= (uint16_t)data[i] << 8;
        for(uint8_t bit = 0; bit < 8; bit++) {
            if(crc & 0x8000) {
                crc = (crc << 1) ^ poly;
            } else {
                crc <<= 1;
            }
        }
    }

    return crc;
}

// Periodic CRC check (called in main loop)
#define CRC_CHECK_INTERVAL_MS  1000

void PeriodicCRCCheck(void) {
    static uint32_t last_check = 0;

    if(GetCurrentTime() - last_check >= CRC_CHECK_INTERVAL_MS) {
        last_check = GetCurrentTime();

        uint16_t calculated = CRC16_CCITT(FLASH_START_ADDR, FLASH_SIZE);
        uint16_t stored = GetStoredCRC();

        if(calculated != stored) {
            // Enter safe state
            EnterSafeState();
        }
    }
}

2.5.4 Data Memory Test: March Test

// Simplified March C test algorithm
bool MarchTestRAM(uint8_t* start, uint32_t size) {
    // Write 0 going forward
    for(uint32_t i = 0; i < size; i++) {
        start[i] = 0x00;
    }

    // Read/write 0xAA going forward, then write 0x55
    for(uint32_t i = 0; i < size; i++) {
        if(start[i] != 0x00) return false;
        start[i] = 0xAA;
    }

    // Read/write 0x55 going forward, then write 0x00
    for(uint32_t i = 0; i < size; i++) {
        if(start[i] != 0xAA) return false;
        start[i] = 0x55;
    }

    // Read/write 0x55 going backward, then write 0xAA
    for(int32_t i = size - 1; i >= 0; i--) {
        if(start[i] != 0x55) return false;
        start[i] = 0xAA;
    }

    // Read/write 0xAA going backward, then write 0x00
    for(int32_t i = size - 1; i >= 0; i--) {
        if(start[i] != 0xAA) return false;
        start[i] = 0x00;
    }

    return true;
}

2.5.5 Block-wise Periodic RAM Test

// Block-wise periodic RAM test (doesn't corrupt valid data during operation)
#define RAM_BLOCK_SIZE 256
#define RAM_TEST_INTERVAL_MS 100

void PeriodicRAMTest(void) {
    static uint32_t current_block = 0;
    static uint32_t last_test = 0;

    if(GetCurrentTime() - last_test >= RAM_TEST_INTERVAL_MS) {
        last_test = GetCurrentTime();

        uint8_t* block_start = RAM_START + (current_block * RAM_BLOCK_SIZE);

        if(!MarchTestRAM(block_start, RAM_BLOCK_SIZE)) {
            EnterSafeState();
        }

        current_block = (current_block + 1) % RAM_BLOCK_COUNT;
    }
}

2.6.1 Failure Mode Analysis

Communication Failure Types:

  • Data bit errors
  • Data frame loss
  • Communication timeout
  • Data injection attacks

2.6.2 Class B Acceptable Measures

According to Table H.2, for communication faults, Class B accepts:

  1. Hamming distance 3 or 4 protection
  2. CRC check
  3. Transfer redundancy
  4. Protocol test

2.6.3 Implementation: CRC-16 Communication Protection

// Communication frame structure
typedef struct {
    uint8_t  header;
    uint8_t  cmd;
    uint16_t data;
    uint16_t crc;      // CRC-16 checksum
    uint8_t  tail;
} CommFrame_t;

// Calculate and fill CRC
void FillFrameCRC(CommFrame_t* frame) {
    // Calculate all data except CRC field
    frame->crc = CRC16_CCITT((uint8_t*)frame, sizeof(CommFrame_t) - sizeof(uint16_t) - sizeof(uint8_t));
}

// Verify received frame
bool VerifyFrameCRC(CommFrame_t* frame) {
    uint16_t calculated_crc = CRC16_CCITT((uint8_t*)frame, sizeof(CommFrame_t) - sizeof(uint16_t) - sizeof(uint8_t));

    if(calculated_crc != frame->crc) {
        // CRC check failed
        return false;
    }

    return true;
}

// Communication receive handler
void ProcessReceivedFrame(uint8_t* data) {
    CommFrame_t* frame = (CommFrame_t*)data;

    // 1. Verify frame header
    if(frame->header != FRAME_HEADER) {
        return;
    }

    // 2. Verify CRC
    if(!VerifyFrameCRC(frame)) {
        // Discard error frame
        return;
    }

    // 3. Process valid data
    HandleValidCommand(frame->cmd, frame->data);
}

2.6.4 Timeout Detection

// Communication timeout detection
#define COMM_TIMEOUT_MS  100

typedef struct {
    uint32_t last_rx_time;
    bool     timeout_detected;
} CommMonitor_t;

CommMonitor_t comm_monitor = {0};

void CheckCommTimeout(void) {
    uint32_t current_time = GetSystemTimeMs();

    if((current_time - comm_monitor.last_rx_time) > COMM_TIMEOUT_MS) {
        if(!comm_monitor.timeout_detected) {
            // First timeout detection
            comm_monitor.timeout_detected = true;
            HandleCommTimeout();
        }
    }
}

void OnDataReceived(void) {
    comm_monitor.last_rx_time = GetSystemTimeMs();
    comm_monitor.timeout_detected = false;
}

3. Implementation Methods and Code Examples

3.1 Complete Watchdog Configuration

3.1.1 Window Watchdog Configuration

typedef struct {
    uint32_t timeout_min;
    uint32_t timeout_max;
    uint32_t last_feed_time;
} WindowWatchdog_t;

WindowWatchdog_t wwdt = {
    .timeout_min = 9,   // ms
    .timeout_max = 11,  // ms
    .last_feed_time = 0
};

void FeedWindowWatchdog(void) {
    uint32_t current_time = GetSystemTimeMs();
    uint32_t elapsed = current_time - wwdt.last_feed_time;

    // Check if within window
    if(elapsed < wwdt.timeout_min) {
        // Feeding too early, possible program flow anomaly
        RecordError(ERROR_WDT_EARLY_FEED);
        // Wait for watchdog timeout reset
        while(1);
    }

    if(elapsed > wwdt.timeout_max) {
        // Feeding too late, watchdog already triggered
        return;
    }

    // Feed watchdog
    NVIC_ClearResetEvent();
    WDT->FEED = 0xAA;
    WDT->FEED = 0x55;

    wwdt.last_feed_time = current_time;
}

3.1.2 Main Loop Feeding Strategy

void MainLoop(void) {
    InitWindowWatchdog();

    while(1) {
        uint32_t loop_start = GetSystemTimeMs();

        // Execute main control tasks
        ReadInputs();
        CalculateControl();
        WriteOutputs();

        // Execute diagnostics
        RunDiagnostics();

        uint32_t loop_time = GetSystemTimeMs() - loop_start;

        // Ensure loop time is within watchdog window
        if(loop_time < WDT_MIN_FEED_TIME_MS) {
            // Delay to meet minimum time
            Delay(WDT_MIN_FEED_TIME_MS - loop_time);
        }

        FeedWindowWatchdog();
    }
}

3.2 Variable Monitoring and Redundancy Protection

3.2.1 Triple Modular Redundancy (TMR) Storage

// Using Triple Modular Redundancy (TMR) for critical variables
typedef struct {
    uint16_t value;
    uint16_t copy1;
    uint16_t copy2;
} SafeVariable_t;

SafeVariable_t battery_voltage;

void SetVoltage(uint16_t voltage) {
    // Plausibility check
    if(voltage > MAX_VOLTAGE) {
        EnterSafeState();
        return;
    }

    // Store three copies
    battery_voltage.value = voltage;
    battery_voltage.copy1 = voltage;
    battery_voltage.copy2 = voltage;
}

uint16_t GetVoltage(void) {
    // Two-out-of-three logic
    if(battery_voltage.value == battery_voltage.copy1) {
        return battery_voltage.value;
    } else if(battery_voltage.value == battery_voltage.copy2) {
        return battery_voltage.value;
    } else if(battery_voltage.copy1 == battery_voltage.copy2) {
        return battery_voltage.copy1;
    } else {
        // All three disagree, enter safe state
        EnterSafeState();
        return 0;
    }
}

4. Testing and Verification Requirements

4.1 Fault Injection Test Plan

Test ItemFault Injection MethodDetection MethodResponse RequirementRecord
Flash faultModify Flash contentCRC detectionProhibit operation at startupTEST-FLASH-001
RAM faultWrite erroneous dataMarch testDetect at startupTEST-RAM-001
Watchdog testPrevent feedingWatchdog resetReset within 40msTEST-WDG-001
Clock faultSwitch to faulty clock sourceFrequency monitoringDetect within 1sTEST-CLK-001
ADC faultInject incorrect voltagePlausibility checkDetect within 100msTEST-ADC-001
Communication faultInject erroneous dataCRC checkDiscard error frameTEST-COM-001
Relay weldShort relay contactsReadback detectionDetect and alarmTEST-RLY-001

4.2 EMC Test Requirements

According to Table H.12, Class B protection control must meet Test Level 3:

Test ItemLevel 3 RequirementClass B Importance
Voltage dip/interruptionSpecific duration cyclesMust pass
Surge immunitySpecific voltage levelMust pass
EFT/BurstSpecific frequency and durationMust pass
ESDContact/air discharge specific voltageMust pass
RF radiated immunitySpecific field strengthMust pass

4.3 Test Coverage Requirements

  • Statement coverage: 100%
  • Branch coverage: 100%
  • Safety-related code coverage: 100%

5. Common Non-Compliance Analysis

5.1 NC-001: Missing or Incomplete CPU Testing

Standard Requirement: Table H.2 - CPU registers and instruction decoding require periodic self-test

Common Issues:

  1. Only startup test, no periodic testing during operation
  2. Insufficient test coverage, only testing partial registers
  3. No instruction decoding test

Non-Compliance Description:

Non-Compliance: NC-001
Clause: Table H.2, CPU Registers
Problem Description: The system only performs basic register testing at startup,
but does not conduct periodic CPU testing during operation, unable to detect
CPU faults occurring during runtime.
Severity: Major
Compliance: Does not meet Class B requirements

Corrective Actions:

  1. Add runtime periodic CPU testing (execute once every 24 hours)
  2. Implement equivalence class testing for instruction decoding coverage
  3. Record test results and trigger fault response

5.2 NC-002: Insufficient Memory Test Coverage

Standard Requirement: Table H.2 - Memory protection measures

Common Issues:

  1. Flash only has simple checksum, no CRC
  2. RAM only has startup test
  3. No protection against address errors

Non-Compliance Description:

Non-Compliance: NC-002
Clause: Table H.2, Non-volatile Memory
Problem Description: Program memory only uses 8-bit checksum for verification,
unable to meet Class B requirement of 100% detection for single-bit faults.
8-bit checksum has risk of missed detection.
Severity: Major
Compliance: Non-compliant

Corrective Actions:

  1. Upgrade checksum to CRC-16
  2. Add runtime periodic RAM testing
  3. Add parity check or Hamming code for critical data variables

5.3 NC-003: Missing Program Flow Monitoring

Standard Requirement: H.3.18.10.2 Logical program sequence monitoring

Common Issues:

  1. Only watchdog, no program flow monitoring
  2. State machine has no illegal state check
  3. No call sequence verification

Non-Compliance Description:

Non-Compliance: NC-003
Clause: H.3.18.10.2 Logical Monitoring
Problem Description: Software uses watchdog timer as the only program flow
monitoring method. However, watchdog can only detect program timeout, unable
to detect cases where program runs to wrong location but still feeds on time.
Severity: Minor
Compliance: Partially compliant

Corrective Actions:

  1. Implement state machine monitoring, check illegal state transitions
  2. Add software signature or program counter monitoring
  3. Set up checkpoints to verify execution order

5.4 NC-004: Watchdog Configuration Issues

Standard Requirement: H.3.18.10.4 Time-slot monitoring (upper and lower limit sensitive)

Common Issues:

  1. Timeout period too long
  2. Using regular watchdog instead of window watchdog
  3. No system status check before feeding
  4. Watchdog reset not distinguished from normal startup

Non-Compliance Description:

Non-Compliance: NC-004
Clause: H.3.18.10.4 Time-slot Monitoring
Problem Description: Watchdog timeout set to 2 seconds, for overcurrent
protection (fault tolerance time 100ms), unable to detect program anomaly
within fault tolerance time and enter safe state. Additionally, watchdog
is of regular type, unable to detect fast program execution.
Severity: Major
Compliance: Non-compliant

Corrective Actions:

  1. Adjust watchdog timeout based on strictest fault tolerance time
  2. Use window watchdog or add program execution lower limit monitoring
  3. Check system health status before feeding watchdog
  4. Implement special handling after watchdog reset

6. Best Practices Summary

6.1 Table H.2 Compliance Table

ComponentFailure ModeClass B RequirementImplementation MeasureStandard ClauseComplianceEvidence
CPU RegistersStuck-at/DCFunctional test or periodic self-testStartup register test + runtime periodic testH.3.18.10SW-TEST-001
Program CounterStuck-atTime-slot + logical monitoringWindow watchdog + state machine monitoringH.3.18.10.4SW-ARCH-003
ClockIncorrect frequencyFrequency monitoringInternal RC vs external crystal comparisonH.3.18.10.1HW-SCH-002
FlashSingle bit faultCRC or checksumStartup CRC checkH.3.19.4.1SW-TEST-002
RAMDC faultsStatic memory testMarch C algorithm testH.3.19.6SW-TEST-003
ADCData errorPlausibility checkRange check + two-out-of-three logicH.3.18.13SW-CODE-005
Communication InterfaceData errorHamming distance 3CRC-16 checkH.3.18.7SW-CODE-008
Digital I/OIncorrect outputPlausibility checkOutput readback verificationH.3.18.13SW-TEST-004

6.2 Software Safety Measures Summary Table

Measure CategorySpecific MeasureImplementationDetection PeriodResponse MethodVerification Method
CPU MonitoringWatchdog timerHardware window watchdog100ms timeoutSystem resetFault injection test
CPU MonitoringProgram flow monitoringState machine + flagsEach cycleEnter safe stateCode review
Memory ProtectionFlash CRCCRC-16At startupProhibit operationCheck failure test
Memory ProtectionRAM testMarch CAt startupProhibit operationMemory fault injection
Clock MonitoringFrequency detectionExternal crystal comparisonEvery 1sSwitch to safe clockFrequency deviation test
I/O MonitoringOutput readbackGPIO readbackEvery 10msTurn off outputOutput short circuit test
Communication ProtectionCRC checkCRC-16Per frameDiscard packetCommunication error injection

★ Insight ─────────────────────────────────────

Three Key Insights into Table H.2 Design:

  1. Fault Detectability Over Fault Prevention: The core philosophy of IEC 60730-1 Annex H is acknowledging that faults are inevitable, but faults must be detected within an acceptable time. This aligns with the “fail-safe” concept of automotive functional safety ISO 26262.

  2. Measure Diversity and Equivalence: Table H.2 allows multiple equivalent measures to meet the same requirement. For example, CPU testing can use static memory test, functional test, or word protection with single bit redundancy. This design flexibility enables the standard to adapt to different MCU architectures and application scenarios.

  3. Upper and Lower Limit Sensitivity is Key: H.13.2.1.1 explicitly requires time-slot monitoring to be sensitive to both upper and lower limits, meaning simple timeout watchdog is insufficient to meet Class B requirements. Window watchdog or combined monitoring schemes are the correct choice, a requirement often overlooked.

─────────────────────────────────────────────────


References

  1. IEC 60730-1:2022 Annex H - Requirements related to functional safety
  2. IEC 60730-1 Table H.2 - Fault/error control techniques
  3. IEC 61508-3 - Software safety requirements
  4. MISRA C:2012 - Coding guidelines

Document Version: 1.0 Release Date: March 14, 2026

Tags

#IEC-60730 #Table-H2 #fault-control #program-flow-monitoring #Annex-H