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.

[参考译文] MSP430FR2000:MSP 低功耗微控制器论坛

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1230593/msp430fr2000-msp-low-power-microcontroller-forum

器件型号:MSP430FR2000

您好!

 我正在处理一个需要定时器 B 和 2端口中断的项目。 在项目中、我收到如下错误。

#10099-D 程序将无法放入可用内存中,或者该段包含的调用站点需要无法为该段生成 trampoline。 对齐放置在"ALL_FRAM"段大小0x316中失败。 可用内存范围:lnk_msp430fr2000.cmd /编译行132 C/C++ problem

因此、我尝试了尽可能多的方法、但错误仍然存在。 所以、我仔细监控了 FRAM 大小、发现在 ISR 中编辑全局变量的多行导致了问题的产生。  有问题的代码如下。

#include "msp430fr2000.h"


volatile int Cpwm = 0;

int main(void){                                                //P1.1 PULSES COMING FOR FAIL SAFE      P1.3 RESET THE MICRO CONTROLLER

  P1DIR |= 0x09;  // P1.0 & P1.3 output
  PM5CTL0 &= ~LOCKLPM5;
   WDTCTL = WDTPW + WDTHOLD;
  TB0CCTL0 = CCIE;                            // CCR0 interrupt enabled
  TB0CCR0 = 40000; // 1

  TB0CTL = TBSSEL_1 + MC_1 + ID_2;                 // SMCLK, contmode

    P1DIR &= (~0x06); // Set P1.1 & P1.2 Set as Input
    P1IES |= (~0x06); // rising Edge
    P1IFG &= (~0x06); // Clear interrupt flag for P1.1 and P1.2
    P1IE |= (0x06); // Enable interrupt for P1.3
    _BIS_SR(GIE);

while(1){
   P1OUT = 0x08;

}

}

// Timer A0 interrupt  routine

#pragma vector=TIMER0_B0_VECTOR
__interrupt void Timer_B (void){


  P1OUT &= ~(0x08);                         // RESET heartbeat P1.1
  __delay_cycles(10000);
  P1OUT |= 0x08;
  __delay_cycles(100000);


 if(((P1IN && 0x04)||(P1IN && 0x06) ) && (Cpwm == 0)){
     P1OUT |= 0x01;  //Failsafe on
  }

}



#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{

if(P1IFG==0x02){
    TB0R = 0;
    P1IFG &= (~0x02); // HEART BEAT
    if(Cpwm==0){


       if((P1IN && 0x04)||(P1IN && 0x06) ){
                    P1OUT &= ~(0x08);                          // RESET heartbeat P1.1
                    __delay_cycles(10000);
                    P1OUT |= 0x08;
                    __delay_cycles(100000);
                                       //oooooooooooooooooooooooooooooooooooooooo
                    if((P1IN && 0x04)||(P1IN && 0x06) ){
                            P1OUT |= 0x01;  //Failsafe on
            }                                              //0000000000000000000000000000000000000000000000000000000000


        }else{
            P1OUT &= ~(0x01);  // turn off fail safe

        }

    }


    Cpwm = 0;
    TB0R = 0;

}
else if(P1IFG==0x04){
    Cpwm = Cpwm+1 ;
    P1IFG &= (~0x04);      // PWM

}


}

当我将代码全局变量更改为常量、并 在 ISR 例程中对全局变量进行编辑的各行添加注释时、发现这是使用低内存构建的。   代码和内存分配如下。

#include "msp430fr2000.h"


const int Cpwm = 0;

int main(void){                                                //P1.1 PULSES COMING FOR FAIL SAFE      P1.3 RESET THE MICRO CONTROLLER

  P1DIR |= 0x09;  // P1.0 & P1.3 output
  PM5CTL0 &= ~LOCKLPM5;
   WDTCTL = WDTPW + WDTHOLD;
  TB0CCTL0 = CCIE;                            // CCR0 interrupt enabled
  TB0CCR0 = 40000; // 1

  TB0CTL = TBSSEL_1 + MC_1 + ID_2;                 // SMCLK, contmode

    P1DIR &= (~0x06); // Set P1.1 & P1.2 Set as Input
    P1IES |= (~0x06); // rising Edge
    P1IFG &= (~0x06); // Clear interrupt flag for P1.1 and P1.2
    P1IE |= (0x06); // Enable interrupt for P1.3
    _BIS_SR(GIE);

while(1){
   P1OUT = 0x08;

}

}

// Timer A0 interrupt  routine

#pragma vector=TIMER0_B0_VECTOR
__interrupt void Timer_B (void){


  P1OUT &= ~(0x08);                         // RESET heartbeat P1.1
  __delay_cycles(10000);
  P1OUT |= 0x08;
  __delay_cycles(100000);


 if(((P1IN && 0x04)||(P1IN && 0x06) ) && (Cpwm == 0)){
     P1OUT |= 0x01;  //Failsafe on
  }

}



#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{

if(P1IFG==0x02){
    TB0R = 0;
    P1IFG &= (~0x02); // HEART BEAT
    if(Cpwm==0){


       if((P1IN && 0x04)||(P1IN && 0x06) ){
                    P1OUT &= ~(0x08);                          // RESET heartbeat P1.1
                    __delay_cycles(10000);
                    P1OUT |= 0x08;
                    __delay_cycles(100000);
                                       //oooooooooooooooooooooooooooooooooooooooo
                    if((P1IN && 0x04)||(P1IN && 0x06) ){
                            P1OUT |= 0x01;  //Failsafe on
            }                                              //0000000000000000000000000000000000000000000000000000000000


        }else{
            P1OUT &= ~(0x01);  // turn off fail safe

        }

    }


 //   Cpwm = 0;
    TB0R = 0;

}
else if(P1IFG==0x04){
  //  Cpwm = Cpwm+1 ;
    P1IFG &= (~0x04);      // PWM

}


}

那么、我们为什么不能编辑任何全局变量、是否有任何方法可以与不同的中断服务例程和主代码共享数据? 任何类型的帮助都是非常感谢。  

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

    您好、Ravindo:

    是的、全局变量会对代码大小产生很大影响。 因此、我们建议避免使用全局变量值。 我的建议是、您可以在 FRAM 中使用特定地址来记录代码未使用 FRAM 区域的标志数据。  

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

    您好、Gary Gao、

    首先,谢谢你的答复。 我最近发现有一个名为 SYSCFG 的 FRAM 内存保护寄存器、此寄存器可被用来访问受保护的 FRAM 区域。 我 对 使用 C 编程访问受保护 FRAM 中某个位置的经验不多。 如果有任何教程或示例可以提供,将是一个很大的帮助。  

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

    是的、如果您要在 FRAM 中写入值、您可以这样做

    jump_key 是定义的值、是用于保存标志值的地址。

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

    TI 多年前创建了一个文档、该文档详细介绍了如何为低内存器件(如 FR2000)创建优化的 C 代码。 这是一个非常有用的文档、甚至描述了将全局变量初始化为值会产生更大代码大小的原因。  《利用 MSP430 MCU 优化 C 代码:提示和技巧》(SLAA801)