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.

[参考译文] MSP430G2452:访问堆栈上的 SR 位置。

Guru**** 2508425 points
Other Parts Discussed in Thread: MSP430F2013

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/986041/msp430g2452-access-sr-location-on-stack

器件型号:MSP430F2013

由于 MSP430F2013上的闪存数量有限 、我的引导加载程序(位于闪存的上限1K)处理一些低级 I2C 功能并将执行传递给应用(位于闪存的下限1K)。 使用常规函数调用传递执行。

要在中断退出时更改电源状态、应用需要在退出时更改 SR 寄存器的状态以进行中断。 为此、我分配了一个变量 SR_ADDRESS_ON_EXIT (地址0x027C)、该变量在引导加载程序和应用程序之间共享。 在引导加载程序调用应用程序之前、它会将"堆栈" SR 寄存器的地址写入 0x027C。 如果应用程序需要在退出时更改电源状态、它将从 0x027C 中获取存储 SR 的地址、并根据需要进行更新。

问题是确定 SR 在堆栈上的位置。 调用 __get_SR_register_ON_EXIT ()会返回 SR 寄存器的"中断退出"值。

调用__get_sp_register()将返回当前值,而不考虑帧大小(在中断开始时调用 push.W)。

一种方法是用汇编语言编写 ISR、此时这是不可行的。

最好具有一个内在函数__get_sp_on_exit (),该函数将返回 SP 的值+"push.W 调用添加的任何内容"。

是否可以使用当前工具在堆栈上获取 SR 地址而不在汇编语言中写入整个 ISR?

2.另一种方法是 调用 __get_SR_register_ON_EXIT ()并将 SR 值保存在共享位置。 如果需要、应用程序将更新共享位置的值。 返回到引导加载程序后、来自共享位置的值应写入栈上的 SR 值。 在汇编语言中、它可以用一条指令来完成。 由于__set_SR_ON_EXIT (val)不存在,我必须进行两次调用:

__bic_SR_register_on_exit(~sr_value_on_exit);
__bis_SR_register_on_exit(sr_value_on_exit);

这些将展开为四条指令:

MOV.W &sr_value_on_exit+0,r15
INV.W r15
BIC.W r15,10(SP)
BIS.W &sr_value_on_exit+0,10(SP)

任何使编译器生成指令的方法:

MOV.W &sr_value_on_exit+0,10(SP)

自动? 这会将4条指令替换为仅1条指令(节省一些闪存空间和执行时间)。

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

    您好!

    似乎您已经深入探讨了这个问题、尽管我没有完全关注这个问题。  您是否正在尝试修改栈上的值、以便在从中断/函数返回时自动加载该值?   

    至于#1、您似乎完全了解、但 所有可用的内在函数都列在 MSP430编译器 UG 中 、并且没有您所要求的函数。

    对于#2。。。。。 进行一些挖掘时、您列出的内在函数似乎也是唯一的选择、但我知道您需要完全复制、因此必须同时调用这两个函数、并添加几行汇编代码。    

    到目前为止、我无法为您提供更好的解决方案。  我们确实有一个用于混合 C 语言和汇编语言的应用手册、但它需要将汇编语言编写在单独的文件中并通过其自身的函数调用进行调用... 因此、我认为只有您按照您提到的那样编写整个函数、这才会真正有帮助。

    从代码空间的角度来看、这4行代码或汇编代码是太多、还是只是为了保存这些指令?  

    谢谢、

    JD   

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

    在 MSP430F2013上实现 I2C 功能需要占用大量可用闪存。 因此、向引导加载程序和应用程序添加 I2C 不切实际。 我在引导加载程序中实现了低级 I2C 功能,应用程序仅包含高级处理程序char rxbyte(void)void txbyte(char)。 要在退出时更改电源状态、应用必须更改 堆栈上的返回 SR 值。 为此、引导加载程序可以通过存储器中的保留地址将位置的地址传递给应用程序。 另一种方法是引导加载程序将 SR 退出值复制到应用程序可以在需要时更新的保留存储器位置。 返回到引导加载程序后、该值将复制回堆栈空间。 到目前为止、后者是在 C 语言中实施它的唯一方法

    4行也不算太差。 它只是一个可以改进的东西。  如果在汇编语言中有一个"本地帧大小"宏、那么我要写一个类似这样的东西来更新堆栈上的 SR 值:

    asm("MOV.W &sr_value_on_exit,FRAMESIZE(SP)");

    我认为 TI 应该通过添加__get_sp_register_ON_EXIT ()和__set_SR_register_ON_EXIT ()来扩展内在函数列表。

    谢谢你。

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

    嗨、Gennadiy、

    感谢您的反馈。  我将把它传递给编译器团队。  很明显、4行权变措施目前已足够满足您的需求?   

    我还寻找了一种将汇编语言直接插入 C 代码的方法、但编译器也不支持这种方法、尽管我认为 MSP430 GCC 编译器确实支持直接在代码中插入 asm 指令。  在本例中、您只需输入一行、然后继续按 C   

    这是一个有趣的用例。   感谢您的分享。  

    JD

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

    是的、两行 C 指令(4行汇编)就足够了。

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

    当您说不支持 C 语言汇编语言时、您是指特定的编译器吗? 我可以将 asm ("")指令插入我的 C 代码中。 例如、引导加载程序使用以下行将 WDT 中断传递给应用程序:

    #pragma location=0xFBFC
    const unsigned int __WDT_AISR;
    #pragma vector = WDT_VECTOR
    __interrupt void wdt(void)
    {
    __asm("\t MOV.W\t &__WDT_AISR, PC");
    }

    我使用的编译器是 TI v.18.12.7.LTS。 从 Code Composer Studio v9运行。 它还与以前版本的编译器一起在 CCS V8中工作。

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

    您好 Gennadiy、

    抱歉。  我只是仔细检查 了编译器 UG ,您可以像现在一样使用内联 asm ()函数。  (这正是我所期望的。)  

    昨天我刚刚看到一些旧的 E2E 帖子,说它不受支持,但仔细观察,用户试图以一种不受支持的非常具体的方式使用 ASM(),而不是内联汇编支持本身。  

    你们都很好!

    JD