ARM Cortex-M4 HardFault Triggered by arm_fir_q15 Function

The issue at hand involves a HardFault exception being triggered on an ARM Cortex-M4 processor when executing the arm_fir_q15 function from the CMSIS DSP library. The function is part of a Finite Impulse Response (FIR) filter implementation, specifically designed for Q15 fixed-point arithmetic. The HardFault occurs during the execution of the filter, and the root cause is not immediately obvious from the code or the error message. The problem manifests when the processor attempts to execute an undefined function, arm_fir_q15_1_8_mve, which is not part of the standard CMSIS DSP library. This suggests a misconfiguration or an underlying issue with the memory or data alignment.

The Cortex-M4 processor is a 32-bit RISC core optimized for digital signal processing (DSP) and real-time control applications. It includes a DSP extension with instructions specifically designed for efficient fixed-point arithmetic, such as the Q15 format used in this FIR filter. The HardFault exception is a critical fault that occurs when the processor detects an error condition that it cannot handle, such as an invalid memory access, an undefined instruction, or a misaligned data access.

The arm_fir_q15 function is designed to process blocks of input data using a set of filter coefficients. The function requires the filter state and coefficients to be properly aligned in memory, and the number of filter taps must meet specific alignment requirements. In this case, the number of taps was set to 29, which is an odd number and does not meet the alignment requirements for the Q15 FIR filter implementation. This misalignment likely caused the processor to attempt executing an undefined function, leading to the HardFault.

Misaligned Data and Odd Number of Filter Taps

The primary cause of the HardFault is the misalignment of data in memory due to an odd number of filter taps. The CMSIS DSP library, particularly the arm_fir_q15 function, expects the number of filter taps to be even. This requirement is due to the way the Cortex-M4 processor handles fixed-point arithmetic and memory access. The processor uses load/store instructions that operate on aligned memory addresses, and an odd number of taps can result in misaligned memory accesses, which are not supported by the hardware.

The arm_fir_q15 function processes the input data in blocks, and each block is processed using a set of filter coefficients. The coefficients are stored in memory as an array of Q15 values, and the function expects this array to be properly aligned. When the number of taps is odd, the alignment of the coefficients array is disrupted, leading to misaligned memory accesses. This misalignment can cause the processor to attempt executing an undefined instruction, such as arm_fir_q15_1_8_mve, which is not part of the standard CMSIS DSP library.

Additionally, the arm_fir_q15 function uses a state buffer to store intermediate results between block processing. This state buffer must also be properly aligned in memory. If the state buffer is misaligned, it can lead to incorrect memory accesses, further contributing to the HardFault. The state buffer is typically allocated as an array of Q15 values, and its size is determined by the number of filter taps and the block size. In this case, the state buffer was allocated with a size of BLOCK_SIZE + NUM_TAPS - 1, which is 60 for a block size of 32 and 29 taps. This size does not meet the alignment requirements for the Q15 FIR filter implementation, leading to misaligned memory accesses.

Correcting Data Alignment and Ensuring Even Number of Taps

To resolve the HardFault issue, the number of filter taps must be adjusted to ensure proper data alignment. The CMSIS DSP library requires the number of taps to be even, so the number of taps should be changed from 29 to 28. This adjustment ensures that the coefficients array and the state buffer are properly aligned in memory, preventing misaligned memory accesses and the resulting HardFault.

The following steps outline the necessary changes to the code to correct the data alignment issue:

  1. Adjust the Number of Filter Taps: Change the number of filter taps from 29 to 28. This ensures that the coefficients array and the state buffer are properly aligned in memory. The coefficients array should be updated to reflect the new number of taps, and any unused coefficients should be removed.
#define NUM_TAPS 28
static q15_t firCoeffs[NUM_TAPS] = {35, -23, -104, -138, 0,
                                    319, 543, 249, -657, -1543,
                                    -1268, 967, 4736, 8345, 9835,
                                    8345, 4736, 967, -1268, -1543,
                                    -657, 249, 543, 319, 0,
                                    -138, -104, -23};
  1. Update the State Buffer Size: The state buffer size should be adjusted to reflect the new number of taps. The size of the state buffer is calculated as BLOCK_SIZE + NUM_TAPS - 1, which should now be 59 for a block size of 32 and 28 taps.
static q15_t firStateQ15[BLOCK_SIZE + NUM_TAPS - 1];
  1. Verify Memory Alignment: Ensure that the coefficients array and the state buffer are properly aligned in memory. The Cortex-M4 processor requires Q15 arrays to be aligned to 4-byte boundaries. This can be verified by checking the memory addresses of the arrays and ensuring that they are divisible by 4.

  2. Recompile and Test: After making the necessary changes, recompile the code and test the FIR filter implementation. The HardFault should no longer occur, and the filter should process the input data correctly.

In addition to these steps, it is important to ensure that the arm_fir_q15 function is correctly initialized and that the input and output buffers are properly aligned. The arm_fir_init_q15 function should be called with the correct parameters, and the input and output buffers should be aligned to 4-byte boundaries.

arm_fir_instance_q15 S;
q15_t* inbufPtr_q15;
q15_t* outbufPtr_q15;
inbufPtr_q15 = &signal_q15_in[0];
outbufPtr_q15 = &signal_q15_out[0];
arm_fir_init_q15(&S, NUM_TAPS, (q15_t *)&firCoeffs[0], (q15_t *)&firStateQ15[0], blockSize);

By following these steps, the HardFault issue can be resolved, and the FIR filter implementation can be successfully executed on the Cortex-M4 processor. Proper data alignment and adherence to the CMSIS DSP library requirements are critical to ensuring the correct operation of the filter and avoiding hardware exceptions.

Similar Posts

Leave a Reply

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