【发布时间】:2015-09-21 10:32:09
【问题描述】:
更新 - 改写问题:
因为我知道错误是什么!如何知道嵌入式编译时静态分配何时失败?
老年人:
我在下面的“C”中有这个简单易懂的代码,在带有 2K SRAM 的 Atmega328P-AU 中运行。我使用性能良好的 UART 库(我在调试过程中使用了很多)在我的 PC 终端中获取调试字符串。
此代码中有一个错误:它冻结了。我得到的只是这个输出......
Hello World - 加载中
我应该为每个循环获得一个 '+'。
你能解释一下为什么会冻结以及为什么编译器没有通知我静态分配的内存比 uC 所能获得的多。
代码中包含您可能需要的所有信息。
/**************************************************************************************************
Info
**************************************************************************************************/
/*
Device: Atmega328P-AU - No arduino
IDE: Atmel Studio 6.2
Compiler: AVR/GNU C Compiler : 4.8.1
F_CPU: 8000000 Hz defined in makefile
Fuses:
Extended: 0x07
High: 0xD9
Low: 0xE2
Lockbit: 0xFF
When compiled it show in build output these:
text data bss dec hex filename
1088 0 57 1145 479 Bug Catcher.elf
Done executing task "RunCompilerTask".
Task "RunOutputFileVerifyTask"
Program Memory Usage : 1088 bytes 3,3 % Full
Data Memory Usage : 57 bytes 2,8 % Full
Done executing task "RunOutputFileVerifyTask".
Done building target "CoreBuild" in project "Bug Catcher.cproj".
Target "PostBuildEvent" skipped, due to false condition; ('$(PostBuildEvent)' != '') was evaluated as ('' != '').
Target "Build" in file "C:\Program Files\Atmel\Atmel Studio 6.2\Vs\Avr.common.targets" from project "C:\Users\Tedi\Desktop\Bug Catcher\Bug Catcher\Bug Catcher.cproj" (entry point):
Done building target "Build" in project "Bug Catcher.cproj".
Done building project "Bug Catcher.cproj".
Build succeeded.
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
*/
/**************************************************************************************************
Definitions
**************************************************************************************************/
#define BIG_NUMBER 1000
// Atmega328P - Pin 12
#define SOFT_UART_RX_DDR DDRB
#define SOFT_UART_RX_DDR_bit DDB0
#define SOFT_UART_RX_PORT PORTB
#define SOFT_UART_RX_PORT_bit PORTB0
#define SOFT_UART_RX_PIN PINB
#define SOFT_UART_RX_PIN_bit PINB0
// Atmega328P Pin 13
#define SOFT_UART_TX_DDR DDRB
#define SOFT_UART_TX_DDR_bit DDB1
#define SOFT_UART_TX_PORT PORTB
#define SOFT_UART_TX_PORT_bit PORTB1
#define SOFT_UART_TX_PIN PINB
#define SOFT_UART_TX_PIN_bit PINB1
/**************************************************************************************************
Includes
**************************************************************************************************/
#include "softuart.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
/**************************************************************************************************
Main function
**************************************************************************************************/
int main()
{
/**********************************************************************************************
Setup
**********************************************************************************************/
softuart_init( &SOFT_UART_TX_DDR, SOFT_UART_TX_DDR_bit,
&SOFT_UART_TX_PORT, SOFT_UART_TX_PORT_bit,
&SOFT_UART_RX_DDR, SOFT_UART_RX_DDR_bit,
&SOFT_UART_RX_PIN, SOFT_UART_RX_PIN_bit );
sei();
softuart_puts_P( "\r\n\r\nHello World - Loading\r\n\r\n" ); // Can use custom UART function.
_delay_ms( 200 );
/**********************************************************************************************
Forever loop
**********************************************************************************************/
while(1)
{
char temp[BIG_NUMBER];
memset( temp, '\0', sizeof( temp ) );
{
char temp[BIG_NUMBER];
memset( temp, '\0', sizeof( temp ) );
{
char temp[BIG_NUMBER];
memset( temp, '\0', sizeof( temp ) );
}
}
softuart_puts_P("+"); // BUG!!!!! It never reaches here.
_delay_ms( 500 );
}
}
【问题讨论】:
-
由于编译器不知道你的目标有多少内存,它应该如何警告?它是执行重定位和绑定的链接器,因此您必须检查链接器命令文件。你可能已经指定了错误的目标,文件可能是错误的,等等。无论如何,“我的代码被冻结”不是特定的错误语句。请启动调试器以获得更准确的原因。
-
我使用 USBasp 编程器和 FTDI 芯片作为从 uC 获取字符串的一种方式。我没有调试器 :( 使用 IDE 模拟器,当我尝试调试时,它会在 trird memset 函数中冻结。
-
“我没有调试器”和“当我尝试调试它时冻结”不要放在一起。有可用于 AVR 的调试器,只需搜索即可。但是,在模拟器中,您应该能够检查状态 - 这正是您使用它的原因!
-
我是自学编程的,有很多对其他人来说显而易见的想法,我很幸运能够理解。让我们从头开始。短语“冻结”是指模拟器一直在第三个 memset 函数中,并且永远不会进入下一个命令。你说的状态是什么意思?检查什么?
-
@Olaf 很可能他希望它在 编译时 失败,如果您提供合适的链接器文件,这可能是可能的。 (至少你可以为全局内存做到这一点)