当前位置:  开发笔记 > 编程语言 > 正文

FreeRTOS vTaskDelayUntil()立即完成

如何解决《FreeRTOSvTaskDelayUntil()立即完成》经验,为你挑选了1个好方法。

我有一个问题,vTaskDelayUntil()函数没有延迟,但立即完成.这是代码:

TickType_t xLastWakeTime = xTaskGetTickCount();
while(1){
    if (xSemaphoreTake(xSemaphoreRS485, portMAX_DELAY) == pdTRUE) {
        printf("S display data %d\n", xTaskGetTickCount());
        sendDisplayData();
        printf("E display data %d\n", xTaskGetTickCount());
        xSemaphoreGive(xSemaphoreRS485);
        printf("W display data %d\n", xLastWakeTime);
        vTaskDelayUntil(&xLastWakeTime, 2000);
    }
}

从这里我得到以下输出:

S display data 29928
E display data 30534
W display data 3919
S display data 30534
E display data 31140
W display data 5919
S display data 31140
E display data 31746
W display data 7919
S display data 31746
E display data 32352
W display data 9919

函数sendDisplayData()执行大约需要670毫秒,xTaskGetTickCount()确认它.然后任务应该在1230毫秒左右等待,因此整个迭代可能需要2000毫秒.但vTaskDelayUntil()立即完成.第一次执行在30534结束,第二次执行也从30534开始.xTaskGetTickCount()返回的值证明vTaskDelayUntil()没有引入延迟.我也可以通过sendDisplayData()的输出频率来看.

第二个有趣的事情是xLastWakeTime显示完全不同的值,并且这些值实际上增加了2000.它不应该存储xTaskGetTickCount()返回的类似值吗?



1> Clifford..:

在您的第一次迭代xLastWakeTime中,值为3919,并且您请求增量为2000,因此延迟到5919,但您已在30534时调用它.

从文档中 vTaskDelayUntil()

应该注意的是,如果vTaskDelayUntil()用于指定已经过去的唤醒时间,则它将立即返回(不阻塞).

您的任务花费了26009个刻度(29928 - 3919)在初始信号量上被阻止.你的目标2000滴答增量早已过去.

我建议以下内容至少接近你的意图

for(;;)
{
    if (xSemaphoreTake(xSemaphoreRS485, portMAX_DELAY) == pdTRUE)  // Lock
    {
        TickType_t xLastWakeTime = xTaskGetTickCount();
        sendDisplayData();
        xSemaphoreGive(xSemaphoreRS485); // Unlock

        vTaskDelayUntil(&xLastWakeTime, 2000);
}

这将使循环迭代总共花费2000个滴答,包括执行所花费的时间sendDisplayData() 加上等待RS485资源可用的时间,这就是我想你想要的.

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有