6

我在 STM32F4DISCOVERY 板上运行 FreeRTOS,并且我有以下代码:

xTaskCreate( vTask1, "Task 1", 200, NULL, 1, NULL );
xTaskCreate( vTask2, "Task 2", 200, NULL, 1, NULL );
vTaskStartScheduler();

其中 vTask1 是这个函数:

void vTask1( void *pvParameters )
{
volatile unsigned long ul;

    for( ;; )
    {
        LED_On(0);

        for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
        {
        }
        LED_On(2);
        LED_Off(0);
    }
}

vTask2 具有几乎相同的代码:

void vTask2( void *pvParameters )
{
const char *pcTaskName = "Task 2 is running\n";
volatile unsigned long ul;

    for( ;; )
    {
        LED_On(3);
        LED_Off(2);
        for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
        {
        }

        LED_Off(3);
    }
}

当我运行程序时,我看到 LED0 和 LED3 一直亮着(它们的切换对我的眼睛来说太快了,这很好),并且“共享资源”的 LED2 闪烁得非常快。问题是这样的:当我颠倒xTaskCreate调用顺序时,我会遇到相同的情况,但 LED2 的闪烁行为不同,速度要慢得多。为什么会发生这种情况,因为任务应该具有相同的优先级并因此遵循循环调度?他们不应该得到相同的时间吗?为什么仅在以不同的顺序创建它们之后它们的行为会发生变化?

提前致谢。

4

1 回答 1

1

rtos 不会尝试循环执行任务,您不应期望它们以任何特定顺序执行。正如 iama 在评论中指出的那样,您创建的任务都没有延迟。与其在 for 循环中通过无操作来创建延迟,不如使用延迟函数。这将允许执行 while(1) 循环中的代码,然后返回到 rtos,以便处理器可以运行其他任务,直到等待时间过去。如果您需要同步工作,您可能只想将其保留在单个任务中。如果您的一项任务依赖于另一项完成的某项任务,您可能需要使用信号量、队列或其他跨线程通信方法。

您的代码让我想起了当我从 main 中的 while(1) 循环转换为 rtos 时。如果您不熟悉使用 rtos,ST 的本指南看起来会是一个很好的介绍https://www.st.com/resource/en/user_manual/dm00105262-developing-applications-on-stm32cube-with-rtos-意法半导体.pdf

此外,不要依赖延迟功能进行细粒度计时;改用定时器驱动的中断。上面的链接应该让您更好地理解为什么我可以在这篇文章中进行管理。

ST 还应该在某个地方有示例项目,这将是很好的参考或用作您自己项目的开始。

于 2021-09-21T19:23:26.283 回答