面试题-如何连续读取缓冲区而不丢失数据

Nav*_*een 3 c can-bus spi i2c embedded-linux

我是一名嵌入式工程师,经验不多。我在接受采访时被问到了一个问题,我想这并不新鲜,并且已经有了答案:

您有一个不断接收来自外部世界的输入的外设,该外设有一个缓冲区。输入的速率时不时地发生变化。外设需要读取输入缓冲区并对其进行处理。它检查输入消息并查看其是否与配置的过滤器匹配。如果匹配则转发,否则丢弃。

问题如下:

  1. 你如何处理这个问题?
  2. 如果缓冲区满了怎么办?您的缓冲区大小有限?外设仅具有一定的处理缓冲消息的速度。
  3. 如何使缓冲区适应不同的输入速度?

感谢你的帮助。谢谢。

Lun*_*din 5

基本上,他们会检查您是否曾经为某些串行外设编写过程序,因此这是一个很好的面试问题,可以检查某人是否是一个完全的初学者。

以“老派”方式执行此操作的正常方法是设置接收中断。如果数据可以不规则地到达并且我们不允许丢失数据,那么中断几乎是唯一明智的方法。特别是如果计划也支持不同的波特率。

然后可以将过滤器检查置于 ISR 内部(CAN 中除外,此类检查实际上由硬件完成)。从那时起,有效数据被传递到软件环形缓冲区。这最大限度地减少了 ISR 内的执行时间,同时解决了硬件缓冲区有限的问题。数据重入保护优选地需要通过环形缓冲区代码来执行。

现代方法宁愿避免中断,而是使用 DMA(如果微控制器支持)。这减轻了 CPU 处理频繁接收中断的负担。然后我们可以在每次缓冲区满时交换 DMA 缓冲区目标地址,并从那里使用原始缓冲区。或者,如果我们由于某种原因无法交换 DMA 缓冲区地址,则可以将整个 DMA 缓冲区粗略地硬复制到其他地方。

  • @Naveen 是的,以上内容适用于所有串行总线。如果输入的速率超出了 CPU 的处理能力,那么再多的队列也救不了你。处理实际数据本身的时间很可能比中断开销+延迟还要长,因此,如果您甚至无法及时接收数据,那么您如何期望以后有时间用它做一些有意义的事情呢?第一个工程师实践是编写一个合理的规范,第二个实践是质疑规范是否有意义。 (2认同)
  • 因此,如果你有一些 10MHz SPI 轰炸运行在 8MHz 系统时钟上的糟糕 AVR,问题不在于如何让 AVR 及时响应(这不会发生),而是质疑整体系统设计并质疑波特率和微控制器的选择。 (2认同)