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

这件事让我困惑的是:

  • 我是 甚至无法访问新数据, ,只是声明一个初始化的数组。
  • 它与大小相关 - 仅当数组> 40 个字时才会出现问题。
  • 我知道我没有溢出链接映射中的任何数据段。
  • 没有数据缓存,因此这不是由于破坏缓存一致性造成的。

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

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

有帮助吗?

解决方案 5

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

所以问题就变成了:在闪存中存储但不访问附加数据如何导致执行附加指令?

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

其他提示

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

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

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

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top