来自 ISR 的 FreeRTOS Sempahore 无法正常工作
Posted
技术标签:
【中文标题】来自 ISR 的 FreeRTOS Sempahore 无法正常工作【英文标题】:FreeRTOS Sempahore from ISR not working 【发布时间】:2014-02-14 07:32:31 【问题描述】:我需要制作一个数据采集设备,其任务是对一些 GPIO 进行采样并记录 GPIO 状态并通过 UART 将其发送到 PC 以在 PC 上显示。我选择的算法是(请纠正我,因为我是 RTOS 的新手)创建一个以 1us 运行的计时器,然后轮询所有所需 GPIO 的状态。为此,我在 freertos 演示中使用了一个计时器。并在计时器 ISR 中给出一个信号量,它应该调用一个任务来完成所有剩余的工作。
不知道为什么,但我编辑的代码不起作用
我的 main() 是
int main(void)
/* Prepare the hardware to run this demo. */
prvSetupHardware();
vSemaphoreCreateBinary(SemaphoreTask);
if( SemaphoreTask != NULL )
xTaskCreate( SemaphoreTakeTask, "SemaphoreTakeTask", 240, NULL , 3, NULL );
vTaskStartScheduler();
for(;;);
return 0;
任务 1 我写的一个虚拟函数只是为了测试信号量是否工作
void SemaphoreTakeTask(void* parameter)
vSetupTimerTest(10); // Timer initialization function in FreeRtos DEMO
TRISEbits.TRISE6 = 0; // Set the GPIO as Output
xSemaphoreTake( SemaphoreTask, 0 ); // As mentioned in user guide just take the semaphore once to clear the semaphore at start
for(;;)
xSemaphoreTake( SemaphoreTask, portMAX_DELAY );
LATEbits.LATE6 ^= 1; // Toggle an IO to see whether its working
定时器 ISR 处理程序
void vT2InterruptHandler(void)
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Clear the timer interrupt. */
IFS0CLR = _IFS0_T2IF_MASK;
xSemaphoreGiveFromISR(SemaphoreTask, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken != pdFALSE)
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
当我在 ISR 处理程序中放置断点时,它会出现,但 GPIO 没有切换(我放置在任务 1 中)
我是 RTOS 的新手,如果我错过了代码中的任何基本内容,请原谅我
我只需要从 ISR 处理程序中提供一个信号量
经过一些锻炼后,我发现所有问题都是在调用 xSemaphoreGiveFromISR 时发生的。控件转到 vAssertCalled 函数并停留在无限循环中
xSemaphoreTake() 总是返回 pdFALSE
【问题讨论】:
你在运行什么?您必须花一些时间才能为 1MHz 的中断率提供服务。当我在 72MHz ARM Cortex-M3 上评估 FreeRTOS 时,仅线程上下文切换时间就在 15us 左右(顺便说一下,FreeRTOS 是我评估的三个 RTOS 中最慢的,最好的仍然只有 5us 上下文切换时间)。某些目标的中断延迟也很重要,具体取决于架构。与其在定时器上轮询 GPIO,不如使用 GPIO 中断。如果您需要计时信息,可以轮询 GPIO 中断上的计时器或使用计时器捕获输入。 【参考方案1】:中断的优先级必须设置为低于configMAX_SYSCALL_INTERRUPT_PRIORITY
要获得更清晰的想法,请参阅 SourceForge Forum
【讨论】:
以上是关于来自 ISR 的 FreeRTOS Sempahore 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
STM32 ISR 例程挂在 cmsis-OS osThreadFlagSet() 内部
STM32:将 USART 与字符匹配 ISR 和 DMA 缓冲区一起使用