FreeRTOS 不从 ISR 进行上下文切换 - ARM926EJ-S 内核

FreeRTOS not context switching from ISR - ARM926EJ-S core

我正在尝试在 freeRTOS 上实现 Jpeg 编码设置。主要任务初始化捕获单元。

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

    }
}

capture_start函数配置传感器参数并启动捕获单元,在每帧结束时触发回调函数(帧结束中断)。

capture_startSNAP定义如下

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;
}

Smpl_NT99141_HD_SNAP 函数设置回调函数并启动 capture.The ISR 通知帧结束,然后应该执行上下文切换到 Video_SNAPThread 任务以进一步数据处理。我已经使用任务通知方法从 ISR 切换回 Video_snapthread 进行编码,但它不起作用。

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 );     
}

如有不妥之处请指正。还是freeRTOS的新手。

问题已解决。显然,中断中的 'Debug' printf() 触发了问题。

很抱歉挖掘这个旧线程,但我认为我的观点可以帮助其他人在 FreeRTOS 中面临缺乏上下文切换的问题。

首先:永远不要尝试在中断上下文中在 UART 上打印出一些东西(比如调试字符串)。这是嵌入式软件开发中随处适用的经验法则。 中断上下文意味着尽可能快。相反, print something 意味着缓慢甚至有时甚至最糟糕(睡觉)。

为了在中断上下文中进行调试,您有多种选择:

  • 使用调试器 (gdb...)
  • 使用 MCU 的调试寄存器(指令、周期、错误计数器)
  • 切换 GPIO 引脚(用示波器探测或打开 LED)

其次,其他原因可能导致上下文切换受阻:

  • 更高优先级的任务可能会使您的任务暂时或永远处于挂起状态。
  • 中断处理程序代码中缺少保护。考虑过再入保护吗?

     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