全部学习汇总: GreyZhang/g_FreeRTOS: learning notes about FreeRTOS. (github.com)
前面简单分析了vTaskDelay(),这一次分析一下vTaskDelayUntil()的实现。之前,看文档的时候模模糊糊记得vTaskDelayUntil()能够完成的延迟更加精准一些。这一次,从代码设计的角度来看看为什么。
这里的pxPreviousWakeTime实现的功能还是一个参数的传入功能,传入的是一个时间基准。当然,它本身是一个指针,传入的并不是一个数值参数。这里,关键的一点信息在于:1,调度器不能挂起; 2,唤醒时间定时设置。看上去,套路跟之前分析的vTaskDelay()没有太大的差异。
这里,区分了tick是否超时。在每一种情况下,都判断了延时时间是否已经达到。如果达到了,那么接下来直接请求任务调度即可。
其实,这部分的处理跟之前分析的vTaskDelay()的处理接口也是很相似的。其实,主要的方式就是加入到delayed task链表之后触发任务调度请求。
那么,这两个接口差异点究竟在哪里呢?为什么说vTaskDelay()不如vTaskDelayUntil()精准呢?其实,看完代码基本上也能够理解两者的差异。如果理解两者的差异,其实从函数的接口形式就能够看出一些端倪。两个接口的延时实现其实都是定时器设置一个参考值之后不断进行判断,但是这个参考点的设置是不同的。vTaskDelay()设置的参考点总是从当前开始,而vTaskDelayUntil()参考点的设置其实是可以指定的。
这是一个使用的代码例子,其实,我觉得这个例子实现的功能跟vTaskDelay()接口实现的功能也没有太大的差异。尤其是出现 某些高优先级任务抢占的时候。那么,如果才会让着两个接口实现有一定差异呢?那肯定是参考点的设置不断更新的时候,可能会存在更加灵活的方式。
这是针对例子的分析以及增加的一个对比。其实,不管是vTaskDelayUntil()还是vTaskDelay(),如果不断遭遇到运行时间久且优先级高的任务,本身的精准度肯定都会受到影响。毕竟到现在为止,并没有看到这样的任务优先级有提升。从这个角度讲,前面考虑到的差异点,其实2种接口都受到影响。排除这样的差异之后,这两个接口的差异可以理解为:vTaskDelay()设置的其实是时间等待,而vTaskDelayUntil()实现的是框定一个时间窗口。