如何清晰地告诉任务要在FreeRTOS中死亡

问题描述 投票:2回答:1

我正在使用ESP32照明,我选择的HomeKit库使用FreeRTOS和esp-idf,我不熟悉。

当前,每当需要更改灯光的颜色时,都会调用一个函数,它只是一步更改它。我想让它在颜色之间渐隐,这需要运行一两秒钟的功能。有了此块,程序的主要执行显然会使它变得毫无响应,因此我需要将其作为任务运行。

我面临的问题是,我只希望一次运行一个衰落函数的一个副本,如果在完成之前第二次调用它,则应该退出第一个副本(而不等待整个淡入时间),然后再开始第二个副本。

我发现vTaskDelete,但是如果我要在任意点处终止衰落功能,则某些变量和LED本身将处于未知状态。为了解决这个问题,我想到了使用“ kill flag”全局变量,衰落函数将在其每个循环中对其进行检查。

这是我正在考虑的伪代码:

update_light {
    kill_flag = true
    wait_for_fade_to_die
    xTaskCreate fade
}

fade {
    kill_flag = false
    loop_1000_times {
        (fading code involving local and global variables)
        .
        .
        if kill_flag, vTaskDelete(NULL)
        vTaskDelay(2 / portTICK_RATE_MS)
    }
}

我的主要问题是:

  • 这是执行此操作的最佳方法还是有更好的选择?
  • 如果可以,我的wait_for_fade_to_die等于多少?我暂时无法找到任何东西,但是我是FreeRTOS的新手。
esp32 freertos esp-idf
1个回答
0
投票

很抱歉,我给您的印象是,您在尝试解决您的具体问题时走上了错误的道路。您写的是您对FreeRTOS和esp-idf不熟悉,所以我建议您先熟悉freeRTOS(或与一般的RTOS或任何其他RTOS相同的概念,然后将这些知识转移到freeRTOS,...) 。

[这样做时,您会注意到(除了一些特定的示例),task与为单个作业的顺序“批处理”而编写的function完全不同。] >

模型与理论

通常,在嵌入式系统中设计好的RTOS任务时想到的最有用的model是状态机的对象,该任务接收对其做出反应的events,可能会更改其state和/或执行某些actions>],其起点和有效负载取决于状态机接收的事件以及检测到事件时其所处的状态。在没有事件的情况下,任务应该不是idle而是block在RTOS函数创建的某个障碍处,应该传递下一个相关事件。

实现这样的任务意味着对任务函数进行编程,该任务函数包含一个简短的初始化块,然后是一个无限循环,该无限循环首先调用RTOS库以获取下一个逻辑事件(请参见下面的...),然后是处理该事件的代码。逻辑事件。现在,逻辑事件不必由RTOS事件表示(尽管这可以在简单的情况下发生),但是也可以由RTOS队列,邮箱或其他实现。在这种设计模式下,基于RTOS的软件的任务“永远存在”,等待下一个作业执行。

如何将理论应用于您的问题

您必须检查如何将编程问题分解为不同的任务。

当前,每当需要更改灯光的颜色时,都会调用一个函数,它只是一步更改它。我想让它在颜色之间渐隐,这需要运行一两秒钟的功能。有了此块,程序的主要执行显然会使它变得毫无响应,因此我需要将其作为任务运行。

我希望我正确理解了您的应用程序的目标:该系统正在驱动多个不同颜色的光源,并且某些“请求光源”正在选择要显示的下一个颜色。当要求使用其他颜色时,不应立即执行更改,但在一定时间内会出现“褪色”。即使发生淡入淡出,系统(及其请求源)也应保持响应,这可能会改变中间的淡入淡出的方向。

我想您没有说颜色要求来自哪里。因此,我猜测此请求源可能是在后台运行的某些按钮,串行接口或复杂算法(或随机数生成器?)。现在,它并不重要。

我面临的问题是我一次只希望运行一个衰落函数的副本,如果在完成之前第二次调用它,则应该退出第一个副本(而不必等待整个淡入时间),然后再开始第二个副本。

您本质上在寻找的是如何随时更改state

(此处为淡入淡出的目标颜色),以使旧的,正在进行的淡入淡出过程变得过时,但输出(=淡入淡出)行为将不能以不连续的方式进行更改。

我建议您设置以下任务:

  • 一个(或多个)任务可以根据您的需要从...生成颜色更改请求。

  • 一项评估当前应输出哪种颜色混合的任务。该任务应准备就绪一个。新的颜色请求(更改“目标颜色”状态而不更改当前的颜色混合值)b。定期的滴答事件(例如,来自硬件或软件计时器)导致颜色混合值被更新为当前目标颜色的方向

  • 零,通过驱动系统的输出功能(例如,配置GPIO或PWM,或通过串行连接传输信息……我们不知道)来实现颜色混合值的一项或多项任务。如果调整输出部分只是分配一些寄存器,那么“零”是您的正确选择。否则,请尝试“一个或多个”。

  • 现在要做什么

    我找到了vTaskDelete,但是如果我要在任意点处终止渐变功能,则某些变量和LED本身将处于未知状态。为了解决这个问题,我想到了使用“ kill flag”全局变量,衰落函数将在其每个循环中对其进行检查。

只是不要那样做。杀死一个任务,即使是没有准备好从内部被杀死的任务,也会导致对软件进行管理和清理输出内容的需求的跟进,最终您会想知道为什么甚至开始使用RTOS。

我确实知道,以从未有过的方式开始进行设计和编程是一项巨大的努力,就像跳入冷水一样。请相信我,这样您将学习如何设计和实现出色的嵌入式系统的基础知识。专业教育公司以数千美元/欧元/英镑的价格提供有关RTOS集成,响应式编程和状态机设计的课程,这是此类工作知识的良好指示。

祝你好运!通过这种方式,您会遇到很多详细的问题,欢迎将其发布到此公告板上(或在上面找到较早的答案)。

© www.soinside.com 2019 - 2024. All rights reserved.