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
我正在尝试在 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