ARM Cortex-M33 Hard Fault During VLDR Execution

The issue at hand involves a HardFault triggered by the execution of the vldr d16, [r7, #200] instruction on an ARM Cortex-M33 processor, specifically the LPC55S69 (CM33_Core0) with DSP extensions. The fault occurs during the execution of a floating-point unit (FPU) instruction, suggesting potential misconfigurations or memory access issues. The system is built using GNU Tools ARM Embedded/8 2019-q3-update and debugged in MCUXpresso IDE v11.0.1. The SystemInit() function, which is responsible for initializing the system, including the FPU, appears to execute correctly, but the fault persists even after adding data synchronization barriers (DSB) and instruction synchronization barriers (ISB).

The primary concern revolves around understanding the current processor context (secure/non-secure, privileged/unprivileged, thread/handler), verifying the FPU’s enabled state, and ensuring proper memory alignment for the VLDR instruction. Additionally, the absence of DSB and ISB instructions after enabling the FPU in SystemInit() raises questions about their necessity in this context.

FPU Configuration, Memory Alignment, and Processor Context

The HardFault could stem from several root causes, including incorrect FPU configuration, improper memory alignment, or an invalid processor context during the execution of the VLDR instruction. The Cortex-M33 processor’s FPU must be explicitly enabled by setting the appropriate bits in the Coprocessor Access Control Register (CPACR). The SystemInit() function correctly sets the CPACR bits to enable full access to the FPU, but the absence of DSB and ISB instructions immediately after this configuration could lead to pipeline inconsistencies, causing the processor to execute FPU instructions before the FPU is fully enabled.

Memory alignment is another critical factor. The VLDR instruction requires the memory address to be word-aligned. If the address in register r7 (0x2003FEA0) plus the offset (200 or 0xC8) results in a non-word-aligned address, the processor will generate a HardFault. The value of r7 and the structure of gMyInout must be examined to ensure proper alignment.

The processor context (secure/non-secure, privileged/unprivileged, thread/handler) also plays a significant role. The Cortex-M33 implements the ARMv8-M architecture, which introduces a security extension. The Non-Secure Access Control Register (NSACR) must be configured to allow non-secure access to the FPU. The SystemInit() function sets the NSACR bits correctly, but the current context during the VLDR execution must be verified to ensure it has the necessary privileges and security permissions.

Verifying FPU Status, Aligning Memory, and Ensuring Proper Context

To resolve the HardFault issue, a systematic approach is required to verify the FPU status, ensure memory alignment, and confirm the processor context. Below are detailed troubleshooting steps and solutions:

Verifying FPU Configuration and Status

The FPU status can be verified by inspecting the CPACR and NSACR registers. The CPACR should have bits 20-23 set to enable full access to the FPU. The NSACR should have bits 0, 1, 10, and 11 set to allow non-secure access to the FPU. Additionally, the FPU enable status can be checked using the Floating-Point Status and Control Register (FPSCR). If the FPU is enabled, the FPSCR will reflect the current state of the FPU.

To ensure the FPU is fully enabled before executing FPU instructions, add DSB and ISB instructions immediately after setting the CPACR and NSACR bits in SystemInit(). These instructions ensure that the pipeline is flushed and the FPU is ready for use.

SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); // Enable CP10 and CP11 (FPU)
SCB->NSACR |= ((3UL << 0) | (3UL << 10)); // Enable non-secure access to FPU
__DSB(); // Ensure the configuration is complete
__ISB(); // Flush the pipeline

Ensuring Proper Memory Alignment

The VLDR instruction requires the memory address to be word-aligned. Verify that the address in r7 (0x2003FEA0) plus the offset (200 or 0xC8) results in a word-aligned address. If gMyInout is a structure or array, ensure that its elements are properly aligned in memory. Use the __attribute__((aligned(4))) attribute in C to enforce alignment.

typedef struct {
    int32_t data[50]; // Example array
} __attribute__((aligned(4))) MyStruct;
MyStruct gMyInout; // Ensure alignment

Confirming Processor Context

The processor context can be verified using the Control Register (CONTROL) and the Security Attribution Unit (SAU). The CONTROL register indicates whether the processor is in privileged or unprivileged mode, while the SAU configuration determines the security state. Use the following code to check the current context:

uint32_t control_reg = __get_CONTROL();
uint32_t is_privileged = !(control_reg & 0x1); // Bit 0 indicates privilege
uint32_t is_secure = __TZ_get_PSPLIM_NS() == 0; // Check secure state

If the processor is in an unprivileged or non-secure state during the VLDR execution, it may lack the necessary permissions to access the FPU or memory. Ensure that the code is executed in a privileged and secure context.

Debugging the HardFault

The Configuration Fault Status Register (CFSR) provides detailed information about the cause of the HardFault. Inspect the CFSR to determine whether the fault is due to an alignment issue, an access violation, or an FPU configuration error. The CFSR can be accessed using the following code:

uint32_t cfsr = SCB->CFSR;
if (cfsr & SCB_CFSR_IMPRECISERR_Msk) {
    // Imprecise data access error
} else if (cfsr & SCB_CFSR_UNALIGNED_Msk) {
    // Unaligned memory access error
} else if (cfsr & SCB_CFSR_NOCP_Msk) {
    // Coprocessor access error (FPU not enabled)
}

Final Recommendations

  1. Add DSB and ISB instructions after enabling the FPU in SystemInit().
  2. Verify the alignment of the memory address used in the VLDR instruction.
  3. Ensure the processor is in a privileged and secure context during FPU operations.
  4. Inspect the CFSR to identify the specific cause of the HardFault.
  5. Use debugging tools to step through the code and verify the values of critical registers (CPACR, NSACR, CONTROL, CFSR).

By following these steps, the HardFault issue can be systematically diagnosed and resolved, ensuring proper FPU configuration, memory alignment, and processor context.

Similar Posts

Leave a Reply

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