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.

[参考译文] MSP430FR2422:MSP430-GCC 属性请求

Guru**** 2590990 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/875705/msp430fr2422-msp430-gcc-attribute-request

器件型号:MSP430FR2422

目前、gcc 允许将函数属性为中断。

当添加为属性时、我希望看到具有以下规范的附加修饰符标记:

必须伴随一个"中断"标签

-不要使用正常的 RETI 返回、而是使用 RET

我提出此请求的动机是减少禁用中断时所花费的时钟周期数。

当我写入中断处理程序时、我访问敏感位(如 TA0CCR1)、然后快速重新启用中断、以允许其他时间敏感的进程继续。

然后、我执行需要执行的任何操作、并从函数中执行 RETI。

但是、目前如果我有一个中断函数、那么在我甚至可以访问时间敏感寄存器(如 TA0CCR1)之前、函数中被触摸的所有寄存器都被压入堆栈

我要做的是将我的中断处理程序拆分为两个函数:

 -一个立即处理程序(在堆栈上推入极少或没有寄存器)、用于处理时间敏感的东西并重新启用中断

 立即 处理程序(使用调用)调用的后续函数(标记为"interrupt"和新属性)、然后将堆栈上需要的任何寄存器入栈并使用 RET 返回

在使用 ASM "br ADDR"指令之前,我曾遇到过类似的行为,但我认为这样做会更干净。


同样、我希望、如果中断函数在栈上不按任何参数并调用另一个中断函数、这将简化为仅使用"br"指令。

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

    听起来像是一个汇编语言作业。 虽然我怀疑裸体会被滥用来做你想要的事。

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

    我希望保留编译器的自动寄存器分配行为。 因此、裸机在这里不起作用。

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

    此代码:

    void __attribute__((naked、interrupt (TIMER0_A0_vector))) stub (void)
    {
    tick++;
    }
    
    void __attribute__((interrupt)) Timer0_A0_ISR (void)
    {
    int i;
    
    for (i = 0;i < 10;i++)
    P1OUT ^= 1;
    }
    

    结果为:

    void __attribute__((naked、interrupt (TIMER0_A0_vector)) stub (void)
    {
    tick++;
    4474: 92 53 04 1c 公司 &0x1c04 ;
    
    00004478 :
    }
    
    void __attribute__((中断) Timer0_A0_ISR (void){
    
    4478: 0°C 15. Pushm #1、 R12. ;16位字
    
    0000447a <.LCFI3>:
    447a: 7C 40 0A 00 MOV.b #10、R12 ;#0x000a
    
    0000447e <.L14>:
    int I;
    
    for (i = 0;i < 10;i++)
    P1OUT ^= 1;
    447e: D2 E3 02 02 XOR.b #1、 &0x0202;R3 As=01
    
    00004482 <.LVL14>:
    4482: 3c 53. 添加 #1、R12 ;R3 As=11
    
    00004484 <.LVL15>:
    
    void __attribute__((interrupt)) Timer0_A0_ISR (void)
    {
    int i;
    
    for (i = 0;i < 10;i++)
    4484: 0C 93 CMP #0、 R12. ;R3 As=00
    4486: FB 23. Jnz 8美元 ;abs 0x447e
    
    00004488 <.Loc.52.1>:
    P1OUT ^= 1;
    }
    4488: 0C 17. Poem #1、 R12. ;16位字
    448a: 00 13. TI 

    它当然可以满足您的需求。

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

    您好、Dave、

    让我检查一下我是否理解了您要做的事情:

    • 为了防止时间敏感型寄存器"过时"、"立即处理程序"不会保存任何寄存器、除非明确要求。
      • 我假设这个 ISR 已经被汇编语言编写、以防止 GCC 为您保存这些寄存器中的任何一个?
      • 我还假设在调用"后续函数"后、除了 RETI、此 ISR 不执行任何操作?
    • "立即处理程序"调用"后续函数"(用 C 编写)、该函数包含 ISR 中代码的主要部分、并保存修改的寄存器。

    我明白这是个问题的原因、但我认为拥有一个 ISR、它可以被修改为只像 ISR 那样具有部分行为、这是一个需要解决的问题、并不能解决真正的问题。

    如果您能够以某种方式向 ISR 中添加一个"预编译"代码段、该段在常规编译运行之前执行并保存必要的寄存器、会怎么样? 这还将使您不必插入额外的调用指令。

    此致、

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

    在后续处理程序前面准备一个裸中断处理程序可能会在我的大多数情况下达到90%。 非常整洁!

    当存根必须分配比较器但仍发生的寄存器时、它不会处理这种情况。

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

    Josef、

     我的 ISR 几乎用 C 语言编写、但在少数情况下除外。 现在、我在保存这些寄存器之前、要吃 pushm 的延时时间。

     正确、这些处理程序在 RETI 之后永远不会执行任何任务。

    我真的很喜欢序言前的想法、在这种情况下、这肯定对我有效!

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

    这是一个巧妙的技巧、但如果与-ffunion-sections 一起使用、可能会有危险。 链接器可以自由地移动段、并且只要使用了-mcode-region=、链接器就会这样做。

    有大量 GCC 优化 可重新排序、虽然在函数级别运行的优化看起来都需要配置文件反馈、但这不是将来可以依赖的行为。 尤其是在 LTO 的进步中。

    但是、如果程序员知道风险、这是一个很好的解决方案。

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

    好的、听起来不错。 我需要更详细地了解这项提议的功能的细节、但我们的目标是将其纳入今年发布的其中一个版本中。

    此致、

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

    我确实说过"滥用"。 :-)

    您可以防止链接器很容易地移动内容:

    void __attribute__((naked、interrupt (TIMER0_A0_vector))) stub (void)
    {
    tick++;
    __eint ();
    
    asm ("br &Timer0_A0_ISR\n");
    }
    

    但是、组装仍然是最好的方法。 在跳转到主部分之前、要么针对整个 ISR、要么仅针对这个关键位。