MCU: STM32F303
ChibiOS: 2.6.3 (FPU enabled, prefetch buffer on)
Board: custom
I have a pretty IRQ intense application running (FOC motor control of 2 PMSM) and experiencing spurious BusFaults after some random time (10s - 5mins). So most probably the most nasty thing to debug. After disabling the CM4 write buffer I was able to transform the imprecise BusFaults to precise ones and isolate the problem. The fault always appears at the same code location, which gives me some hope to find a solution.
TIM1, TIM2, TIM3, TIM4 and TIM8 fire fast IRQs with priorities from 3 to 5, ChibiOS is configured this way:
Code: Select all
#define CORTEX_PRIORITY_SYSTICK 9
#define CORTEX_PRIORITY_SVCALL 8
#define PORT_INT_REQUIRED_STACK 128
#define PORT_IDLE_THREAD_STACK_SIZE 512
None of the timers use any OS functions.
Furthermore I have a SPI DMA running (two to be precise, one DMA for RX, one for TX) at IRQ 12 posting to a Mailbox. Here is the code:
Code: Select all
void DMA1_Channel2_IRQHandler()
{
CH_IRQ_PROLOGUE();
DMAClearTCIE(DMA_Channel_RX);
DMAClearTEIE(DMA_Channel_RX);
msg_t event = EVENT_RX_DONE;
if(DMA1->ISR & DMA1_FLAG_TE2)
event = EVENT_RX_ERROR;
if(SPI1->SR & SPI_FLAG_CRCERR)
event = EVENT_RX_ERROR;
chSysLockFromIsr();
EventClientSendI(spi1.pEventClient, event);
chSysUnlockFromIsr();
CH_IRQ_EPILOGUE();
}
EventClientSendI is part of my custom event handling system, it basically does this:
Code: Select all
msg_t EventClientSendI(EventClient* pClient, uint32_t event)
{
return chMBPostI(pClient->pEventQueue, event | (pClient->clientId << 16)); // combine event with source ID
}
I created a idle tick hook function to measure the CPU load, it goes to 40% at max.
The BusFault occurs during _port_irq_epilogue of the above DMA handler, to be more precise here:
Code: Select all
(ctxp + 1)->fpccr = (regarm_t)(fpccr = SCB_FPCCR);
The ctxp value is 0x55555555, so that dereferencing goes to nirvana. I know that this is the stack fill pattern, but I checked all stacks and they all had large areas of 0x55555555 still there. All stack checks and debug options are enabled, none of them fires.
What I absolutely don't get is why the code crashes in that line. According to the code ctxp must have been used/dereferenced before, but everything is fine there. Is there some weird situation where a fast IRQ could smash in there?
Furthermore, this problem seems to occur only in debug builds. A release build with -Os runs without a problem for at least 30mins. As the BusFaults occur after random time I would not take for granted that the problem never occurs in release builds, I just did not encounter it yet.
I would really like to figure out the root cause of this problem to make sure it does not occur again, please point me to the things to look after/check.