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.

[参考译文] CCS/MSP430FR5969:混合动力系统和#39;C#39;和汇编代码工程的持续复位问题。

Guru**** 2555630 points
Other Parts Discussed in Thread: OPT3001

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/822425/ccs-msp430fr5969-continuous-reset-issue-with-hybrid-c-and-assembly-code-project

器件型号:MSP430FR5969
主题中讨论的其他器件:OPT3001

工具/软件:Code Composer Studio

我有一个包含 C 语言和汇编代码的项目、该项目正在不断复位。 我已编辑了代码、以帮助简化故障条件和观察结果。 所需的代码片段调用的汇编函数不执行任何操作(仅一条 RETA 指令)、然后是使能中断、然后是正常的 C 函数调用。 C 函数调用永不结束、UC 复位。 顺便说一下、C 代码构建在一个"大型模型"下。 删除 Assy 函数或启用中断似乎会停止持续复位。 此问题与之前的帖子非常相似、只是我使用的是正确的 RETA 指令(不是 RET)

       (空) main (空)

       {

   initRxMsgHandler();             //不执行 Assy 函数
   __ENABLE_INTERRUPT ();         //全局启用中断
   init_FRAM();                          //普通 C 函数

   微控制器在这里复位!!!!!!!!!!!!!!!!!!!

   init_OPT3001();

initRxMsgHandler:
;   NOP
   返回

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

    何时禁用看门狗? 或者您是否也编辑了代码的关键位?

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

    自动初始化标志期间的保持安全装置打开。 我在我的'main'的第二行启用看门狗。 我现在也禁用了它、没有区别。 我认为看门狗设置为有点慢的值2到4秒。 下面复制了我更完整的"Main"代码(加上一些其他代码)。 我将添加 一个_delay_cycles 调用、以查看此故障是否存在"time"元素。

    void main (void)

       MSP430_Init();
       initWDT();
       init_gpio();
       init_rtc();
       init_Timer();
    //   initTimer0A0();
       init_i2C();
       init_spi();
       init_Comm1(0);
       initFRAMmgr();
       WDTreset();
       initRxMsgHandler();

       _enable_interrupt ();                   //全局启用中断

       init_FRAM();
       init_OPT3001();
       init_BME280();
       initADXL362();

       Comm1_putStr ((char*) BannerStr);
       InitMessageHandler();
       initDataManager();
       initMainStateMachine();

       while (真)
       {
          WDTreset();
          MainStateMachine();
          DataAbisitionStateMachine();
          CommandHandler();
          HighLevelADXL362_INT1();
       }


    void initWDT( void )

     // WDTCTL =(WDTPW | WDTSSEL_VLO | WDTCNTCL | WDTIS_4);  

      WDTCTL =(WDTPW | WDTSSEL__VLO | WDTCNTCL | WDTIS_4 | WDTHOLD);
       SFRIFG1 &=~WDTIFG;                   //清除 WDT 中断标志
    //   SFRIE1 |= WDTIE;                   //启用 WDT 中断


    initRxMsgHandler:
    ;   NOP
       返回


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

    在 Main 顶部添加_DELAY_CYCLES 似乎不会影响故障。 我在 Main 顶部附近注释了一行代码、代码在复位前能够执行大约低5行代码。 奇怪的行为。 想知道问题是否与链接器在何处查找代码函数有关。 编译后、微控制器无法判断源代码是 C 还是汇编代码。 调查仍在继续。

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

    我很好奇编译器或链接器如何知道您的汇编子例程是汇编语言。  它看起来是作为 C 函数调用的、但函数名称只是作为标签出现、而不是定义为 initWDT 函数:

    initRxMsgHandler:
    ;   NOP
       返回

    C 中是如何包含汇编代码的?  如果您将 initRxMsgHandler 更改为不执行任何操作的正确 C 函数、是否仍会获得重置?

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

    您可以通过两种方法使用汇编。 可通过 C 代码中的 asm ("")语句、也可作为单独编译的文件。

    我已经完成了后一项工作、但使用了 gcc。 通过将文件命名为什么。S gcc 前端知道先由预处理器运行它。 这样、您就可以包含器件头文件、其中包含所有这些方便的符号。

    您必须小心命名 C Visible 函数(需要前导"_")、当然也要遵循参数通过标准。

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

    首先、汇编函数从.asm 文件中剪切出、并复制到主代码段的底部以供参考(很抱歉、混淆)。 我知道混合 C 语言和汇编语言项目的命名约定。

    其次、我添加了一个看起来与 asm 函数完全相同的虚拟 C 函数(请参阅下面的)(通过使用 CCS 查看反汇编代码进行验证)。 应用程序工作正常(未复位)。 所以我对自己说“这怎么会?”

    空 DummyFunction (空)

       __no_operation();

    第三、我检查了映射文件、发现添加了这个微不足道的"无任何内容"汇编函数会导致链接器链接到.text 段顶部非常大的目标文件(大小为0x04ac)中、而该文件不在此处。 链接器必须已经看到了一组参考符号、并决定这样做(没问题、不会对此抱怨)。 这会通过一个 Kbyte 将所有剩余的可执行代码向下推。 再说一次、我认为这是有问题的代码位置。 可能存在内存对齐问题。 可能代码正被压入 FRAM2区域。 代码应该能够在任何地方运行(使用大型模型设置)、但 我将对此进行检查。 有什么想法?

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

    根据我的经验、如果您确定 WDT 关闭、那么复位通常意味着您尝试在实际上没有存储器的位置执行代码、或者在那里有存储器、但它都是 FFs。  在汇编器中、当我调用子例程时、我始终会遇到调用#subroutine。

    我想我会查看工作版本和非工作版本的.hex 文件、并查看在存储器中的位置有何不同。  但您的 CCS 反汇编可能会为您实现这一点。

    另一个问题: 在反汇编 C 版本的"不做任何事"函数时、它是否以 RETA 结尾?

    嗯、这是一个很神秘的问题。  最终、它将是一个简单的东西、但发现它是个问题。

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

    非常确定它不是 WDT、我使用的是 RETA 而不是 RET。 这可能是一个无效的存储器问题(当复位发生时、只有 VMAIFG 标志未被置位)。 我会一直看着。 感谢您的输入。 当我找到答案(如果不是太尴尬)时、我会发布答案。

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

    这是交易。

    故障:链接器在64K 以上的 FRAM2空间中查找 ISR 函数。 由于微控制器处理 ISR 地址的方式、无法执行该操作。

    原因:当我调用小型汇编函数时、链接器会拉入包含该函数的整个汇编文件(大约1kB 的值)。 我认为在 C 文件中、链接器仅拉入引用的函数、不链接非引用函数。 这将一个 ISR 函数(之前放置在地址64K 以下)压入64K 以上的 FRAM2空间。 微控制器不喜欢它。 调用时、计算出的返回地址无效、代码崩溃。 我不知道为什么我无法使用 VMAILG 检测到这一点。 对此进行进一步研究。 这是一个构建问题,而不是一个混合的 C./汇编问题。

    解决方案:在所有 ISR 中添加了#pragma 语句、以强制链接器将 ISR 放入低64K 地址空间(使用 linkercmd 文件)。

    重点:我知道 ISR 地址限制、我应该更好地了解。

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

    感谢您的更新。  很高兴您发现了问题。  

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

    真有意思。 GCC 将每个函数放在单独的段中(如果使用了-function-sections)、然后链接器会在给定--gc 段的情况下对未使用的段进行修整。

    我选中了一个中断例程并将其放入".text.rxISR"段中、但如果我使用"-mlarge"获取大型模型、则会将其放入".lowtext"段中。 因此、我可以安全地解决这个问题。 由于矢量表不能指向 ISR、因此 CCS 编译器应该知道的信息比将 ISR 放入高内存中的信息要好。 它至少应在链接时生成一条错误消息。

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

    尊敬的 James:

    感谢您更新状态。 如有进一步的问题或疑问、请随时返回。