0

我试图为我的 AVR 编写一个简单的任务系统。代码在这里。(可悲的是,这也是 MWE。)

系统背后的基本思想是周期性定时器中断设置一个标志,然后主应用程序循环检查该标志以运行任务。任务处理函数是可重入的,因此对于每个待处理的任务,每次迭代都会执行一次:

while (1) {
    if (flTask) {
        flTask = task_process_next();
    }

    // Do other awesome stuff in the loop
}

为了保持设计简单,需要定期运行的任务重新发布自己。

所以可以像这样添加一个简单的心跳任务:

task_add(heartbeat_task, 0);

它的代码可能如下所示:

void heartbeat_task(void)
{
    task_add(heartbeat_task, 10000); // Re-post task

    led_toggle(LEDGreen);
    xbee_send_heartbeat(BASE_STATION_ID);
}

我的问题是:每个定期任务将运行两次。

我已经通过切换引脚确认(正如您在我链接到的代码中看到的那样),在每个任务的第一次和重复执行期间都会task_add调用该方法。

但是,尽管显然是第二次添加任务,但它从未运行。

我进一步尝试大大简化代码task_process_next(包括通过添加一个循环以在一次调用中处理所有任务,以及通过更改运行条件以忽略溢出)。这些修改都没有被证明是成功的。


我的问题是:我是否弄乱了我的链表实现的一些细节,这可能导致重新发布的任务被忽略?

特别是,我是否不小心使列表中的节点可以被跳过而不被评估或运行?

我知道如果不在硬件上运行就很难调试这类问题,但我希望另一双眼睛能看到我错过的东西。

我很乐意提供任何额外的信息/做任何必要的测试。

4

1 回答 1

0

队列末尾的任务被删除时,队列已损坏:

    if (prev) {
        prev->next = task->next;
    } else {
        tasks.head = task->next;
    }

    // Adding these lines fixed the problem
    if (task == tasks.tail) {
        tasks.tail = prev;
    }
于 2013-09-09T12:52:28.243 回答