因为我知道这个bug是什么!如何知道嵌入式编译时静态分配何时失败?
我在" 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 );
}
}
答案 0 :(得分:1)
链接器分配静态存储,在您的情况下为57个字节(数据加bss段)。因此,只要您的静态存储变量太大,就应该看到来自链接器的错误消息。
变量temp[1000]
是一个自动变量,它在运行时分配在堆栈上。未通过链接器静态分配的RAM用于堆栈。这个错误是一个简单的例子,你分配的单个变量大于设备的整个RAM,但通常这种错误实际上很难检测到。一种解决方案是在运行时检查可用的堆栈空间。作为一个简单的规则:不要在堆栈上分配大量的东西。只有在调用该函数时才会看到它失败。
temp[1000]
用于程序的整个运行时,因此只需将其移动到静态存储中就不会丢失任何内容。在它前面放置一个“静态”,你(希望)会看到来自链接器的错误消息。