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.
我有一个代码,用于计算神经网络的一些数学系数。 在调试过程中,我有一个需要为“双”数据类型的变量。 当我在特定位置的代码中使用它时,代码在调试过程中会崩溃。 我使用 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 靠近我的代码。
我知道,我也不知道,但无论如何,你不会试图在堆栈上分配这么多的数据。
我不知道 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 讨论的记忆很模糊。