0

我有兴趣使用 atmel avr 控制器从 LIN 总线读取数据。不幸的是,这种总线上的消息没有开始或结束指示符,唯一合理的解决方案似乎是蛮力解析。来自总线的可用数据被加载到循环缓冲区中,并且蛮力方法在缓冲区中找到有效消息。

使用 64 字节缓冲区和 20MHZ 服装,我如何测试我的代码的性能以查看是否可能发生缓冲区溢出?补充:我担心算法会运行缓慢,从而缓冲更多数据。

关于蛮力算法的一点。缓冲区中的第二个元素被假定为消息大小。例如,如果假定长度为 22,则对前 21 个字节进行异或并针对缓冲区中的第 22 个字节进行测试。如果校验和通过,代码会检查第一个(SRC)和第三个(DST)字节是否是它们应该是的。

4

2 回答 2

1

AVR 是性能分析最简单的微控制器之一,因为它是一个 RISC 机器,具有简单的指令集和众所周知的每条指令的指令执行时间。

因此,基本的程序是您使用汇编代码并开始计算不同的场景。基本寄存器操作需要一个时钟周期,分支通常需要两个周期,内存访问需要三个周期。一个 XORing 周期每个字节可能需要 5-10 个周期,所以它相对便宜。您如何获得汇编代码取决于编译器,但所有编译器都倾向于以合理易读的形式为您提供最终结果。

通常在没有看到算法并且对​​时序要求一无所知的情况下,很难对这类问题给出明确的答案。但是,由于 LIN 总线速度限制为 20 kbit/s,每个字节大约有 10 000 个时钟周期。这对几乎任何事情都足够了。


一个更困难的问题是如何处理取决于时序的 LIN 帧。这不是一个很好的习惯,因为它确实需要微控制器付出一些额外的时间。(使用第 9 位到底有什么问题?)

LIN框架由一个

  • 中断(至少 13 位时间)
  • 同步分隔符 (0x55)
  • 消息 ID(8 位)
  • 消息(0..8 x 8 位)
  • 校验和(8 位)

至少有四种可能的方法,它们的起起落落:

  1. (您的方法。)从所有可能的起始位置开始,并尝试找出校验和消息的位置。同步后,就不需要了。(简单但以 1/256 的概率返回幽灵消息。请记住丢弃同步字段。)

  2. 使用内部 UART 并寻找同步字段;尝试弄清楚分隔符之后的数据是否有意义。(这比上面的错误概率低,但需要同步分隔符无故障通过,因此可能会丢失消息。)

  3. 寻找休息时间。最简单的方法是为所有到达的字节加上时间戳。很可能不需要以任何方式缓冲传入的数据,因为数据速率非常低(最大 2000 字节/秒)。名义上,一帧的最后一个字符的结尾和下一帧的第一个字符的开始之间的距离至少为 13 位。由于接收一个字符需要 10 位,因此接收前一个消息中的最后一个字符的结尾和下一个消息的第一个字符的结尾之间的延迟标称至少为 23 位。为了允许对位时序有一些容限,可以将限制设置为例如 17 位。如果“字符接收”中断之间的时间距离超过此限制,则字符属于不同的帧。一旦检测到中断,您就可以开始收集新消息。

  4. 一点一点自己动手。如果从属设备和主设备之间没有良好的同步,则必须使用此方法确定主设备时钟。实现不是很简单,但一个例子是: http: //www.atmel.com/images/doc1637.pdf(我并不认为它是万无一失的,它相当简单。)

我会选择#3。为传入数据创建一个中断,每当数据到来时,您将当前时间戳(您需要一个计数器)与前一个中断的时间戳进行比较。如果字符间时间太长,则开始一条新消息,否则附加到旧消息。然后,您可能需要对消息进行双重缓冲(您正在收集的消息,正在分析的消息)以避免非常长的中断例程。

实际实现取决于代码的其他结构。这应该不会花费太多时间。

如果你不能确保你的时钟与最近的时钟足够同步(+- 4%),那么你将不得不查看#4,这可能更有指导意义,但也很乏味。

于 2014-06-25T07:31:29.807 回答
0

你的基本问题是这个(如我所见):

如何测试我的代码的性能以查看是否可能发生缓冲区溢出?

在算法开始时将引脚设置为高电平,在结束时将其设置为低电平。在示波器上查看它(我假设您拥有其中之一 - 没有它嵌入式开发将非常困难。)您将能够测量算法所需的最大时间,并了解可变性。

于 2014-06-25T10:30:39.597 回答