This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR5994:禁用/启用单个计时器中断时出现奇怪/未记录的行为

Guru**** 2382390 points
Other Parts Discussed in Thread: MSP-EXP430FR5994, MSP430FR5994, MSP430F6659, MSP430FR2633, MSP430FR4133, MSP430FR5969, MSP430FR6989
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/895839/msp430fr5994-strange-undocumented-behavior-when-disabling-enabling-individual-timer-interrupts

器件型号:MSP430FR5994
主题中讨论的其他器件:MSP-EXP430FR5994MSP430F6659MSP430FR2633MSP430FR4133MSP430FR5969MSP430FR6989

大家好、

硬件: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、解决这个特定的问题显然很容易。 但它是正确的吗?
-其它外设是否有相同的问题? 他们的解决方案是什么?
-除勘误表文档和论坛之外,是否还有其它地方描述此类问题? 在哪里?

我参与了一个非常严肃的项目、我无法承受最终产品中任何隐藏的"意外"。
请提供建议。

感谢您的支持、
Filipe2e.ti.com/.../CrashTest.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好 Filip

    我这边的一些评论:  

    1.我认为你的使用方式在这里有一个错误。 如果计数器值溢出、则延时时间不准确、计数器值将溢出。  

    2.当您想停止计时器以读取计数器值时、请通过"TA0CTL = tassel_SMCLK | MC_STOP;"停止计时器将优于清除 CCIE。

    3.如果您可以制作更多的代码示例以重现问题,将会更好。  

    我想我们可以重点介绍您想要实现的函数是什么、为什么要在计时器 ISR 中添加计数器值?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Gary、

    感谢您的回答。
    但是,这里的问题不是针对此测试程序的逻辑,而是针对序列后的随机代码执行:

    1.禁用外围设备(任何?) 中断。
    2.不放置 NOP

    在官方文件中将其解释为问题的地方。

    此致、
    Filip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我可以在 MSP-EXP430FR5994上使用您的示例程序重复崩溃、尽管使用的是 X430FR5994修订版 A 器件(即原型器件)。

    由于程序似乎在超出范围的 PC 上失败、因此我在程序使用的范围的末尾为 PC 设置了一个断点。 即 0x10576的"程序地址后中断"。

    当断点达到以下条件时、多次尝试会发生:

    • PC 为0x01067A、不在程序末尾
    • 全局 g_nTVal 变量为 1255
    • TA2CCTL0 CCIE 位为零

    我还没有确定原因、也看不到任何能够解释问题的勘误表。 MSP430FR5994具有 EEM 的 S 版本、该版本不支持跟踪、目前为止尚未能够捕获最后执行的有效指令。

    虽然 第1.3.4.1节《MSP430FR58xx、MSP430FR59xx 和 MSP430FR6xx 系列用户指南》中提到需要在 EINT 指令之前插入一条 NOP 指令、在 DINT 指令之后插入一条 NOP 指令、 在启用/禁用外设中断的同时全局中断保持启用时( 这正是 TickGet16函数的功能)、不能清除是否也适用。

    也许 TI 的某个人可以对此发表评论。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我看到了类似的东西(我使用 MPU 来获取它)、当然我的地址不同。 我看到的证据是:

    1) T2刚刚显示了一个 IRQ (CCIFG=1、TA2R=0);由于 CCIE=0、ISR 还未执行。

    2) 2) TickGet16已在0x10470 (BIC)执行其第一条指令、可能在0x10476 (MOV 至 R12)执行其第二条指令、但在0x1047a (MOV 至 R15)执行其第三条指令。

    3) 3)控制然后直接跳转到0x10730 -这是故障。 "旧 PC"和"新 PC"之间的差异似乎是一个常数(~0x2C0)、因为如果我在其他地方添加指令、二者的移动量相同。 我在附近的任何位置都看不到该地址或该偏移量(包括最近的堆栈历史记录)。

    我发现有趣的一点是、在一些情况下、ISR 正在执行、但 CCIE=0。 这告诉我 IRQ 在"BIC CCIE"指令中间的某个时间排队(需要8个 MCLK)、并且在指令完成时、即使 CCIE=0、也允许运行。

    然而、在故障情况下、IRQ 明显出现在 BIC 指令的中间、但却不允许运行。我想知道 Verilog 是否有一个类似"如果 IRQ 出现在指令时钟4之前、请执行它、 但在时钟4之后不执行它"或其他操作。

    但是的、手指似乎指向关闭 CCIE"同步"(模糊术语)、此时计时器显示 CCIFG IRQ。 元周期需要一点时间才能准确匹配。

    [编辑:我忘了提及:SMCLK=MCLK=2MHz (DCO =16MHz、/8)和 NWAITS=1。 代码路径可能足够大、无法放入 FRAM 缓存中。]

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在 DINT 之后放置一个 NOP 的规定原因是为了确保它不受中断的影响。 如果该指令不需要保护、则无需 NOP。 在 EINT 之前使用 NOP 的原因是为了避免引起的问题、也就是在它之前可能发生的某些其他影响指令的中断。

    此处不适用。 本手册建议在更改定时器的操作之前停止定时器。 中断使能的显著例外情况。 (请注意使用奇异而不是复数)不清楚这是仅 TAIE 还是包含 CCIE。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    正如 Filip 提到的,全局变量的位置----在 BIC 之后的指令中引用----很重要。 降低其地址似乎会移动"虚拟分支目标"、使全局地址的变化增加2倍。

    在大约0x2008 (从0x214c 开始)时、目标进入"正常"代码(0x10490)、变得难以捕捉。 在行之后、如果全局地址为0x1FF8、则偏移量将为0、从而使效果消失(至少进入隐藏状态)。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Chester Gillon">我可以在 MSP-EXP430FR5994上使用示例程序重复崩溃、但使用 X430FR5994修订版 A 器件(即原型器件)。我创建了一个新示例、可以在多个不同的器件上运行、使用一个源文件和每个测试器件的不同 CCS 编译配置。  

    它是原始版本的简化版本、在该版本中进行了以下更改:

    1. 复位时、将 CPU 时钟保持为器件默认值、标称值为1MHz。
    2. 仅使用应切换的单个输出引脚、以指示程序仍在运行。
    3. 保持看门狗处于禁用状态、如果在崩溃之后有复位源、则添加一个陷阱、用于在启动和停止时读取 SYSRSTIV。
    4. 从使用 TA2更改为 TA0、以便能够在较小的器件上运行。
    5. 使用填充字段允许调整由 TIMER0_A0_ISR 递增的 nTVal 变量地址的结构、而不是原始示例中使用的#pragma 位置。 这仍然允许链接器在尝试将示例移植到其他器件时检查 RAM 分配。

    在不同器件上进行测试的结果为:

    器件 结果
    MSP430F6659修订版 A 不会崩溃
    MSP430FR2633 不会崩溃
    MSP430FR4133修订版 B 不会崩溃
    MSP430FR5969 崩溃。 PC 更改为无效地址0x01034e、然后器件通过 SYSRSTIV "PMMPW PMM 密码违规(PUC)"复位
    X430FR5944修订版 A 崩溃。 PC 更改为无效地址0x01034e、然后器件通过 SYSRSTIV "PMMPW PMM 密码违规(PUC)"复位
    MSP430FR6989修订版 C 崩溃。 PC 更改为无效地址0x01034e、然后器件通过 SYSRSTIV "PMMPW PMM 密码违规(PUC)"复位

    即、在多种类型的设备上重复了崩溃。 由于已显示崩溃对使用的地址很敏感、因此不确定这是不是所有设备测试中都发生崩溃的原因(因为使用的设备具有不同的内存容量)。

    该项目随附 在 e2e.ti.com/.../MSP430_5F00_crash_5F00_on_5F00_enable_5F00_disable_5F00_timer_5F00_int.zip 上

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Bruce McKenney47378"]降低其地址似乎会将"虚拟分支目标"移动2倍于全局地址的更改。  我可以使用上一帖子中附加的 MSP430_crash_on_enable_disable_timer_int.zip 示例重复此效果。 在 MSP430FR6989上运行时、通过调整前面的填充量来更改 globals.nTVal 字段地址的一些测试:

    globals.nTVal 地址 虚拟分支目标
    0x0020F6 0x010346
    0x0020F8 0x01034A
    0x0020FA 0x01034E
    0x0020FC 0x010352
    0x0020FE 0x010356

    我还没有确定移动全局地址会更改虚拟分支目标的原因、也没有确定导致虚拟分支目标的实际原因。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢您的写、尽管我今晚可能不会再去了。

    我使用 Rev C FR5994在 Launchpad 上尝试了原始代码(Filip 也是如此)、但失败的方式也是一样的。

    看起来形成的画面是、定时器正在呈现 IRQ、但在某些关键时刻、CPU 期望看到一个东西(IRQ 编号?) 而是从下一条(流水线型)指令中看到源地址。 因此、它将占用低8位、乘以2并添加到 PC 中。

    为什么是现在? 我假设它必须与向(相同)计时器发出 RMW 请求的相同指令相关。 这在大部分时间都成功了、所以我怀疑在8个 MCLK 中 IRQ 实际出现时它很重要。

    但这都是猜测。 没有人给我钥匙去 Verilog。

    如果所发生的情况甚至与此类似、则表明适当的解决方法是 Filip 提到的 NOP (在 BIC 之后)、因为其中没有源地址。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、

    感谢您的努力和发帖、我仍在等待 TI 的官方回复。

    再强调一点、如果我们在禁用外设 INT 之后放置一个 NOP、并且编译器优化处于"打开"状态、那么我们如何确保 NOP 将停留在编译代码中而不是由编译器优化器进行优化?
    由于"_disable_interrupt"是编译器内在函数、包含 NOP、因此编译器"知道"不会优化它的 NOP。
    但在我们的情况下、我希望现在和之后都能删除 NOP。
    未以任何方式进行尝试/检查、因为修复应该再次是 TI 的一些官方声明。
    我们不能承担猜测和非官方尝试错误测试的费用(最多只能进行有限的测试)。

    因此、正如我看到的、我们还应该禁用编译器优化以使此修复程序可靠运行。
    如果我错了、请纠正我的问题。

    谢谢、
    Filip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Filip Dimitrov]但在我们的案例中、我希望现在和之后都删除 NOP。我尝试查看最新 的 MSP430优化 C/C++编译器 v20.2.0.LTS 用户指南 、但找不到有关_ _no_operation 内在函数的编译器优化器处理的明确声明。

    在使用 TI MSP430编译 器 v20.2-1进行的测试中、如果最大优化级别为4 "整个程序优化"、则以下 _no_operation 仍会导致程序中出现 NOP:

    uint16_t TickGet16()
    {
    TA0CCTL0 &=~CCIE;
    _NO_OPERATION ();
    
    uint16_t nRet =(uint16_t) globals.nTVal;
    
    TA0CCTL0 |= CCIE;
    
    返回 nRet;
    } 

    如下在调试器中所示:

    61. TA0CCTL0 &=~CCIE;
    $C$L5:
    010082:F0B2 FFEF 0342 和.W #0xffffff&Timer0_A3_TA0CCTL0
    62 _NO_OPERATION ();
    010088:4303 NOP
    64 uint16_t nRet =(uint16_t) globals.nTVal;
    01008a:421F 20fA MOV.W &0x20fa、R15
    01008e:421D 20FC MOV.W &0x20fc、R13
    010092:421D 20FE MOV.W &0x20fe、R13
    010096:421D 2100 MOV.W &0x2100、R13
    66 TA0CCTL0 |= CCIE;
    01009a:D0B2 0010 0342 BIS.W #0x0010、&Timer0_A3_TA0CCTL0
    123 if (nTmrNow - globals.nBlinkTimer > 250)
    0100a0:0FCD MOVA R15、R13
    0100a2:8E0D 低于 W R14、R13
    0100a4:903D 00FB CMP.W #0x00fb、R13
    0100a8:2BEC JLO (0x0082)
    125 LED_operations_port ^= LED_operations_mask;
    0100aa:E3D2 0202 XOR.B #1、Port_A_PAOUT
    126 globals.nBlinkTimer = nTmrNow;
    0100ae:0FCE MOVA R15、R14
    0100b0:4E82 1C00 MOV.W R14、全局
    0100b4:3FE6 JMP (0x0082) 

    在上述示例中、在源代码中添加_no_operation 足以停止崩溃。

    我将通知 TI 编译器专家之一、看看是否可以获得有关编译器优化器删除 源代码中指定的__no_operation 内在函数的可能性的官方声明。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我通常使用'asm volatile (" nop ");'、因为我忘记了如何拼写__no_operation()。 我认为、由于它在这里接受"易失性"、因此它对它进行了适当处理、但现在我看 SLAU132U 中没有提到这一点。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我同意诊断不会解决任何问题、但与切斯特的专用测试案例一起、是引起 TI 注意的一种方法。

    当我听到以前未知的硅错误时、我与 TI 有一种怀疑态度、因为我看到了如此多的此类报告、结果证明这些报告只是错误的编码/设计。 但我看到过一些真正的人经过(可能是12年中的3个人)、这个看起来很可疑。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    gcc 中记录了这种易失性行为。 (6.47.2.1)但是、它指出所有 asm 语句在内部都是易失的、因此它不执行任何操作。 它对扩展 ASM 有影响。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我稍微挖了一点、它看起来也是 IAR (_no_operation 的起源)支持"asm volatile"。 在一个奇特的转变中、"asm"版本比_no_operation 更易于移植。  

    同时、我希望 TI 的某个人能很快出现。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Bruce McKenney47378]0x2008 (从0x214c 开始)左右、目标进入"正常"代码(0x10490)、变得难以捕捉。默认情况是 FRAM 或闪存的未使用部分将处于擦除状态、32位以上的解码为以下指令:

    FFFF FFFF 和.B @R15+、0xFFFF (R15) 

     上述指令的间接自动增量寻址模式意味着在"虚拟分支目标"之后是擦除的 FRAM 或闪存、当 PC 通过擦除的 FRAM 或闪存 R15运行时、地址会递增并写入。 如果尝试写入受密码保护的外设、则会触发复位。 这解释了为什么由于 PMMPW PMM 密码违反(PUC)、测试可以被复位"。

    更改链接器命令文件以指定0x3fff (与从空存储器读取的值相同)的填充值"JMP $"意味着如果 "虚拟分支目标"未使用 FRAM 或闪存、PC 停止递增、从而阻止故障导致复位。 例如、在存储器区域中:

    FRAM :origin = 0x4000、length = 0xBF80、fill = 0x3FFF
    FRAM2 :origin = 0x10000、length = 0x34000、fill = 0x3FFF 

    但是、我仍然没有确定发生"幻象分支"的确切点。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、我使用@R15+来触发 MPU、因为 R15 (大部分时间)包含* WDTCTL=0x5Axx。 在0x2008时,它跳到了"abort()";这是偶然发现的。 我很确定、如果它分支到库中的某个随机位置、我将无法可靠地捕获它。

    我在这里没有材料,但我记得 R15中有(* WDTCTL)或时间戳的一个词。 在失败时、R15包含了前者、因此我得出结论、第一个 MOV 到 R15没有发生。 前面的 MOV 到 R12 不明确、因为 R12几乎始终包含时间戳的第一个字。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Bruce McKenney47378]R15失败时包含前者、因此我得出结论认为、第一个 MOV 到 R15没有发生。 前面的 MOV 到 R12 不明确、因为 R12几乎始终包含时间戳的第一个字。[/quot]我调整了我的示例、以便留下更多有关故障点的"线索":

    • 使链接器命令文件使用0x3fff (JMP $)填充 FRAM、以便在虚拟分支到未使用空间时停止。
    • 将 64位计数 器初始化为值0xFEEDABBADEADBEEF、以帮助确定 MOV 到 R15发生的距离(如果有)。
    • 将一些汇编器语句添加到 TickGet16的开头、以设置 R12和 R15

     用于 TickGet16函数的汇编器为:

    61. ASM volatile (" MOV.W &TA0CCTL0、R12");
    TickGet16():
    01012e:421C 0342 MOV.W &TA0_TA0CCTL0、R12
    62 ASM volatile (" MOV.W &TA0CCTL0、R15");
    010132:421F 0342 MOV.W &TA0_TA0CCTL0、R15
    64 TA0CCTL0 &=~CCIE;
    010136:F0B2 FFEF 0342 和.W #0xffffff&TA0_TA0CCTL0
    66 uint16_t nRet =(uint16_t) globals.nTVal;
    01013c:421C 20fA MOV.W &0x20fa、R12
    010140:421F 20FC MOV.W &0x20fc、R15
    010144:421F 20FE MOV.W &0x20fe、R15
    010148:421F 2100 MOV.W &0x2100、R15
    68 TA0CCTL0 |= CCIE;
    01014c:D0B2 0010 0342 BIS.W #0x0010、&TA0_TA0CCTL0
    71}
    010152:0110 返回 

    以下断点用于检测"虚拟分支"故障何时跳转到用0x3fff 填充的未使用空间:

    在 MSP430FR5994故障点、全局变量为:

    globals.nTValunsigned long long0xFEEDABBADEADC2DF (十六进制)0x0020FA
    globals.nBlinkTimerunsigned int0xC2DB (十六进制)0x001C00

    内核寄存器为:

    PC0x01033ACore
    SP0x002BF4Core
    SR0x0009Core
    R30x000000Core
    R40x00FFFFCore
    R50x00FFFFCore
    R60x00FFFFCore
    R70x00A55ACore
    R80x00FFFFCore
    R90x000112Core
    R100x001AF8Core
    R110x00FFFFCore
    R120x00C2DFCore
    R130x000000
    Core R10 0x000000
    

    TA0CCTL0为0x0001 (CCIE = 0、CCIFG = 1)。

    在 TickGet16的指令中添加采样的寄存器值注释:

    010132:421F 0342 MOV.W &TA0_TA0CCTL0、R15 /* R15具有0x0010、这是 CCIE = 1且 CCIFG = 0 */
    64时的 TA0CCTL0值 TA0CCTL0 &=~CCIE;
    010136:F0B2 FFEF 0342 AND。W #0xffef、&TA0_TA0CCTL0 /* TA0CCTL0的 CCIE = 0,因此这已被执行*/
    66 uint16_t nRet =(uint16_t) globals.nTVal;
    01013c:421C 20fA MOV.W &0x20fa、R12 /* R12具有0xC2DF、它与 globals.nTVal 中的最低有效字匹配、因此已执行*/
    010140:421F 20FC MOV.W &0x20fc、R15 /* R15在该地址没有值(0xDEAD)、因此未执行*/ 

    假定 R15在 CCIE = 1且 CCIFG = 0的情况下、在清零 CCIE 的指令之前以及在 TA0CCTL0崩溃后 、 CCIE = 0立即采样 A0CCTL0、 CCIFG = 1这备份了理论、当 CCIE 在定时器中断激活前后被清除时、崩溃发生。

    更新后的示例随附 在 e2e.ti.com/.../3175.MSP430_5F00_crash_5F00_on_5F00_enable_5F00_disable_5F00_timer_5F00_int.zip 上

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Filip Dimitrov"]如果我们在禁用外设 INT 后放置了一个 NOP,并且编译器优化为"on",那么我们如何确保 NOP 将保留在编译的代码中而不是由编译器优化器进行优化?

    假设您编写以下内在函数序列...

    _disable_interrupts ();
    __no_operation (); 

    TI MSP430编译器将始终按照该顺序发出相应的指令。  无论优化级别如何、都是如此。

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、George、

    感谢您的回答。

    我们很想禁用特定的外设中断,并在下一行 ASM 上设置 NOP...如下所示:

    asm ("  BIC.W #xxx、&yyy");
    asm ("  NOP");

    寄存器&=~BITx;
    asm ("  NOP");

    asm ("  BIC.W #xxx、&yyy");
    __no_operation();

    或它们的任何组合。

    哪个变体更"稳健"...即不可能通过编译器优化器重新排序或优化掉?

    此致、
    Filip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    始终使用 asm 语句作为最后的手段。

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、

    仍在等待 TI 对我的第一篇帖子中的问题作出正式澄清(希望并非  所有来自 TI 的人都被 Corona 病毒感染了:):

    这个问题的官方解决办法是什么?
    -其它外设(定时器除外)是否会受到此问题的影响? 他们的解决方案是什么?
    - 哪些 CPU/修订版受到影响?
    -除勘误表文档和论坛之外,是否还有其它地方描述此类问题? 在哪里?

    此致、
    Filip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好 Filip

    您是否尝试禁用 CCS 优化? 还是使用 IAR?

    此致

    Gary

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、 Gary、

    所有优化都被禁用、正如我所注意到的、我已经检查了生成的汇编代码、这似乎是可以的。
    因此、这不是编译器问题。

    此致、
    Filip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好 Filip

    我已经根据您的情况创建了一个代码示例。 但是 it.e2e.ti.com/.../msp430fr599x_5F00_ta0_5F00_01.c 没有问题 、您能否帮助进行一些更改以重现您所面临的问题?

    此致

    Gary

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [报价用户="Gary GAO]您能否帮助进行一些更改以重现您所面临的问题?[/报价]我之前根据 Filip 提供的示例创建了一个示例、但该示例也失败了。 请参阅 https://e2e.ti.com/support/microcontrollers/msp430/f/166/p/895839/3313155#3313155随附的项目。 您是否能够使用引用的帖子中的代码重复该故障?

    此外、如该参考帖子中所述、我在多个不同的 MSP430FR 器件上遇到了故障。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好

    我无法导入代码、因为我没有编译器 MSP430v20.2。 您使用的 CCS 版本是什么?

    我将 CCS 9.3与编译器版本 TI v18.12.4.LTS 配合使用。 我无法在线找到 MSP430v20.2。

    您能否对我的代码进行一些非常简单的更改来重现此问题?

    此致

    Gary

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="Gary GAO]您使用的 CCS 版本是什么?该工程是使用安装 了 MSP430编译器 v20.2的 CCS 10.0创建的。

    我已更新示例项目以使用我在 CCS 9.3中使用的编译器 TI v18.12.4.LTS

    e2e.ti.com/.../8105.MSP430_5F00_crash_5F00_on_5F00_enable_5F00_disable_5F00_timer_5F00_int.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我只做了一些更改、使代码更简单、但没有问题发生。

    e2e.ti.com/.../MSP430_5F00_crash_5F00_on_5F00_enable_5F00_disable_5F00_timer_5F00_int.c

    进行此更改的原因是、我认为我们只使用全局变量会使这更简单。

     

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Gary Gao ]进行此更改的原因是、我认为我们只使用全局变量会使这变得更简单。我同意、进行此简化会使故障"消失"。

    如 Filip 所述、故障似乎对变量/代码在内存中的位置很敏感。

    例如 、在 https://e2e.ti.com/support/microcontrollers/msp430/f/166/p/895839/3340896#3340896所附的示例中 、使用了以下全局结构:

    结构
    {
    uint16_t nBlinkTimer;
    uint8_t padding[1272];
    volatile uint64_t nTVal;
    }全局变量; 

    如果填充字段被注释掉、这会改变 RAM 中 nTVal 字段的地址、那么故障不再发生。

    我认为 Filip 所寻求的是对故障对 变量/代码在内存中的位置敏感的解释、以便能够确保以确定的方式避免故障。

    故障案例是否可能暴露了一些先前未知的器件勘误表?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我用 CCS v8.3 (编译器 v18.1.5.LTS)、Filip 的原始代码或 Chester 的检测代码来演示这种症状,甚至还能与演示。 (由于 CCS 错误、我无法导入 Chester 的项目、但源代码的副本/粘贴已足够。) 这是在 Launchpad 上使用修订版 C "M" SP430FR5994。

    为了回传 Chester 的观点:这是编写给用户指南规范的普通代码(几乎可以告诉我)、该规范使用了宽容的功能[参考 UG (SLAU367O)第25.2.1节"注意:"]并且失败了。 一个令人困惑的后果是症状是可怕的,尽管是灾难性的。 任何人都可能会遇到这种情况。

    我的重建是、它需要在一个指令内发生两件事情:(a) TAx 触发一个已启用的 EQU0和(b) CPU 发出一个 RMW 操作来进行 TAx 以禁用该中断。 发生这种情况时、有一件事(IRQ#?) 在总线上是预期的、但有所不同(源操作数与下一条指令是多少?) 到达时、CPU 会分支到任何地方。 可能重要的是(1)这些事件发生的顺序以及(2)发生这些事件的[也许]特定子指令时钟。

    比赛? 所以看起来。 不可能? 当然。 但我已经诊断出足够模糊的比赛,如果你遇到足够多的时间,你最终会输。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好

    我添加了您之前提到的结构、但仍然没有出现任何问题。

    结构

    uint16_t nBlinkTimer;
    uint8_t padding[1272];
    volatile uint16_t nTVal;
    }全局变量;

    我将"volatile uint64_t nTVal;"更改为"volatile uint16_t nTVal;"的原因是我们不需要在    TickGet16 ()中将 uint64_t 转换为 uint16_t。

    这是我的测试代码 e2e.ti.com/.../0513.MSP430_5F00_crash_5F00_on_5F00_enable_5F00_disable_5F00_timer_5F00_int.c

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好 Bruce

    感谢你的建议。 我对您的观点有一些疑问、您能帮我澄清一下吗?谢谢

    我 已阅读"[参考 UG (SLAU367O)第25.2.1节"注意:"]、并且禁用和启用 CCIE 的风险很小。 "令人困惑的效果是症状是可怕的、尽管是灾难性的"的含义是什么?

    2. “CPU 发出 RMW”的含义是什么。 如果您能提供更详细的描述、我不能完全理解您在这里的观点。 谢谢

    此致

    Gary

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    1)"TI 建议在修改计时器的运行(中断使能、中断标志和 TACLR 除外)之前停止计时器、以避免错误的运行条件。" (重点矿)。 此异常似乎涵盖了 CCIE。 请记住、在许多情况下、在定时器运行时修改 CCIFG 几乎是必需的、因此 CCIE 推理似乎是有道理的。

    症状是来自代码的随机(-ish)分支、其中不包含分支。 这里的某个位置有一个 IRQ、但是分支目标不是相关向量的内容(也不是任何其他向量、也不是在栈中、也不是在任何寄存器中)。 Chester 的研究表明,分支目标的 PC 偏移取决于(*2?) 源地址(低字节?) 清除 CCIE 的 BIC 之后的指令中。

    该代码会大量地执行测试用例。 如果出现这样一种奇怪的症状、即每月一次、则可能会被记为电干扰或某种情况。 (如果您正在设计一个连续运行一年的系统、那么这种奇怪现象会引起您的注意。)

    2) 2)在相关指令(BIC)期间、CPU 执行读-修改-写操作以更改计时器外设中的 TA0CCTL0。 这似乎是问题的重要组成部分。 正如我在前面的线程中提到的、我看到执行到达 ISR、但 CCIE=0的情况很多。 这表明 CCIE 清零和 IRQ 都发生在 BIC 指令期间。 因此,有时这是可行的,有时是不可行的,因此,关于排序和/或特定子周期的建议很重要。 (BIC 至少需要6个时钟。)

    没有人给我讲韦里罗格的钥匙,所以我只能报告从外面可以看到的东西。 具有精确到周期的模拟器的人可能会说得更多。 Chester 的测试用例很少在我的 Launchpad 上运行超过2秒、因此跟踪不会花费一生的时间。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    另外、作为一个" amicus 简述"、我将指出这条线程。 它与 FR57系列有关、我认为至少是 FR59的表弟:

    https://e2e.ti.com/support/microcontrollers/msp430/f/166/p/722730/2700430

    需要注意的是、计时器外设的操作不是 CPU 观察到的原子操作。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不清楚更改定时器操作时的异常适用于 CCIE。 该注释使用奇异时长、因此最多只能是写得不好的、最坏的情况下不适用于 CCIE。

    从25-15的角度来看、如果 CCIE 在中断生成后被清除、我认为运气不好、就有可能生成一个到中断逻辑的短脉冲。 中断系统如何处理脉冲输入? 当需要获取 ISR 地址时、它是否会启动一个中断服务周期、然后遇到问题?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    1)这是我提到 CCIFG 的一点、因为语言有点模糊。 禁止在定时器运行时修改 CCIFG 可能会使20年的先例无效(每个程序都包含 A1 ISR)、因此我假设奇异(字面量)旨在同时适用于 CCIFG 和 CCIE。

    2) 2)这基本上是我认为正在发生的情况。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Gary GAO"]或使用 IAR ?我使用与 CCS 相同的源文件为 MSP430FR5994创建了一个 IAR 项目。

    当使用 IAR 构建程序时,程序仍然失败,在这种情况下,失败会导致 PC 跳转到无效地址0x020010:

    用于 MSP430 Kickstart v7.20.1的 IAR 被用来构建附加的项目(.zip 文件包含 IAR 和 CCS 项目文件、它们都使用相同 的 MSP430_crash_on_enable_disable_timer_int.c)。

    e2e.ti.com/.../6888.MSP430_5F00_crash_5F00_on_5F00_enable_5F00_disable_5F00_timer_5F00_int.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢 Burce 和 Chester 在这里所做的出色工作和提供的建议。 当我有时间时、我将对它进行更多的测试。