4

我有一个实时嵌入式应用程序,主要周期以 10KHz 运行。它在配置为从闪存启动的 TI TMS320C 上运行。我最近在一个源文件中添加了一个初始化数组,突然之间时间被搞砸了(以一种太复杂的方式无法很好地解释——本质上串行端口写入不再按时完成。)

这件事让我感到困惑:

  • 什至没有访问新数据,只是声明了一个初始化数组。
  • 它取决于大小 - 仅当数组大于 40 个字时才会出现问题。
  • 我知道我没有溢出链接图中的任何数据段。
  • 没有数据缓存,因此不是由于破坏了缓存一致性。

关于如何简单地增加闪存中 .cinit 段的大小会影响代码的时序的任何想法?

附加信息:
我认为代码可能已经移动,但它与数据分离良好。我通过内存映射验证了所有代码段在错误之前和之后都具有相同的地址。我还验证了没有一个段是完整的 - 地图中唯一更改的地址是 .cinit 部分中的少数。该部分包含用于初始化 ram 中的变量的数据值(如我的数组)。在 main() 被调用后,它不应该被访问。

4

7 回答 7

1

我的怀疑将指向您的数据/代码与底层媒体/内存之间的对齐方式发生变化。添加到您的数据中会更改堆中的内存位置(取决于内存模型),并且可能会将您的代码放在闪存设备上的“页面”边界上,从而导致以前不存在的延迟。

于 2008-09-24T21:05:45.580 回答
1

也许新的静态分配数组将现有数据推送到较慢的内存区域,导致对该数据的访问变慢?

于 2008-09-24T22:31:17.623 回答
1

如果数组是其地址空间块中的最后一个东西,问题是否会再次出现?如果没有,请查看您的地图,尝试移动数组声明,以便将放置在它之后的东西一个一个地打乱到它之前。通过这种方式,您可以查明相关对象并开始找出移动它会导致延迟的原因。

于 2008-09-24T22:42:35.597 回答
1

我会冒着风险声称您在这里没有性能问题,而是某种内存损坏,表现为性能问题。将数组添加到可执行文件中以更改内存图片。所以我的猜测是你的内存损坏大部分是无害的(即覆盖未使用的内存部分)并将你的内存移动超过 40 个字节会导致内​​存损坏造成更大的问题。哪一个是真正的问题

于 2008-09-25T09:17:09.037 回答
1

经过一天多的时间盯着痕迹和生成的程序集,我想我明白了。根本原因问题原来是一个设计问题,只有在启动串行端口写入的 ISR 与更高优先级的 ISR 冲突时才会导致故障。时间恰好计算出来,只需要在一个循环中添加一些额外的指令就可以导致两个中断发生冲突。

所以问题就变成了:在闪存中存储而不是访问额外的数据如何导致额外的指令被执行?

答案似乎与 Frosty 和 Frederico 的建议有关,但并不完全相同。新数组确实移动了一些现有变量,但不会跨越页面边界或移动到较慢的区域(在此板上,所有区域的访问时间应该相同)。但是它确实改变了一些经常访问的结构的偏移量,这导致优化器发出稍微不同的指令序列来访问它们。一种数据对齐可能会导致一个周期的流水线停顿,而另一种则不会。这几条指令改变了足够的时间,足以暴露潜在的问题。

于 2008-09-26T16:22:28.637 回答
0

初始化是否会覆盖另一段相邻的代码?是否有任何使用数组的结构或变量,现在更大并且可能导致堆栈溢出?

于 2008-09-24T21:10:40.623 回答
0

也可能是银行或页面冲突。也许您有两个经常被调用的例程(中断处理程序等),它们位于同一页面,现在被分成两页。

于 2008-09-24T21:19:08.060 回答