code crashing in ISR- Cortex-M4

query1920 wrote on Wednesday, October 24, 2018:

Hello,
I am using Cortex M4 processor with Keil compiler with FreeRTOS and i notice that occasionally code is crashing in start up file ( attached is the snapshot of the point where code gets to when i stop controller).

Basically the system is a simple data acquisition board that has various sensor data collected in an FPGA. FPGA then sends a bulk of data-stream to my microcontroller on interrupts.
this data is stored on to external NAND flash memory (parallel type).

Using stack window , I see that the code always gets into an ‘UNKNOWN AREA’ in ISR. This ISR is called during the time when I’m writing data into the NAND flash. I’m certain that the micro-controller gets interrupts during the data-writing process.

I am unable to understand why would the code specifically go to the region that I have highlighted in the attachment.
Any help would be appreciated – I have spent weeks trying to resolve this problem.

rtel wrote on Wednesday, October 24, 2018:

I’m afraid it is not clear what the problem you describe is or why you
think it is a FreeRTOS issue - especially if it is in the start up code.
However, looking at the screen shot it looks you have entered a
default interrupt handler - so you have not installed a real handler for
whichever interrupt executed. The first thing to do would be to
determine which interrupt executed.

heinbali01 wrote on Thursday, October 25, 2018:

Interrupts that you do not define will all end-up in the same routine ( Default_Handler() ), which exists of a for-ever-loop.

What you can do is define all possible interrupts:

    ...
    void NMI_Handler()            { for( ;; ); }
//  void HardFault_Handler()      { for( ;; ); }
    void MemManage_Handler()      { for( ;; ); }
    void BusFault_Handler()       { for( ;; ); }
    void UsageFault_Handler()     { for( ;; ); }
//  void SVC_Handler()            { for( ;; ); }
    void DebugMon_Handler()       { for( ;; ); }
//  void PendSV_Handler()         { for( ;; ); }
//  void SysTick_Handler()        { for( ;; ); }
    void WWDG_IRQHandler()        { for( ;; ); }
    void PVD_IRQHandler()         { for( ;; ); }
    void TAMP_STAMP_IRQHandler()  { for( ;; ); }
    etc...

In this example, I commented-out the ones that are used by the application.

In this way, the .weak declarations, which call Default_Handler(), will be overwritten. Make sure to define all possible interrupts that you do not use.

Now when the undefined interrupt is called, at least you will see which interrupt was triggered.

query1920 wrote on Thursday, October 25, 2018:

My ISR looks like below

void ACQ_TASK_DataReady_ISR(void)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;

FpgaInterruptFlagClear();

if (acqTaskInitialisedOk)
{
		
    xSemaphoreGiveFromISR(m_acquisitionSemaphoreHandle,
                          &xHigherPriorityTaskWoken);
		
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken); 	
}

if i comment portYIELD_FROM_ISR then system doesnt crash but when i probed signals on oscope i see that interrupt remains high for a long time hence losing many expected interrupts. ( in snapshot green signal is interrupt which remained high while my system performed write to flash task which is in yellow)

However, if i dont comment this function then system is crashing. Crash occurence is very randon some times it happen as soon as system is turned ON, but at times it runs for hours without any issue.
Since I am getting interrupt from FPGA at the variable frequency(fastest at .24msec) , i was wondering that may be at time during context switching due to multiple occurance of interrupt one after the other stack is getting corrupted causing it to crash.

To give you more information, i 4 interrupts ( FPGA, SYSTick, UART1, UART2). FPGA interrupt is the highest priority as compared to all other 4 interrupts.In Freertos configuration i have configured all these 4 interrupts as maskable my setting configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY to 5 (which is FPGA interrupt priority).

rtel wrote on Thursday, October 25, 2018:

Are you saying the interrupt remains high for the entire time that the
flash is being written to. Evidently the flash is not being written to
from the interrupt handler itself, so it would seem interpreting what
the trace is showing is a bit tricky. Unless the flash is being written
to by a higher priority interrupt, which also seems doubtful as you say
the FPGA interrupt is the highest priority.

Can’t remember if we already went through this, but which version of
FreeRTOS are you using? I ask because the newer the version the more
configASSERTS() are included in the code to help determine issues
arising from interrupt priority mis-configurations. Do you have
configASSERT() defined?

If the interrupts come in quickly then they will tail chain with each
other. So if the FPGA interrupt is executing when another FPGA
interrupt arrives then the second interrupt will be held pending
(assuming the first has been cleared) until the first has been handled -
at which point the interrupt handler will just be re-entered without any
impact on the stack.

query1920 wrote on Thursday, October 25, 2018:

As per oscope capture i see interrupt line remained high for the time flash was been written. My understanding was if i dont use portYeild function then context switching will be delayed till next interrupt but from scope capture it looks like interrupt arrives and since context switch is not enabled it keep executing flash write and once its done with that flash write task it execute the ISR either on next FPGA interrupt or systimer interrupt. From scope capture interrupt doesnt seems to be clearing and 1st step in my ISR is to clear interrupt. Does that mean it didnt service interrupt(ISR) and continued to execute flash write ?

Attached is the scope capture when portYield function is used, here you can see how frequently flash write function was interrupted and frequency at which i am getting interrupt.

In ISR i am giving semaphore and in FPGA task i am waiting on this semaphore to read data from FPGA. FPGA task is higher priority than flash write task. My project is using FreeRtOS version 10.0.1. I see configAssert() in config file.-

define configAssert(x) if((x) ==0) { taskDISABLE_INTERRUPTS(); for(;;);}

From the stack window in emulator, i have seen that whenever system crashes its in FPGA ISR, and mostly while returnng from the function where i am clearing the interrupt flag. This is why i thought may be system doesnt know where to return hence it crashes.



query1920 wrote on Thursday, November 01, 2018:

I defined Handlers for all interrupts which were enabled, and found out that code crashing due to bus error ( Presciserr). As per the Arm processor it says data bus error or due to stack corruption. It doesnt provide any more information on bus error and potential cause for it. Any idea where can i find more information on it ? Or any other troubleshooting recommendation on bus error fault ?

query1920 wrote on Thursday, November 01, 2018:

I defined Handlers for all interrupts which were enabled, and found out that code crashing due to bus error ( Presciserr). As per the Arm processor it says data bus error or due to stack corruption. It doesnt provide any more information on bus error and potential cause for it. Any idea where can i find more information on it ? Or any other troubleshooting recommendation on bus error fault ?

rtel wrote on Thursday, November 01, 2018:

You need to get the ARMv7-M technical reference and user manuals from
Arm directly. They are freely available - Google will find them but
sometimes finds older copies.