主题中讨论的其他器件:MSP-EXP430FR5994、 MSP430F6659、 MSP430FR2633、 MSP430FR4133、 MSP430FR5969、 MSP430FR6989
大家好、
硬件:MSP430FR5994 LaunchPad 开发套件(MSP-EXP430FR5994)
CSS 编译器:CCS 版本:9.3.0.00012
CPU:78C85QW G4/MSP430FR5994/REV C
有关设置的更多详细信息、请参见随附的工程。
我有这个与我为 MSP430FR5994实现的简单节拍计数器相关的非常奇怪的编程。
设置非常简单、我将使用中断(在 CCR0上)启动计时器(TA2)。 在 ISR 内部、我只递增计数器(uint64)。
当我需要从主代码中获取计数器值时、我会禁用该特定计时器的中断并获取该值。
然后、我为它重新启用中断。
长故事简短:这会导致代码的通篇执行、挂起以及各种类似问题。
我对这一切都没有任何合理的解释。 已检查勘误表、系列数据表、数据表、论坛帖子等...我找不到任何合理的解释。
我唯一能找到的最接近的东西是 MSP430系列用户指南第1.3.4.1节"中断接受"、其中有一条关于启用/禁用全局中断标志的说明。
但这与全局 inerrupt 标志相关、该标志在使用编译器内在函数__disable_interrupt ()/__enable_interrupt ()时被称为固定(未显式测试/检查)。
在我添加了一些变量之后、突然开始重置器件的大型项目完成3天后、我设法将问题归结为简单的测试项目。
我已经检查了汇编代码(看起来很好)、链接器映射文件(段看起来不错、堆栈不会被我的值覆盖)以及我可以想到的任何其他内容。
我将其连接到这个线程中。 在 main.c 的开头、有更详细的设置/构建/使用的器件和修订版本等说明
整个测试用例位于 main.c 中、附带适当的注释。 其他文件只是初始化等的补充文件
我知道这个示例项目在读取正确的计数器值方面存在逻辑问题(由于 CPU 内的指令预取机制)、
但这不应导致任何观察到的效果。
因此、测试项目设置为在当前一切正常时使绿色 LED 闪烁、并在检测到错误复位时打开红色 LED。
LED 闪烁可能挂起、这也表示存在问题、还设置了长 WDT (~ 40秒)、因此器件最终将复位、红色 LED 将亮起。
根据具体情况、问题立即出现(无 LED 亮起)或在短时间(1 - 10秒)后出现。
此外、还存在启动延迟(4秒)、因此如果存在任何类型的复位、则肉眼可见。
开发板复位按钮将清除红色状态。
如果初始化失败、器件将永久挂起(无 WDT 复位)、因此也很容易检测到这一点。
测试和查看问题出现的时间非常容易、不需要调试器或连接任何可能影响测试的通信。
根据我的测试,影响此问题是否出现以及如何出现的相关“事项”是:
-内存中的计数器位置。
-计数器的大小(uint16/uint32/uint64)。
-各种 NOP (或其他)放置了计数器的计数函数。
-放置在 ISR 内部的各种 NOP (或其他)。
-删除可禁用/使能中断会使问题脱离(请检查 main.c 注释)
一般来说,我的问题不是问题本身,而是缺乏有关问题的信息。
我在代码的各个部分中使用其他"无锁"技术、如果存在此类未解释的问题(?) 我不能信任这个 CPU。
所以我的问题(最后):
-通过在禁用中断和读取主代码中的计数器值之间添加简单的 NOP、解决这个特定的问题显然很容易。 但它是正确的吗?
-其它外设是否有相同的问题? 他们的解决方案是什么?
-除勘误表文档和论坛之外,是否还有其它地方描述此类问题? 在哪里?
我参与了一个非常严肃的项目、我无法承受最终产品中任何隐藏的"意外"。
请提供建议。