单个生产者和单个消费者的环形缓冲区的最佳大小

时间:2019-01-25 06:26:37

标签: real-time microcontroller rtos circular-buffer

我有一个单一的生产者,一个单一的消费者问题(我相信)可以使用循环/环形缓冲区解决。

我有一个运行RTOS的微控制器,带有一个ISR(中断服务程序),用于处理UART(串行端口)中断。当UART产生中断时,ISR将接收到的字符发送到循环缓冲区中。在另一个RTOS任务(称为packet_handler)中,我正在从该循环缓冲区中读取数据,并运行状态机来解码数据包。一个有效的数据包有64个字节,包括所有成帧字节。

UART在115200上运行,每10毫秒到达一个数据包。 packet_handler每10毫秒运行一次。但是,由于执行另一个更高优先级的任务,此处理程序有时可能会被调度程序延迟。

如果我使用任意大的循环缓冲区,则不会丢包。但是在这种情况下如何确定最佳的循环缓冲区大小?至少在理论上。在实践中如何确定缓冲区大小?

目前,我正在通过一些检测功能检测缓冲区溢出,然后增加缓冲区大小以减少数据包丢失。

4 个答案:

答案 0 :(得分:1)

由于您正在处理随机过程(根据您的解释),因此永远不会安全。 回答您的问题:您将需要一个无限的缓冲区,以防使用者任务处于就绪状态持续数秒钟。因此,您将不得不在初始方法中进行一些更改:

  • 增加使用者的优先级,以确保执行10ms(最小的缓冲区方法,但可能无法实现)。
  • 尝试更好地表征模型,以便预测将不执行使用者任务的最大时间间隔(使系统尽可能可预测)。
  • 丢失包装的缓冲区大小随机(可能不安全)

答案 1 :(得分:0)

我会这样计算:

只知道64字节
环形缓冲区中仍有64字节
+ 100%节省
 ===================
256字节缓冲区

但这只是一个猜测。您必须对缓冲区进行一些最坏的情况测试,然后再花费+ 100%进行保存。

答案 2 :(得分:0)

尽管以上所有答案都是正确的,并且可以阐明问题,this page总结了选择环形缓冲区大小时要考虑的所有因素。

可以使用某些排队模型从理论上分析手头的问题并找出合适的环形缓冲区大小。

一种更为实用的方法是从一个大的缓冲区开始,然后在实际测试用例中找出最大使用的缓冲区大小(此过程称为水印),并在最终代码中使用该数字。

答案 3 :(得分:0)

只需确定最大可能的延迟-所有可以运行的所有更高优先级任务的执行时间之和-然后除以数据包到达间隔即可。

这可能并不简单,但是可以通过按照速率单调原则将仅确定性最高的任务设置为更高的优先级,并将确定性较低且运行时间较长的任务降低为较低的优先级,从而简化操作,这些任务经常运行很短时间,但偶尔会发生运行时间更长的候选对象可以分为两个任务(和更多队列),以将较长的执行任务卸载到较低的优先级。