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.

[参考译文] MSP430FR2676:使用大模型寻址时中断不起作用(MSPGCC 中的大型)

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1067402/msp430fr2676-interrupts-not-working-when-using-large-model-addressing-mlarge-in-mspgcc

部件号:MSP430FR2676
“线程”中讨论的其它部件: Captivate - FR2676Captivate - PGMR

您好,

对于一个项目,我们使用 MSP430FR2676微控制器。 该项目 使用 MSP430-GCC 编译器,由于与 TI 库的链接,因此需要启用大模型寻址。 通过在编译过程中提供-mlarge 编译器标志,可以启用大模型寻址。 这会将寻址从16位切换到20位,并使用 MSP430X 指令而不是默认的 MSP430指令集。

我们遇到了这个问题,因为在 Captivate 库中,调用__bis_SR_register()后,它在 Capt_blockOnFlag()方法上被阻止/卡住。 在缩小这个问题的规模时,我们发现这个问题也是在一个简单的例子中出现的,如下所述。

禁用-mlarge 标志时,它编译成功,代码能够成功运行。 该代码执行外围设备(如时钟,GPIO 等)的初始化,在初始化后,使用函数调用__bis_SR_register (LPM0_bits | GIE)将其置于低功耗模式。 系统现在正在等待按下端口5上的按钮,按下评估套件上的按钮时,系统将唤醒设备并成功执行中断服务例程中定义的操作。

当启用-mlarge 标志时,它成功编译并能运行代码。 但是,当 我们使用与前一个示例相同的代码时:初始化后使用函数调用__bis_SR_register (LPM0_bits | GIE)初始化并进入低功耗模式。 系统正在等待按下端口5上的按钮,按下该按钮后,它永远不会到达中断服务例程。 而是在调用调试器中的暂停按钮时,显示它卡在地址0x000004处。 当我们从函数调用中删除 LPM0_BITS 参数时 ,调用__bis_SR_register()函数后,它似乎立即被滞留在0x000004。

我们使用的是 MSP430-GCC 编译器的版本:“MSP430-EL-gcc (Mitto Systems Limited - MSP430-gcc 9.3.1.11) 9.3-1”。

为了使用这种大型编址模型,我们是否可能缺少一些编译标志?  或者我们还有什么不对的地方(可能看起来很奇怪,因为它似乎与小模型寻址有关)?

我们还查看了 MSP-GCC 用户指南中的“中断状态更改之间需要8.2 NOP 说明”,但这似乎没有任何效果。 我们还通过 应用标志-Wa,-mu 和-Wa,-mn 来查看“表4-3 MSP430 GCC 汇编器选项”,但这也没有任何影响。 请访问 https://www.ti.com/lit/ug/slau646f/slau646f.pdf

感谢你的帮助。

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

    您好,Randy,

    作为一个附带的注意事项,它鼓励您能够在 GCC 中构建 Captivate 库源。  让我们看看我们能否让您克服下一个障碍。

    这听起来非常像是您缺少中断源的处理程序。  我的意思是,只要在调用__bis_sr_register 中设置 GIE 位,就会设置并启用一些中断标志,但向量表尚未初始化,因此没有 ISR 辅助器可跳至。  在 CCS 中,通过使用库提供的单跳转至陷阱功能预先填充所有引导程序位置,可以自动处理此问题。  如果确实有处理程序,链接程序将把该处理程序的地址放入表中。 因此,请检查所有中断源,看看是否有一个中断源导致了此问题,并且您已为所使用的所有外围设备声明了 ISR 处理器。  一个值得检查的是 UCAx 模块,其中 TXIFG 默认设置(空缓冲区),如果您设置 TXIE 位,则稍后设置 GIE - bingo,您将有一个未处理的中断。

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

    您好 Dennis,

    感谢您的快速回复。 这绝对是一个很好的迹象,表明图书馆可以与 GCC 兼容。

    我将研究您关于未处理中断的建议,并返回信息。 老实说,如果这是一个未经处理的中断,那么奇怪的是,这种现象不是通过小模型来解决的。

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

    您好,Randy,

    我同意,但这是我最先想到的。  我还在由我们的 SW 团队负责管理,以征求意见。  

    我不知道 GCC 如何处理 ISR 处理程序的放置,但由于矢量仅为16位地址,您能否检查地图文件以查看它们是否放置在64K 内存的下半部分。

    以下是 MSP430FR2676_BSWP 示例.MAP 文件的片段。  您可以看到有放置在中

    下面是定义 FR2676中2-FRAM 内存段的链接器文件的片段,其中 FRAM 段以0x8000开头,并延伸到矢量表的正下方。

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

    GCC 将中断部分标记为“低文本”,以便链接器将其放置在下半部分。 链接器选项也会起作用,首选的是"-mcode-region=by"。 无是此选项的错误默认值。

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

    如果您检查了.map 文件,但没有看到任何代码被放置在低于64K 的地址中,那么我不知道。

    如果您创建了一个简单的程序(如以下程序)并完成了一个步骤,那么您是否看到了相同的问题?

    void main(void)
    {
    	WDTCTL = WDTPW | WDTHOLD;
    	
    	_no_operation();
    	__bis_SR_register(LPM0_bits | GIE);
    	_no_operation();
    }
    

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

    Dennis 和 David 您好,

    起初,我以 Dennis 的建议开始,为了捕捉一个未处理的中断,我为每个向量声明了一个处理程序,并检查了处理程序是否被击中。 不幸的是,处理程序未命中任何一个,仍然发现调试器命中0x4地址,如我附加到此回复的屏幕截图所示。

    然后,我开始按照 Dennis 的建议检查地图文件,我发现处理程序位于64K 内存的下半部分。 但是,我也看到该地址不在 FRAM 部分(0x8000),但在0x2000范围内找到了这些地址。 如果我在 LD 文件中查找此信息,则此部分必须是 RAM 部分。   我们附加了地图文件和用于 回复的 LD 文件,您能否检查我们是否正确读取了该地图文件?

    此外,我们还按照 David 的建议检查了编译器标记--mcode-region=by"。 我们 验证了定义此编译器标志的方法,并且可以在附加到此回复的 build.log (编译日志文件)文件中进行验证。 我们还看到处理程序被放置在“.lowtext”标记上,这可以在附加到此回复的地图文件中看到。

    最后,我们检查了 Dennis 提供的简单程序,编译并 成功执行了该程序,调试时它停留在“__bis_SR_register()”行。 但是,我们对简单程序做了一些调整,以增加简单程序的中断。 运行此选项时,它 还会跳至0x4地址,并像附加的屏幕截图所示那样卡住。 此简单程序的源文件也附在本答复中。

    通过所有这些信息,我们希望您能够重现此问题,并为我们提供更多的指导,谢谢。  

     e2e.ti.com/.../5756.main.ce2e.ti.com/.../0844.build.loge2e.ti.com/.../stb_5F00_map.txte2e.ti.com/.../msp430fr2676_5F00_ld.txt

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

    链接程序脚本在 FRAM 中放置 LOW.text 时正常。 但地图文件显示了一些不同的内容:

    .lowtext        0x0000000000002000      0x108 load address 0x00000000000080c4
     .lowtext       0x0000000000002000      0x108 stb/CMakeFiles/stb.dir/src/main.c.o
                    0x0000000000002000                P5_ISR
                    0x0000000000002006                ISR_TRAP0
                    0x000000000000200c                ISR_TRAP1
                    0x0000000000002012                ISR_TRAP2
    
    etc.

    查看链接程序脚本时,我找不到 msp430fr2676.ld 中定义的低文本。 快速的 grep 会在许多其他脚本中找到它,例如针对 fr5969的脚本:

      .text :
      {
        PROVIDE (_start = .);
    
        . = ALIGN(2);
        KEEP (*(SORT(.crt_*)))
    
        . = ALIGN(2);
        KEEP (*(.lowtext))
    
    

    因此,这似乎是 fr2676的链接程序脚本中的错误。 尝试编辑脚本以添加.lowtext 符号。

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

    您好,Randy,

    我使用 TI GNU 编译器(Mitto Systems 9.3.1.11)编译了以下代码片段,并进行了一次步进。 我从您的代码中复制的 ISR 引导程序和陷阱是不能显示的。  启用计时器中断并通过__bis_sr_register (LPM0_bits | GIE),代码将立即引导至计时器的正确陷阱,这是应该的。  我尝试了小内存和大内存模型。

    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;
    
        TA0CTL |= MC__UP | TASSEL_2;
        TA0CTL |= TAIE | TAIFG;
    
       __bis_SR_register(LPM0_bits | GIE);
    
    }

    这是我的拆卸。  在__bis_sr_register (LPM0 _bits | GIE)之前和之后验证您是否有 NOP;

    此外,您使用的是哪个调试器?

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

    大卫和丹尼斯,你好!

    起初,我们尝试了 David 的建议,更改 链接程序脚本。 将“.lowtext”符号添加到链接器文件时,ISR 处理程序的所有地址都从0x2xxx 更改为0x8xxx 左右。 在测试我们 之前使用按钮提供的基本示例时,现在似乎已经开始工作,它 现在按预期访问 ISR,但不会在某些地方卡住。 在验证链接程序脚本时,我看到我们使用了版本1.211,我在工具链目录中看到有较新版本1.212可用。 我们比较了这两个文件,发现这两个文件之间的唯一区别是添加了“低文本”部分。 这意味着 此问题在链接程序脚本的1.212版中得到了修复。

    现在基本示例有效,我们已经将 Captivate 库放回,以检查它现在是否也起作用。 运行此程序时,我们发现此修复程序未完全解决我们的问题。 在  启动设备时调用 Capt_CalibrateUI()时,由于转换中断终止,因此调用了 Capt_ISR 处理器。 但是,现在似乎在完成中断后,它没有返回 到低功耗模式下的状态,而是再次以0x4地址结束。 我们再次删除了用于调试 方案的方法的 MAP_*前缀。 这是我们再次使用 Capt_blockOnFlag()方法尝试进入低功耗模式并等待到设置转换结束标志时的情况。 在打开拆分时,可以看到 在__bis_SR_register()调用之前和之后没有 NOP 指令。 在插入__NO_OPERATION()调用之前和之后,它似乎会继续校准。

    我们已经朝着正确的方向迈出了一步,修改了链接器脚本,但我们不太确定如何解决这一问题,因为这 通常是 ROM 代码的一部分。 我们将  对其进行更详细的调查,但 我们希望您可以有更多的指针来查看。

    关于调试器,我们使用 TI Code Composer Studio 内置调试器与  Captivate - FR2676评估板和 Captivate - PGMR 编程器/调试板结合使用。

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

    感谢 Randy 为缩小问题范围所做的巨大努力。  我会在我的身边深入探讨这个问题。

    只是为了澄清:

    [引用 userid="458572" url="~/support/microsofts/MSP-low-Power-microcontroller-group/MSP430/f/MSP-low-Power-microcontroller-forum/1067402/msp430fr2676-interrupts -不工作-使用时-大模型寻址- mlarer-in_mspgOP/3952119] ,在打开呼叫寄存器前没有看到指令,并且在 N52119 (在 N3952bis_N)。 在插入__NO_OPERATION()调用之前和之后,它似乎会继续校准。

    您是否指在阻止代码以0x0004结尾且校准例程完成并继续运行(即代码按预期运行)之前和之后执行 nop()指令?

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

    这是正确的,当在 Capt_blockOnFlag()方法中围绕__bis_SR_register()调用放置 nop()实例时,我们完成了校准例程。 但是,当我们在校准后运行代码时,代码无法成功运行,但在0x4时再次卡住,或者点击错误号(),如所附的屏幕截图所示。 理论上,它是否有可能被其他点卡住,因为此时还没有 nops()在__bis_sr_register 周围?

    作为补充信息,我们为 Captivate 创建了一个单独的模块,称为 CPT,我们在该模块中使用下面链接中所述的简单代码示例。 请注意,CPT_Run()方法在顶层“whit-loop”中被连续调用。

     http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/CapTIvate_Design_Center/latest/exports/docs/users_guide/html/CapTIvate_Technology_Guide_html/markdown/ch_library.html#simple-code-example

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

    设置/清除 GIE 时,发出 NOP 指令的目的是为了计时。 例如,清除 GIE 后的指令可能会在中断被禁用之前开始执行。 如果目的是防止以下指令被中断,这将是一个问题。 因此 ,编译器会自动插入它们。

    从“信息为”

    '-mn'
         enables the generation of a NOP instruction following any
         instruction that might change the interrupts enabled/disabled
         state.  The pipelined nature of the MSP430 core means that any
         instruction that changes the interrupt state ('EINT', 'DINT', 'BIC
         #8, SR', 'BIS #8, SR' or 'MOV.W <>, SR') must be followed by a NOP
         instruction in order to ensure the correct processing of
         interrupts.  By default it is up to the programmer to supply these
         NOP instructions, but this command-line option enables the
         automatic insertion by the assembler, if they are missing.
    

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

    大卫,你好。

    我们添加了“-Wa,-mn”编译器标志 ,现在它似乎连续执行了 Capt_updateUI()方法,这意味着它不再被卡住。 当暂停代码时,我看到它停在某个位置,调试器显示__errno()文件,但当进一步步进或断入代码时,它将被识别并可调试。

    当 Capt_updateUI()方法正在运行时,我们还没有看到探测到接触/接近,还看到“bCalibrationError”标记被设置为1。 这是 目前的最后一个状态,我们 将深入探讨这个问题,并向您和 Dennis 提供更多信息。

    关于编译器标志, '-mdata-region'标志设置为 none 是否正确? 还是这也需要这两个值?

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

    除非您在汇编程序中做一些有趣的事情,否则不应要求将-mn 标志发送给汇编程序。 编译器在与 GIE 进行 fidling 时添加了需要或不需要的 NOP。 如果装配者认为需要 NOP,则会发出警告(或至少确实发出了警告)。

    很少真正需要这些解决方案。

    由于所有 SRAM 都在较低的内存中,因此任何 SRAM 都不能正常工作。 如果使用大量标记为持久的内存,这可能会很有用。 将其放入 FRAM 中。

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

    感谢丹尼斯和大卫的帮助! 目前,我们似乎能够与 Captivate 库一起执行自己的代码。 当使用 MAP_Capt_getGlobalUIProximityStatus()检测到接近时,我们可以切换 LED,非常基本,但 它是一个很好的扩展起点。

    总结:确保链接程序脚本包含“.lowtext”符号(使用版本1.212),使用链接程序标志 “--mcode-region=by",并且“'-mn”编译器标志完成了该操作。  我身边最后缺少的一点是 ISR 处理器的定义不正确,不仅适用于 Captivate,还适用于 GPIO,UART,ADC 等。对于其他用户,使用 MSP-GCC 时,需要使用“__attribute__(中断(Captivate 矢量))”定义,而不是使用#pragma vector=Captivate 矢量。 我们之前检查过这一点,但由于构建系统在清理输出时刷新外部源,它被删除,并恢复为用于普通编译器的原始定义。

    再次感谢您对这项工作的贡献!

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

    Randy 做的很棒  这对 TI 非常有帮助,因为这证实了 Captivate Library 可以与 GCC 重新编译并运行。  你们为社区的发展提供了一个很好的总结,我再次感谢你们的工作,并感谢 大卫帮助我们完成与海湾合作委员会有关的旗帜。

    由于您看起来是您的路由,我将把此帖子标记为已解决。  如果不是这种情况,请单击“这无法解决我的问题”按钮,并以更多信息回复此主题。
    如果此线程锁定,请单击“询问相关问题”按钮,在新线程中描述您的问题的当前状态以及您可能需要帮助我们解决您的问题的任何其他详细信息。