更新 - 改写问题:
因为我知道错误是什么!如何知道嵌入式编译时静态分配何时失败?
年长者:
我在下面的“C”中有这个简单易懂的代码,它在带有 2K SRAM 的 Atmega328P-AU 中运行。我使用行为良好的 UART 库(我在调试期间使用了很多)在我的 PC 终端中获取调试字符串。
这段代码中有一个错误:它卡住了。我得到的只是这个输出...
Hello World - Loading
我应该为每个循环得到一个'+'。
你能解释一下为什么是卡住的吗?为什么编译器没有通知我静态分配比 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 );
}
}
最佳答案
链接器分配静态存储,在您的情况下为 57 个字节(数据加上 bss 段)。因此,只要您的静态存储变量太大,您就会看到链接器的错误消息。
temp[1000]
变量是一个自动变量,它在运行时分配在堆栈上。链接器未静态分配的 RAM 用于堆栈。这个错误很简单,你分配的是一个比设备整个 RAM 都大的变量,但通常这种错误真的很难检测到。一种解决方案是在运行时检查可用堆栈空间。作为一个简单的规则:不要在堆栈上分配大的东西。您只会在调用该函数时看到它失败。
temp[1000]
用于程序的整个运行时,因此您只需将它移入静态存储就不会丢失任何东西。在它前面放一个“static”,您将(希望)看到来自链接器的错误消息。
关于c - AVR/GNU C 编译器和静态内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32693013/