Close-up photograph of an Infineon AURIX TC3xx microcontroller chip mounted on an automotive PCB.

AURIX TC3xx LBIST (Logic Built-In Self-Test) Technical Principles and Engineering Implementation

Author: Johnny Liu

Title: CEO at Dowway Vehicle

Date: June 24, 2026

Category: Automotive Electronics / Functional Safety / Embedded Firmware

Quick FAQ

What is LBIST on the AURIX TC3xx? It is a hardware self-test that checks the microcontroller’s digital logic gates. It uses internal scan chains, runs pseudo-random test patterns, and creates a unique signature to verify that the hardware contains no latent structural faults.

Why does running LBIST trigger a Warm Reset? The scan test overrides and scrambles the state of the digital circuits. A Warm Reset is necessary to clear these invalid states and boot the system back up in a clean, predictable state.

Where do you find the golden signature for the test? It is a static, pre-calculated 32-bit value. You can find the signature for your specific pattern count and frequency in the System Control Unit (SCU) appendix of the Infineon AURIX TC3xx User Manual.

Why This Guide Matters (The ISO 26262 Angle)

In safety-critical automotive designs (ASIL-B to ASIL-D), we must detect random hardware faults. Latent faults are especially dangerous. These are faults that stay hidden during normal driving but can lead to safety violations if a second fault occurs.

The Logic Built-In Self-Test (LBIST) is a key hardware safety mechanism (SM:MCU:LBIST) on the AURIX TC3xx. It targets the Latent Fault Metric (LFM). Because it checks the digital core gates, running a successful LBIST lets us verify the CPU, bus, and safety controllers at boot. This removes the need for slow, complex software-based logic checks later.

Quick Comparison of Startup Self-Tests

To keep your design clean, do not confuse LBIST with other built-in tests on this platform:

Test MechanismWhat It TestsCauses Reset?When to Run ItPrimary Goal
LBISTInternal Digital LogicYes (Warm Reset)Early Boot (Cold PORST / Standby Wakeup)Detects structural gate faults for LFM
MBISTSRAM and Flash MemoriesNo (Configurable)Startup or RuntimeFinds memory cell and address line failures
MONBISTPMS Voltage MonitorsNoEarly BootVerifies the voltage monitor backup paths
FwCheckKey Register ConfigurationsNoPost-Reset / RuntimeChecks register and firmware footprints

How TC3xx LBIST Works in Hardware

Scan Chains and Signature Compression

LBIST relies on structural scan testing. During manufacturing, the chip designers link the internal flip-flops together to form serial registers called scan chains.

+---------------------------------------------------------------------------------+
|                                 AURIX TC3xx SCU                                 |
|                                                                                 |
|   +-------------------+    Test Patterns    +-------------------------------+   |
|   |   LFSR Engine     |====================>|       Internal Scan Chains    |   |
|   | (Seed & Patterns) |                     | (Registers linked in series)  |   |
|   +-------------------+                     +-------------------------------+   |
|                                                             ||                  |
|                                                             || Capture & Shift  |
|                                                             \/                  |
|   +-------------------+     Final Signature   +-------------------------------+   |
|   |   LBISTCTRL3      |<====================|         MISR Compressor       |   |
|   |  (SIGNATURE)      |                     | (Compresses output stream)    |   |
|   +-------------------+                     +-------------------------------+   |
+---------------------------------------------------------------------------------+

The hardware follows a clean, automated cycle:

  1. Generating Patterns: A Linear Feedback Shift Register (LFSR) creates pseudo-random test patterns based on a starting value (the Seed).
  2. Shifting In: The controller shifts these patterns into the internal scan chains.
  3. Capture Phase: The system runs one or more functional clocks. The logic gates process the patterns, and the flip-flops capture the output.
  4. Shifting Out & Compressing: The captured data shifts out into a Multiple Input Signature Register (MISR), which compresses the long stream of bits into a single 32-bit signature.
  5. Evaluating: Software compares this signature to the golden value to confirm the hardware is healthy.

What LBIST Does Not Cover

Keep these hardware limits in mind:

  • Analog Modules: It does not test the PMS, EVR, or ADC analog blocks.
  • SRAM Contents: Memory testing is left to MBIST. Because LBIST scrambles the hardware, it corrupts certain Memory Test Unit (MTU) registers. Your software must back up and restore these register values.

Hardware Registers to Know

Configuring the test means writing to registers in the System Control Unit (SCU). These writes are protected by Safety Endinit (SEINIT) to prevent accidental execution.

  • LBISTCTRL0 (Control 0): Contains the redundant trigger bits (LBISTREQ and LBISTREQRED), the controller reset bit (LBISTRES), and the completion flag (LBISTDONE).
  • LBISTCTRL1 (Control 1): Sets the test clock frequency divider (FREQU), the logic structural layout (BODY), shifting speed limits to manage current spikes (SPLITSH), and the LFSR seed (SEED).
  • LBISTCTRL2 (Control 2): Sets the number of test patterns to run (LENGTH).
  • LBISTCTRL3 (Control 3): Holds the final 32-bit test signature (SIGNATURE).
  • RSTSTAT (Reset Status): Monitors how the test ended via the LBTERM (test ended normally) and LBPORST (test was not cut off by a power-on reset) flags.

The Warm Reset Boundary

The hardware always forces a system Warm Reset when the test finishes. This is a deliberate hardware design choice.

Because the scan test forces random values through the chip, the internal states of the logic gates become invalid. The Warm Reset flushes all registers and starts the MCU from a clean state.

Although the SRAM retains its data through a Warm Reset, the reset corrupts parts of the MTU. The software must handle this transition carefully.

Designing a Cross-Reset State Machine

Because the test triggers a Warm Reset, you must split your software driver into two parts: the Pre-Reset Trigger Phase and the Post-Reset Analysis Phase.

                    +--------------------+
                    |     Power On       |
                    +--------------------+
                              |
                              v
                  +------------------------+
                  |  Read RSTSTAT Register |
                  +------------------------+
                              |
               Is Cold PORST or Standby Wakeup?
               /                              \
             YES                               NO
             /                                  \
            v                                    v
  +------------------+                 +--------------------+
  | Check Persistent |                 | Skip LBIST & Boot  |
  |   Context State  |                 +--------------------+
  +------------------+
    /     |      \
 START   RUN    PASS/FAIL (Terminal States)
  /       |        \_______________________
 v        v                                \
[Trigger] [Analyze Signature]               v
          /       \               +--------------------+
       Valid     Invalid          | Continue app boot  |
        /           \             +--------------------+
       v             v
  Set PASS       Retries < 3?
  Clear Flags     /       \
  App Boot      YES        NO
                 /          \
                v            v
           Increment      Set FAIL
         Retry Counter   Enter Safe State
          Re-Trigger

1. Setting Up Persistent Storage

To pass status information across a Warm Reset, you need a small memory block that does not clear during reset. On the AURIX TC3xx, we use a dedicated segment of the DLMU SRAM configured for Standby-mode power retention.

Here is how you can set up this memory block in C:

typedef enum {
    LBIST_STATE_START = 0xA5A5A5A5U,
    LBIST_STATE_RUN   = 0x5A5A5A5AU,
    LBIST_STATE_PASS  = 0x3C3C3C3CU,
    LBIST_STATE_FAIL  = 0xC3C3C3C3U
} LbistState_t;

typedef struct {
    LbistState_t state;
    uint32_t     retryCounter;
    uint32_t     callerIntentCheck; // Prevents wild triggers via a CRC
    uint32_t     lastFailureReason;
} LbistPersistedContext_t;

/* Map this struct to a non-initialized retention RAM area */
__attribute__((section(".bss.backup_ram_noinit"))) 
volatile LbistPersistedContext_t g_LbistContext;

2. Software Flow and Steps

Phase A: Pre-Reset Trigger

  1. Check Reset Cause: Read RSTSTAT. Only run the test if the reset was a Cold PORST or a Standby Wakeup. Skip it for software-triggered resets.
  2. Read Current State: Read g_LbistContext.state. On cold boot, initialize this to LBIST_STATE_START.
  3. Back Up MTU Registers: Save any critical MTU register states to the retention RAM so you can restore them after the reset.
  4. Configure Hardware: Disable interrupts. Unlock the Safety Endinit protection (UnlockSEINIT()). Write the seed, frequency, and pattern count configurations to LBISTCTRL1 and LBISTCTRL2.
  5. Write Intent Verification: Calculate a CRC of the config and write it to g_LbistContext.callerIntentCheck. This prevents wild software bugs from triggering the test accidentally.
  6. Set State to RUN: Write LBIST_STATE_RUN to g_LbistContext.state.
  7. Redundant Trigger: Write 1 to both LBISTCTRL0.LBISTREQ and LBISTCTRL0.LBISTREQRED in the same clock cycle.
  8. Lock CPU: Enter an infinite assembly loop (while(1);) and wait for the hardware reset to hit.

Phase B: Post-Reset Analysis

  1. Boot Entry: The MCU boots. The software reads RSTSTAT and detects the Warm Reset.
  2. Check State: The software reads g_LbistContext.state and finds it set to LBIST_STATE_RUN.
  3. Verify Intent: Calculate the CRC and compare it to g_LbistContext.callerIntentCheck. If they do not match, flag a data corruption error and skip the test to avoid boot loops.
  4. Check Flags: Confirm that RSTSTAT.LBTERM == 1, RSTSTAT.LBPORST == 0, and LBISTCTRL0.LBISTDONE == 1.
  5. Verify Signature: Read the signature from LBISTCTRL3.SIGNATURE and compare it to the golden value.
    • If it matches: Set the state to LBIST_STATE_PASS. Reset the LBIST controller via LBISTRES. Clear the Cold Reset flags in RSTSTAT to prevent re-running the test on subsequent warm resets. Restore the MTU registers and boot the application.
    • If it mismatches: Run the retry logic.

3. Production C Implementation

Here is a clean, production-ready implementation of the driver:

#include "tc3xx_scu_registers.h"

#define GOLDEN_LBIST_SIGNATURE    0x2E4A9F18U  // Golden signature from User Manual
#define MAX_LBIST_RETRIES         3U

void Handle_Fatal_Safety_Fault(uint32_t reason) {
    // Notify the SMU and transition the ECU to a safe state
    while (1);
}

void Execute_LBIST_Evaluation_Sequence(void) {
    uint32_t rststat = SCU_RSTSTAT.U;
    
    // Check if the reset source is Cold PORST or Standby Exit
    if ((rststat & SCU_RSTSTAT_COLD_RESET_MASK) != 0U) {
        
        // Safe initialization check for retention RAM
        if (g_LbistContext.state == 0xFFFFFFFFU) { 
            g_LbistContext.state = LBIST_STATE_START;
            g_LbistContext.retryCounter = 0U;
        }

        switch (g_LbistContext.state) {
            case LBIST_STATE_START: {
                Backup_MTU_Configuration();

                // Unlock Safety Endinit and write configurations
                Unlock_Safety_Endinit();
                SCU_LBISTCTRL1.U = (0x1U << 16) | (0x0U << 8) | 0x5A5A5A5AU; // SPLITSH, BODY, SEED
                SCU_LBISTCTRL2.U = 0x000003E8U;                            // LENGTH (1000 Patterns)
                Lock_Safety_Endinit();

                // Protect against wild software jumps
                g_LbistContext.callerIntentCheck = Calculate_CRC32((uint8_t*)&g_LbistContext, sizeof(g_LbistContext) - 8);
                g_LbistContext.state = LBIST_STATE_RUN;

                // Redundant trigger write
                Unlock_Safety_Endinit();
                SCU_LBISTCTRL0.U |= (1U << SCU_LBISTCTRL0_LBISTREQ_POS) | (1U << SCU_LBISTCTRL0_LBISTREQRED_POS);
                Lock_Safety_Endinit();

                // Wait for hardware reset
                while (1) {
                    __nop();
                }
                break;
            }

            case LBIST_STATE_RUN: {
                // Verify caller intent CRC
                uint32_t calc_crc = Calculate_CRC32((uint8_t*)&g_LbistContext, sizeof(g_LbistContext) - 8);
                if (calc_crc != g_LbistContext.callerIntentCheck) {
                    g_LbistContext.state = LBIST_STATE_FAIL;
                    Handle_Fatal_Safety_Fault(0xFEED0001U); 
                    return;
                }

                // Verify hardware flags
                uint32_t test_done = (SCU_LBISTCTRL0.U & (1U << SCU_LBISTCTRL0_LBISTDONE_POS));
                uint32_t normal_term = (rststat & (1U << SCU_RSTSTAT_LBTERM_POS));
                uint32_t power_interrupted = (rststat & (1U << SCU_RSTSTAT_LBPORST_POS));

                if ((test_done != 0U) && (normal_term != 0U) && (power_interrupted == 0U)) {
                    uint32_t signature = SCU_LBISTCTRL3.U;

                    if (signature == GOLDEN_LBIST_SIGNATURE) {
                        g_LbistContext.state = LBIST_STATE_PASS;
                        
                        // Reset the controller and clear reset flags
                        Unlock_Safety_Endinit();
                        SCU_LBISTCTRL0.U |= (1U << SCU_LBISTCTRL0_LBISTRES_POS); 
                        SCU_RSTCON.U     |= SCU_RSTCON_CLEAR_COLD_FLAGS_MASK;    
                        Lock_Safety_Endinit();

                        Restore_MTU_Configuration();
                        return; // Continue to main boot
                    }
                }

                // Run retry strategy
                g_LbistContext.retryCounter++;
                if (g_LbistContext.retryCounter >= MAX_LBIST_RETRIES) {
                    g_LbistContext.state = LBIST_STATE_FAIL;
                    Handle_Fatal_Safety_Fault(0xFEED0002U); // Hardware error
                } else {
                    Unlock_Safety_Endinit();
                    SCU_LBISTCTRL0.U |= (1U << SCU_LBISTCTRL0_LBISTRES_POS);
                    Lock_Safety_Endinit();
                    
                    g_LbistContext.state = LBIST_STATE_START;
                    Execute_LBIST_Evaluation_Sequence(); // Re-run
                }
                break;
            }

            case LBIST_STATE_PASS:
                // Passed; continue standard boot
                break;

            case LBIST_STATE_FAIL:
            default:
                Handle_Fatal_Safety_Fault(0xFEED0003U);
                break;
        }
    }
}

Practical Engineering Pitfalls

1. Standby SRAM Power Settings

During Standby mode, the system might shut off power to your retention RAM. If this happens, your state variable resets, and the MCU will trigger a fresh test on every wakeup, causing an infinite boot loop.

  • How to fix: Configure the STBYRAMSEL and PROCONRAM.LMUINSEL registers in the SCU to force the LMU RAM sectors to stay powered during Standby. Also, make sure your linker script puts the g_LbistContext variable in a .noinit section so your startup C-initialization code does not clear it on wakeup.

2. Early Data Access Traps

Reading uninitialized SRAM sectors right after a cold boot can cause a Data Access Trap on some AURIX silicon steps due to bad ECC or parity bits.

  • How to fix: Your trap handler must check if the exception happened in the retention memory space during early boot. If it did, write dummy data to initialize the ECC bits, clear the trap status, and resume execution instead of halting the CPU.

3. Multi-Core Boot Coordination

AURIX is a multi-core platform. If all cores boot at the same time during the Warm Reset cycles, they can interfere with your state machine.

  • How to fix: Set up a master-slave boot sequence. Hold all auxiliary cores in a halt state (using Boot Mode Headers or SCU controls) during startup. Only allow Core 0 to run the LBIST state machine. Once Core 0 verifies the test and writes LBIST_STATE_PASS, it can release the other cores to boot.

Lab Testing and Validation

To verify your design for functional safety assessors, you can use these testing methods:

  • Verify the Golden Path: Use your debugger to confirm the state machine successfully completes the transition: $$\text{START} \longrightarrow \text{Warm Reset} \longrightarrow \text{RUN} \longrightarrow \text{PASS}$$
  • Inject Data Errors: Halt the CPU during the START phase, manually corrupt the g_LbistContext.callerIntentCheck CRC in memory, and resume. Confirm that the software catches the error and transitions to the safe state without running the test.
  • Inject Signature Failures: Change your test configuration slightly (such as changing the pattern count in LBISTCTRL2). This will alter the signature. Verify that:
    1. The code attempts to run the test up to 3 times.
    2. The MCU enters the safe state on the 3rd failed attempt.

Wrapping Up

Running LBIST on the AURIX TC3xx is a highly reliable way to satisfy ISO 26262 diagnostic requirements for digital logic. By using internal scan chains and pseudo-random patterns, the hardware pinpoints structural gate failures.

To run this safely, you must build a clean, cross-reset state machine. Focus on protecting your retention RAM configurations, managing startup traps, coordinating your CPU cores, and setting up a solid retry limit. This ensures your self-test is both safe and dependable.

Leave a Comment

Your email address will not be published. Required fields are marked *

Need a Quote or Have Questions?

Please fill out the form below, our engineers will contact you within 24 hours.