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.

[参考译文] MSP430FR6043:MSP430-GCC:如何将多个向量设置为同一个陷阱处理程序(C、链接器或 ASM)?

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1298962/msp430fr6043-msp430-gcc-how-to-set-multiple-vectors-to-the-same-trap-handler-c-linker-or-asm

器件型号:MSP430FR6043

为了降低 FRAM 消耗、我要尝试将同一个公共陷阱处理程序设置为 MSP430FR6043上的多个中断矢量。

借助 TI 编译器、可以使用"pragma 向量":

#pragma vector=RTC_VECTOR, PORT2_VECTOR, …, UNMI_VECTOR
__interrupt void Dummy_ISR(void) { while (1) { } }

MSP430 GCC 编译器9.3.1.11是否有使用"__attribute__(interrupt (x))"的等效代码?

MSP430 IRQ 处理器和向量中 、有一条提示、但是它每32位而不是每16位填充一次存储器(向量表中有16位元素!)。

示例 msp430fr6043.ld:

MEMORY {
…
  UNUSED_VECTS_1   : ORIGIN = 0xFF90, LENGTH = 0x004C  /* END=0xFFDB, 38 vectors, size 76 bytes*/
…
}

SECTIONS
{
…
  __unused_vectors_1      : { KEEP (*(__unused_vectors_1)) } > UNUSED_VECTS_1  /* 0 - 37 =  38 vectors */
…
}

Traps.c:

static void __attribute((interrupt)) default_trap(void) {
    while (1) { }
}

__attribute__((section("__unused_vectors_1"), used))
static void (*vectors[19])(void) = {  // 1. compile ok, but elements are 32 not 16-bit!
//static const uintptr_t v[19] = {    // 2. compile ok, but elements are 32 not 16-bit!
//static const __int20 v[19] = {      // 3. compile ok, but elements are 32 not 16-bit!
//static const uint16_t v[38] = {     // 4. compile error: initializer element is not computable at load time
    default_trap,  // unused
    default_trap,  // unused
    default_trap,  // unused
    default_trap,  // unused
    0,             // intentionally left zero to check the result
    0,             // same as above
};

在上述 traps.c 代码片段中,前3种形式会进行编译,但结果是错误的。 例如、如果 DEFAULT_TRAP 的结果地址为0x99FA、那么在0xFF90处得到的存储器内容为:99FA 0000、99FA 0000、99FA 0000、99FA 0,000,0000 0000、 0000 0000,... 但我期望的是99FA, 99FA, 99FA, 99FA,...

如果我尝试将表强制为16位(上述 traps.c 中的形式4)、则代码无法编译、并出现"加载时无法计算初始化器元素"错误!

有什么建议如何使用任何 C/ASM/连接器组合通过 GCC 实现此目标? 谢谢!

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

    我不知道为什么需要默认处理程序。 除非你启用这些特定中断、它们永远不会发生、所以无需处理程序。

    从来没有这样做过,我尝试了明显的事情:

    unsigned __attribute__((section("__interupt_vector_nmi"), used)) nmi_vector = Timer_A;

    但遇到了相同的错误。 快速测试表明、当然可以在运行时将函数的地址分配给变量、编译器对此不会发出任何抱怨。 我能想到的唯一替代方法是使用原始汇编语言。 对此并不特别困难。 或者至少不是我为一只胳膊做的时候。 甚至对于 MSP430:

            .section __interrupt_vector_timer0_a0,"ax",@progbits
            .word   timer_A_CCR0_isr
            .section __interrupt_vector_usci_a0,"ax",@progbits
            .word   usci_a0_isr
            .section __interrupt_vector_sysnmi,"ax",@progbits
            .word   sysnmi_irq
            .section .resetvec,"ax",@progbits
            .word   sys_init
    

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

    非常感谢!  这项工作做得非常完美!

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

    我实际上是说要明白恩宠。 就像在.S 文件中一样。 (S 对 S 很重要。)

    我已经看到了何处使用"弱"符号、为那些向量分配了值、如果您在其他地方创建 ISR、这些值将会被覆盖。 因此、一个带有默认处理程序和矢量定义的.S 文件为 每个中断提供默认值。

    她对我很生气。 如果你不为特定器件启用中断、中断将永远不会发生、所以你就不需要一个 ISR。 更糟糕的是、某些器件不会自动清除中断、因此您会卡在中断循环中。 因此、默认处理程序没有太大帮助。