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.

[参考译文] MSP430F5359:如果.bss 为985字节或更多、则 CGT 生成的 MSP430X 图像胜出#39;t START

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1470227/msp430f5359-cgt-generated-msp430x-images-won-t-start-if-bss-is-985-bytes-or-more

器件型号:MSP430F5359

工具与软件:

(对于不完整的错误报告、我很抱歉;我会在发现时添加更多数据。)

我们使用最新的 CGT (MSP430 C/C++编译器 v21.6.0.LTS)和最新 Code Composer Studio (CCS 2002)附带的库创建一些 MSP430测试程序、我们遇到了问题。

我们编译 时使用了以下限定符:

Bin/cl430.exe --c11.       \
-- silicon_version=mspx     \
-- use_hw_mpy=F5         \
-- printf_support=nofloat   \
-- c_src_interlist        \
--include_path=./include   \
--include_path=../ccs2002/ccs/ccs_base/msp430/include/\
-- output_file=hello_cgt_1.elf \
hello.c             \
-- run_linker          \
-- search_path=./lib/      \
--output_file=hello_cgt_2.elf \
-- map_file=hello_cgt.map   \
lnk_msp430f5359.cmd

我们的发现是、如果我们的测试程序声明.bss 项总共985字节或更多、则程序永远无法启动。 它似乎干扰了_TI_zero_init ()中的某个位置,因为它试图在程序启动时将.bss 区域清零。 但是、如果.bss 为984个字节或更少、一切都顺利。 此外、如果我们在没有使用--silicon_version=mspx  限定符的情况下进行编译(因此它将成为16位程序而不是20位程序)、一切都顺利。

我还不能告诉您(尚未)传递给 __TI_zero_init ()的参数、但我可以告诉您、如果我将.txt 文件修改为 NOP 而不使用对__TI_zero_init ()的调用、程序将正常启动(当然、.bss 尚未初始化除外)。 在读取.txt 文件时、__TI_cinit_table (及其亲属)似乎包含了有效数据:它指向的地址是 RAM 中正确的位置、它调用__TI_zero_init ()、并传递了正确的初始化大小。

是否有人识别此症状?

如果我的 hello.c 版本有用、但我的程序没有任何特别之处、只能定义和访问将放置在.bss 中的一些全局数组、我可以发布该版本。

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

    在尝试收集更多调试数据的过程中,我将硬件初始化代码移到了刚写的_system_pre_init ()例程中(并使该例程返回1表示成功)。

    这解决了问题! 我现在可以创建大型.bss 段、程序仍能正常启动!

    这很奇怪!

    在图像中、事情发生了变化(毫不奇怪)。 在 __TI_cinit_table (及其亲属)中、一切都相同、只是 __TI_zero_init ()的地址已更改为匹配、其中__TI_zero_init ()实际上落在映像中。

    但一切都正常!

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

    我想问题实际上是看门狗定时器。

    我重新排列的最大区别是_system_pre_init ()现在将 WDT 设置为 HOLD 模式,而我的旧代码导致 CGT 环境调用_TI_auto_init_nobinit_nopint () DOES NOT 不会影响 WDT。 在那种情况下、如果 WDT 超时、程序将被重置。 我想、初始化985字节的.bss 只需足够长的时间、让 WDT 超时。

    我将进行实验以证明这是关键差异。

    稍后…

    是的、这就是问题所在!

    我想知道为什么选择使用环境:

    _TI_auto_init_nobinit_nopint ()

    而不是:

    _TI_auto_init_nobinit_nopint_hold_wdt ()

    但这可能是我未使用的某个编译器/连接器限定符。 我将返回到编译器手册并阅读更多内容。

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

    这听起来像一个老头疼的问题、如果.data/.bss "太大"、看门狗触发器会在 C 初始化可以完成之前。 通常的修复方法是在  某个位置插入类似"void _system_pre_init (void){WDTCTL = WDTPW | WDTHOLD;return (1);}"之类的内容。

    我这里没有 CCS20、但 CCS12中有一个选项"Build Settings->Build->Linker->Basic->Hold watchdog timer"、该选项可以执行此操作。 [我个人更喜欢代码更改、因为这是那些容易忘记的巧妙选项之一。]

    [编辑:看起来你已经找到了这个。]

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

    在链接器限定器上关闭循环:

    将 --cinit_hold_wdt=on 指定为链接器限定符会导致在 c 初始化期间自动保留 WDT。 之后、WDT 会恢复到运行 C 初始化之前的状态。 以下是编译器手册中的相关文本:

    因此、用户的程序仍然必须在此过程中的某个位置处理 WDT、要么将其设置为 HOLD、要么将其实际用作需要偶尔"设置"的看门狗。

    在这一点上,我的问题已完全解决,但希望这些帖子将在未来帮助别人。

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

    布鲁斯:

    谢谢、是的 完全正确 我的问题。 我们的生产代码(由 IAR 编译)早已"知道"了这一点、并在很早的时候就开始处理 WDT、但直到今天早上、我才忘记了这个非常重要的细节。 我现在可能还记得了一两年。 ;-)

    感谢您的答复。

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

    您好、Atlant:
    很高兴看到布鲁斯的回应有所帮助。

    此致、

    Diego Abad