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.

[参考译文] MSP430FR5994:使用&'doube'声明会导致调试崩溃

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1067376/msp430fr5994-using-double-declaration-leads-to-a-crash-in-debugging

部件号:MSP430FR5994
《线程》中讨论的其他部件:BOOSTXL-音频ABS

我有一个代码,用于计算神经网络的一些数学系数。 在调试过程中,我有一个需要为“双”数据类型的变量。 当我在特定位置的代码中使用它时,代码在调试过程中会崩溃。 我使用 BOOSTXL-AUDIO Playback 示例作为参考。 在过去的几天里,我测试了不同的案例,以观察发生这种碰撞的案例。 在我发现的两种情况中,在一种情况下,当我使用“双”数据类型声明变量时,代码工作正常,并继续执行,但在另一种情况下, 完全相同的代码无法执行,并进入“永久锁定”状态,或者只关闭代码并将其分支到“boot.c”文件中。 我完全不知道为什么它对完全相同的代码会有不同的行为,除了一个变量被定义为“双变量”而不是“浮点”的更改。  

PS。 根据函数定义,变量需要为“双”格式。  

下面是发生崩溃的代码的一部分。 我正在从项目中添加“主.c”和“应用程序.c”文件。

int main(void)
{
     WDTCTL = WDTPW | WDTHOLD;       // Stop watchdog timer

    initClock();
    initGpio();

    PM5CTL0 &= ~LOCKLPM5;           // Clear lock bit

    // vm1010 mode pin (P6.1), o/p, low at start for normal mode
    P6OUT &= ~BIT1;             // vm1010
    P6DIR |= BIT1;              // vm1010
    // vm1010 mic power on (P6.2)
    P6OUT |= BIT2;              // vm1010
    P6DIR |= BIT2;              // vm1010

    // vm1010 mode pin, o/p, high for WoS mode
    P6OUT |= BIT1;              // vm1010

    P5IFG &= ~BIT6;             // Clear interrupt on P5.6
    P5IE |= BIT6;               // Enable interrupt on P5.6
    P5IFG &= ~BIT5;             // Clear interrupt on P5.5
    P5IE |= BIT5;               // Enable interrupt on P5.5

    // vm1010
    P5IFG &= ~BIT7;             // Clear interrupt on P5.7
    P5IE |= BIT7;               // Enable interrupt on P5.7

    // Enable Switch interrupt
    GPIO_clearInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN);
    GPIO_enableInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN);

    // Initialize DAC
	DAC8311_init();

	// Set the DAC to low power mode with output high-Z
	DAC8311_setLowPowerMode(DAC8311_OUTPUT_HIGHZ);

	__bis_SR_register(GIE);

    // Starts the application. It is a function that never returns.
    runApplication();

    return 1;
}
    
void runApplication(void)
{
    while(1)
    {
        P5IE &= ~BIT7;      // Disable interrupt on P5.7 // vm1010
        P5IE &= ~BIT6;      // Disable interrupt on P5.6
        P5IE &= ~BIT5;      // Disable interrupt on P5.5

		// Disable button interrupt
		GPIO_disableInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN);

    	switch(applicationMode)
        {
    	    volatile uint16_t j;
            case RECORD:
*                runRecord();
*                amplify_data();
*                fft_init();
                while(window_number < 64)
                {
                    fft_cal();
                }
                window_number=0;
                for(j = 1; j < (VECTOR_SIZE / 2); j++)  // vm1010
                {
                    // vm1010
                    real = fft_res[2 * j] << 2;
                    imag = fft_res[2 * j + 1] << 2;
                    if(real < 0)
                    {
                        real_abs = ~real + 1;
                    }
                    else
                    {
                        real_abs = real;
                    }
                    if(imag < 0)
                    {
                        imag_abs = ~imag + 1;
                    }
                    else
                    {
                        imag_abs = imag;
                    }
                    if(real_abs >= imag_abs)
                    {
                        max = real_abs;
                        min = imag_abs;
                    }
                    else
                    {
                        max = imag_abs;
                        min = real_abs;
                    }
                    mag = max + 3 * (min >> 3);
                    FFT_data[j] = mag << 1;
                }
                break;
            default: break;
        }

        // Toggle app mode
		applicationMode = DEFAULT;

		P6OUT &= ~BIT1;                 // vm1010

		// Set a Switch debounce to 500ms
        __delay_cycles(0.5 * __SYSTEM_FREQUENCY_MHZ__);

        P5IFG &= ~BIT6;                 // Clear interrupt on P5.6
        P5IE |= BIT6;                   // Enable interrupt on P5.6
        P5IFG &= ~BIT5;                 // Clear interrupt on P5.5
        P5IE |= BIT5;                   // Enable interrupt on P5.5
        P5IFG &= ~BIT7;                 // Clear interrupt on P5.7 // vm1010
        P5IE |= BIT7;                   // Enable interrupt on P5.7 // vm1010
        // vm1010 mode pin, o/p, high for WoS mode
        P6OUT |= BIT1;  // vm1010

        GPIO_clearInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN);        // Clear the interrupt flag
        GPIO_enableInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN);       // Re-enable the interrupt

        // Enter low power mode
        
*		__bis_SR_register(LPM4_bits + GIE);
		
		float mfcc_result;
		float mfcc_value[13];
		float mfcc_features_f[12];
*        if(FFT_data[1] != 0)
        {
            // MFCC Calculations can be included here

            double spectrum[512];  // when double changes to float - the code runs correctly
            int i;
            for(i=0;i<512;i++)
            {
                spectrum[i] = (double)FFT_data[i];
            }

我还在第二个文件中标记了我的调试点的位置“*”。 我尝试查看详细描述数据类型和声明行为的不同文档,但我找不到这种行为的原因。 在 另一个项目中单独执行时,如果使用完全相同的逻辑(包括“双”声明)执行,则系数的计算工作正常。 如果我能对这里可能出现的问题有任何想法,我可以尝试一下。 如果需要更多详细信息来帮助更好地理解问题,请告诉我。  

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

    如果你可以使用浮子,你应该可以使用双倍。 您可以将程序下压为显示问题的小示例吗?

    作为 WAG,您可能会尝试增加堆栈空间。

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

    // Returns the specified (mth) MFCC
    double GetCoefficient(double* spectralData, unsigned int samplingRate, unsigned int NumFilters, unsigned int binSize, unsigned int m);
    
    void runApplication(void)
    {
        while(1)
        {
            P5IE &= ~BIT7;      // Disable interrupt on P5.7 // vm1010
            P5IE &= ~BIT6;      // Disable interrupt on P5.6
            P5IE &= ~BIT5;      // Disable interrupt on P5.5
    
    		// Disable button interrupt
    		GPIO_disableInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN);
    
        	switch(applicationMode)
            {
        	    volatile uint16_t j;
                case RECORD:
                    runRecord();
                    amplify_data();
                    fft_init();
                    while(window_number < 64)
                    {
                        fft_cal();
                    }
                    window_number=0;
                    // Some code for calculations
                    break;
                default: break;
            }
    
            // Toggle app mode
    		applicationMode = DEFAULT;
    
    		P6OUT &= ~BIT1;                 // vm1010
            GPIO_clearInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN);        // Clear the interrupt flag
            GPIO_enableInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN);       // Re-enable the interrupt
    
            // Enter low power mode
    		__bis_SR_register(LPM4_bits + GIE);
    		
    		float mfcc_result;
    		float mfcc_value[13];
    		float mfcc_features_f[12];
            if(FFT_data[1] != 0)
            {
                // MFCC Calculations can be included here
                double spectrum[512];
                int i;
                for(i=0;i<512;i++)
                {
                    spectrum[i] = (double)FFT_data[i];
                }
                int coeff;
                for(coeff = 0; coeff < 13; coeff++)
                {
                        mfcc_result = GetCoefficient(&spectrum[coeff], 44100, 48, 128, coeff);
                        mfcc_value[coeff] = mfcc_result;
                }
            }
        }
    }
    
    int main(void)
    {
         WDTCTL = WDTPW | WDTHOLD;       // Stop watchdog timer
    
        initClock();
        initGpio();
    
        PM5CTL0 &= ~LOCKLPM5;           // Clear lock bit
    
        // vm1010 mode pin (P6.1), o/p, low at start for normal mode
        P6OUT &= ~BIT1;             // vm1010
        P6DIR |= BIT1;              // vm1010
        // vm1010 mic power on (P6.2)
        P6OUT |= BIT2;              // vm1010
        P6DIR |= BIT2;              // vm1010
    
        // vm1010 mode pin, o/p, high for WoS mode
        P6OUT |= BIT1;              // vm1010
    
        P5IFG &= ~BIT6;             // Clear interrupt on P5.6
        P5IE |= BIT6;               // Enable interrupt on P5.6
        P5IFG &= ~BIT5;             // Clear interrupt on P5.5
        P5IE |= BIT5;               // Enable interrupt on P5.5
    
        // vm1010
        P5IFG &= ~BIT7;             // Clear interrupt on P5.7
        P5IE |= BIT7;               // Enable interrupt on P5.7
    
        // Enable Switch interrupt
        GPIO_clearInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN);
        GPIO_enableInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN);
    
        // Initialize DAC
    	DAC8311_init();
    
    	// Set the DAC to low power mode with output high-Z
    	DAC8311_setLowPowerMode(DAC8311_OUTPUT_HIGHZ);
    
    	__bis_SR_register(GIE);
    
        // Starts the application. It is a function that never returns.
        runApplication();
    
        return 1;
    }

    我试图在这里简明扼要地概括这个问题。 我的想法是,我有一个名为 GetCoeffices()的函数,它以“双”格式返回一个值。 我想使用此函数来计算使用 MSP430的一些系数。 在计算系数之前,需要从外部麦克风提供此函数的输入-当调试代码时,代码应首先分支到 runApplication 函数中,并通过-__bis_SR_register (LPM4_bits + GIE)进入低功耗模式; 从此处删除 MSP430后,它会检查一个阵列并记录声音并进行一些计算,然后通过-__bis_sr_register  (LPM4_bits + GIE)在低功耗模式下再次结束;  从此处删除后,下一个任务是使用“double()”函数计算系数-在这个位置,我遇到了这个问题。 如果我使用“双”的“浮子”输入词来声明变量“三频”- MSP430运行顺畅-但当“三频”被定义为“双频”时 -代码在上半部分突然停止,甚至不进入低功耗模式。 我不知道这个问题是如何发生的,因为我尝试使用“浮点”值代替“双变量”参数——它们只是在这些程序中显示警告——此外, 在这里,我试图通过将计算存储在“双变量”中来维护数据类型,只有在执行此步骤后,我才将其移动到另一个“浮点”变量中。

    我对冗长的答复表示歉意,但请告诉我是否需要更多详细信息来进一步澄清我的问题。 非常感谢。

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

    >   双频谱[512];

    这会自行消耗8*512=4KB 的堆栈。  你提供了这么多吗? 浮点仅为2KB。

    作为一项快速实验,将此变量移到函数之外(因此它是全局变量),查看程序是否链接。

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

    我发送此回复后,就意识到并将变量移到函数之外-代码现在正在运行-我只需在整个函数运行后进行验证,然后更新问题并解决。 谢谢布鲁斯! 还感谢 Keith 的回应和建议!

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

    我听说 CCS 足够智能,可以使用 malloc()来定义大型定义,因此它们不会在堆栈上。

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

    吉,我希望不是。 我尝试不让 malloc 靠近我的代码。

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

    我知道,我也不知道,但无论如何,你不会试图在堆栈上分配这么多的数据。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="301692" url="~/support/microsofts/MSP-low-Power-microsoft-group/MSP4E/f/MSP-low-Power-microcontroller-forum/1067376/msp430fr5994-使用双分配声明引线到故障调试/3949553#3949553" i 的智能堆栈定义,他们没有听说过足够大的 malloc。]

    我不知道 TI MSP430编译器使用什么自动方法来决定定义是否由 malloc 而不是栈分配。

    使用 TI MSP430 v21.6.0编译器,以下命令可在 堆栈上分配质谱[]:

    int main(void)
    {
    	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
    	
        double spectrum[512];
    
        spectrum[0] = 1.2345;
    
    	return (int) spectrum[0];
    }
    

    如果将频谱定义为变量长度数组(VLA),则编译器调用 __VLA alloc()为堆上的数组分配空间(并调用__VLA dealloc 以在超出范围时释放变量):

    int main(void)
    {
    	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
    
    	int spectrum_size = 512;
        double spectrum[spectrum_size];
    
        spectrum[0] = 1.2345;
    
    	return (int) spectrum[0];
    }
    

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

    感谢切斯特的澄清。 我想我终于对 CCS 如何以及在何处存储价值观有了一定的了解。  

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

    啊,是的,我对一场 VLA 讨论的记忆很模糊。