0

我有一个特定的任务例程,它以特定的顺序执行一些操作,这些操作处理一些易失性变量。有一个特定的中断可以异步更新这些易失性变量。因此,如果发生这样的中断,任务例程应该重新启动。通常 FreeRTOS 会恢复任务,但这会导致错误的派生值,因此需要重新启动例程。我也不能将任务例程保持在关键部分,因为我不应该错过任何中断。

FreeRTOS 中有没有一种方法可以实现这一目标?就像一个 vtaskRestart API。我本可以删除该任务并重新创建它,但这会增加很多内存管理的复杂性,我想避免这种情况。目前我唯一的选择是在例程中添加对标志的检查,以查看是否发生了上下文切换,如果是,则重新启动,否则继续。

谷歌搜索没有得到任何线索。似乎人们从未遇到过这样的问题,或者可能是这种设计很差。在 FreeRTOS 论坛中,很少有人要求重新启动任务似乎没有同样的问题。stackOverflow 在 freertos + 任务 + 重启时没有结果。所以,这可能是第一篇使用这个标签组合的帖子;)

有人可以告诉我这在 FreeRTOS 中是否可以直接实现吗?

4

2 回答 2

0

您可以为此目的使用信号量。如果您决定使用信号量,您应该执行以下步骤。

  • 首先,您应该创建一个二进制信号量。
  • 信号量必须在中断例程中使用 xSemaphoreGiveFromISR( Example_xSemaphore, &xHigherPriorityTaskWoken );
  • 并且,您必须检查任务中的信号量。

    void vExample_Task( void * pvParameters ) {
    for( ;; ) {
    if (xSemaphoreTake( Example_xSemaphore, Example_PROCESS_TIME)==pdTRUE) {

    } } }

于 2013-12-13T08:01:23.003 回答
0

为此,您应该使用队列并使用 queue peek 函数来获取易失性数据。

我正在使用它,因为我有一个实时计时器,这样我就可以将时间用于我的所有任务,而没有任何阻塞。

它是怎么回事:声明队列:

xQueueHandle     RTC_Time_Queue;

创建 1 个元素的队列:

RTC_Time_Queue = xQueueCreate( 1, sizeof(your volatile struct) );

每次中断发生时覆盖队列:

xQueueOverwriteFromISR(RTC_Time_Queue, (void*) &time);

并从其他任务窥视队列:

xQueuePeek(RTC_GetReadQueue(), (void*) &TheTime, 0);

xQueuePeek 末尾的 0 表示如果队列为空,您不想等待。队列窥视不会删除队列中的值,因此每次窥视时都会出现,并且代码永远不会停止。

此外,您应该避免从 ISR 和 RTOS 代码访问变量,因为您可能会遇到意外损坏。

于 2014-01-03T10:50:18.770 回答