RohitMat
RohitMat

Reputation: 165

FreeRTOS not context switching from ISR - ARM926EJ-S core

I'm trying to implement a Jpeg encoding setup on top of freeRTOS. The main task initialises the capture unit.

void Video_SNAPThread(void* pvParameters)
{
    while (1)
    {
        capture_startSNAP();         /* SNAPSHOT Capture - Encode API*/
        vTaskSuspend(xHandleSNAP);   /* Task Suspend - within context*/

    }
}

The capture_start function configures the sensor parameters and starts the capture unit which triggers a callback function on end of each frame (A frame end interrupt).

capture_startSNAP definition is as given below

int capture_startSNAP()
{
     TickType_t xMaxBlockTime;
     xMaxBlockTime = pdMS_TO_TICKS( 4000 );
#if defined(__1ST_PORT__) && !defined(__2ND_PORT__)
        sysprintf("Plug in sensor to port 0\n");
#endif
#if !defined(__1ST_PORT__) && defined(__2ND_PORT__)
        sysprintf("Plug in sensor to port 1\n");
#endif
#if defined(__1ST_PORT__) && defined(__2ND_PORT__)
        sysprintf("Plug in sensor to port 1 and port 2\n");
#endif
        sysSetInterruptPriorityLevel(IRQ_VIN, 2);
        sysSetInterruptPriorityLevel(IRQ_VIN1, 1);
        configASSERT( xTask_Notify == NULL );
        xTask_Notify = xTaskGetCurrentTaskHandle();
        Smpl_NT99141_HD_SNAP();

        while((ulTaskNotifyTake(Task_Woken , xMaxBlockTime ) == 0));             
        jpegmain();
        return 0;
}

The Smpl_NT99141_HD_SNAP function sets up the call back function and starts the capture.The ISR notifies the end of frame and in turn should do a context switch to the Video_SNAPThread task for further data processing. I have used task notification method to switch from the ISR back to the Video_snapthread for encoding, but its not working.

void VideoIn_InterruptHandler_SNAP(void)
{
        pVin1->Close();
        printf("Interrupt");   
        Task_Woken = pdFALSE;
        configASSERT( xTask_Notify != NULL );
        vTaskNotifyGiveFromISR( xTask_Notify, &Task_Woken );
        xTask_Notify = NULL;
        portYIELD_FROM_ISR( Task_Woken );     
}

Please correct me if I'm wrong somewhere. Still a novice in freeRTOS.

Upvotes: 0

Views: 668

Answers (2)

fbourge
fbourge

Reputation: 129

Sorry to dig up this old thread but I think that my point of view could help other peoples facing absence of context switching in FreeRTOS.

Firstly : Never try to print out something (like a debug string) on UART in Interrupt Context. It's a rule of thumb applicable everywhere in embedded software developments. Interrupt Context implies to be as quickest as possible. Inversely, print something implies to be slow or sometimes even worst (to sleep).

For debugging purpose in interrupt context you have several options :

  • Use a debugger (gdb...)
  • Use debug registers of your MCU (instructions, cycles, errors counters)
  • Toggle a GPIO pin (to probe with oscilloscope or to switch on a led)

Secondly, other causes can result in blocking a switch of context :

  • Higher priority task(s) could hold your task in suspend state for a while or for ever.
  • Lack of protection in the interrupt handler code. Did you think about reentry protection ?

     In the interrupt handler :
     1. disable interrupt (interrupt mask register)
     2. clear interrupt source
     3. Do your job (keep it short and simple)
     4. enable interrupt
    

Good practices : embedded.com

Upvotes: 1

RohitMat
RohitMat

Reputation: 165

The problem has been solved. Apparently, the 'Debug' printf() inside the interrupt triggered the issue.

Upvotes: 0

Related Questions