Pending Interrupt Causes Crash

mkrug wrote on Friday, August 24, 2007:

Hello,

I did a small port to the HC12 (that has only minor differences to the existing HCS12 Port).
My application communicates on the CAN Bus. As long as the CAN load can be handled everything works fine. If I increase the CAN load so that I got an overrun interrupt pending while I am still processing the receive interrupt the application crashes. If I just disable the overrun interrupt everything is fine again. However I like to get notice if an overrun occurs by increasing an counter within the overrun ISR. I copied fragments of the two ISR to make it more clear what I programmed.
Does anyone has an idea what I did wrong ?

Best Regards
Markus

/* receive ISR */
ISR(CAN0_recv_ISR)
{
  static unsigned char xYieldRequired = pdFALSE;
  C0RFLG = C0RFLG | 0x01;  /* Reset receive flags */
  switch (IDHIT)
    {
      case 0x00:
        {
          /* CAN ID 0x100 was received */
          xYieldRequired = xTaskResumeFromISR(CAN_ID100_TASK_handle);
          break;
        }
      default:
       break;
    }
  if( xYieldRequired == pdTRUE )  
   portTASK_SWITCH_FROM_ISR();
}

/* overrun ISR */
ISR(CAN0_error_ISR)
{
static int counter = 0;
C0RFLG = C0RFLG | 0x02;        /* reset overun flags*/
counter ++
}

davedoors wrote on Sunday, August 26, 2007:

Don’t know about the HC12, but you CAN0_recv_ISR could probably benefit from using a binary semaphore in place of the xTaskResumeFromISR() call.  Here is an extract from the xTaskResumeFromISR() documentation.

"vTaskResumeFromISR() should not be used to synchronise a task with an interrupt if there is a chance that the interrupt could arrive prior to the task being suspended - as this can lead to interrupts being missed. Use of a semaphore as a synchronisation mechanism would avoid this eventuality"

Look at the example on http://www.freertos.org/a00124.html and notice that the semaphore is only taken in the task and only given in the interrupt.  This is the recommended method.

mkrug wrote on Monday, August 27, 2007:

I changed the mechanism to semaphore (as you described). My proplem disappeared !!! Does anyone know what will happen if a running task gets interrupted by an interrupt service routine that starts exactly this task again. Do I then have two instances of the same task ? Or is the interrupted task just canceled and thrown away ?
Best Regards
Markus