2024-11-18 02:10 AM - last edited on 2024-11-18 03:20 AM by SofLit
I am using the STM32H562VGT6 and IAR Workbench.
I have set up a 4kHz interrupt with LPTIM3 and started transmitting 32 bytes of data using HAL_SPI_Transmit_DMA.
If I break and resume execution after starting the timer interrupt, the SP becomes 0xffff ffd8, causing a HardFault error. The call stack only contains (Exception frame), making it untraceable. The stack area is from 0x2000'0f90 to 0x2000'4f8f.
Although HardFault_Handler() is defined in stm32h5xx_it.c, breaking there does not hit during a HardFault.
Breaking in MemManage_Handler or BusFault_Handler also does not hit.
Commenting out HAL_SPI_Transmit_DMA during the 4kHz interrupt prevents the HardFault, but adding macros to check if the SP is out of range within the HAL API does not trigger any response.
#define CHECK_MSP() {\
uint32_t msp; \
__asm volatile ("MRS %0, msp" : "=r" (msp)); \
if (msp < 0x20000f80 || 0x20004f7f < msp) { \
__BKPT(0); \
} \
}
How can I capture the cause of this issue?
2024-11-18 02:17 AM - edited 2024-11-18 02:25 AM
Please put code in a code block:
Stack overflow doesn't cause a hardfault error unless you set up your linker file in such a way a stack overflow causes access in an illegal memory region. Or if you set up the MPU to define an illegal region past the stack.
Check in STM32CubeMX in NVIC if MemManage_Handler and BusFault_Handler interrupts are enabled.
2024-11-18 02:29 AM
Here is InterruptHandler in 4kHz and Registers in HardFault
{
static const int clkTbl[8 + 1][8] = {
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 1, 0, 0, 0, 1 },
{ 0, 0, 1, 0, 0, 1, 0, 1 },
{ 0, 1, 0, 1, 0, 1, 0, 1 },
{ 0, 1, 0, 1, 1, 0, 1, 1 },
{ 0, 1, 1, 1, 0, 1, 1, 1 },
{ 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
};
int step;
int clk[4];
int dir[4];
BYTE val;
int side = c_count & 1;
if(HAL_SPI_Transmit_DMA(&hspi4, (uint8_t*)(&c_dirclk[(c_count +1 )& 1][0]), 32) != HAL_OK){
Error_Handler();
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
id_type id = i * 4 + j;
if (id < MOTOR_COUNT) {
step = (int)m_motors[id].proceed();
clk[j]= abs(step);
dir[j] = (m_motors[id].direction() ? 1 : 0);
} else {
clk[j] = 0;
dir[j] = 1;
}
}
for (int seq = 0; seq < 8; seq++) {
val = 0;
for (int k = 0; k < 4; k++) {
val |= ((dir[k] << (k + 4))) | (clkTbl[clk[k]][seq] << k);
}
c_dirclk[side][(seq * 4 + i)] = val;
}
}
c_count++;
}
2024-11-18 02:39 AM
Can you check the value of CFSR? And SCB->SHCSR?
https://community.st.com/t5/stm32-mcus/how-to-debug-a-hardfault-on-an-arm-cortex-m-stm32/ta-p/672235
2024-11-18 02:51 AM
Thank you for replying.
CFSR : 0x1001
SHCSR : 0x4
And here is debug log messeage in IAR Workbench :
------------------------------------------------------------------------------------------------
Mon Nov 18, 2024 19:46:50: MemManage fault escalated into HardFault
Mon Nov 18, 2024 19:46:50: The MemManage handler is disabled
Mon Nov 18, 2024 19:46:50: HardFault exception.
Mon Nov 18, 2024 19:46:50: The processor has escalated a configurable-priority exception to HardFault.
Mon Nov 18, 2024 19:46:50:
Mon Nov 18, 2024 19:46:50: An MPU or Execute Never (XN) default memory map access violation has occurred on an instruction fetch (CFSR.IACCVIOL, MMFAR).
Mon Nov 18, 2024 19:46:50:
Mon Nov 18, 2024 19:46:50: A derived bus fault has occurred on exception entry (CFSR.STKERR, BFAR).
Mon Nov 18, 2024 19:46:50:
Mon Nov 18, 2024 19:46:50: Could not determine the location where the exception occurred.
Mon Nov 18, 2024 19:46:50:
Mon Nov 18, 2024 19:46:50: See the call stack for more information.
2024-11-18 03:29 AM - edited 2024-11-19 01:34 AM
@Thoufiel wrote:SHCSR : 0x4
Only one handler is enabled
@Thoufiel wrote:Mon Nov 18, 2024 19:46:50: The MemManage handler is disabled
As I suspected.
Have you enabled the MPU?
Can you step through the interrupt until the error occurs?
2024-11-18 09:57 PM
MPU is not used.
>Can step through the interrupt until the error occurs?
I have tried several times, but the step execution does not generate the error properly and I am not able to stop just before the error.
2024-11-18 11:28 PM
>Can step through the interrupt until the error occurs?
With core faults involved, this usually implies stepping through on instruction/assembler level.
Just saying.
2024-11-18 11:38 PM
Any DMA into an auto/local array?
2024-11-18 11:45 PM
>Any DMA into an auto/local array?
No, and c_count, c_dirclk is a static member of the class to which this interrupt handler function belongs.